OSDN Git Service

Fixes usage of WallpaperManager to make it optional.
authorFelipe Leme <felipeal@google.com>
Mon, 5 Aug 2019 23:00:12 +0000 (16:00 -0700)
committerFelipe Leme <felipeal@google.com>
Tue, 19 Nov 2019 01:24:52 +0000 (01:24 +0000)
As the main javadoc states:
"An app can check whether wallpapers are supported for the current user,
by calling {@link #isWallpaperSupported()}, and whether setting of
wallpapers is allowed, by calling {@link #isSetWallpaperAllowed()}."

Test: manual verification on automotive
Test: atest CtsAppTestCases:android.app.cts.WallpaperManagerTest # on automotive

Bug: 138939803
Bug: 132111956

Change-Id: I88946f92ff54e556d289c41c28e22da3a4b8c8b8
Merged-In: I88946f92ff54e556d289c41c28e22da3a4b8c8b8
(cherry picked from commit 34a861add16eed6ef2f487b3d40017d5ad70c2a6)

core/java/android/app/DisabledWallpaperManager.java [new file with mode: 0644]
core/java/android/app/SystemServiceRegistry.java
core/java/android/app/WallpaperManager.java
core/java/android/app/backup/WallpaperBackupHelper.java
core/java/com/android/internal/colorextraction/ColorExtractor.java
packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java
packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java
packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
services/core/java/com/android/server/wm/DisplayPolicy.java
services/java/com/android/server/SystemServer.java

diff --git a/core/java/android/app/DisabledWallpaperManager.java b/core/java/android/app/DisabledWallpaperManager.java
new file mode 100644 (file)
index 0000000..5185941
--- /dev/null
@@ -0,0 +1,346 @@
+/*
+ * 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 android.app;
+
+import android.annotation.NonNull;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
+import android.util.Log;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * A no-op implementation of {@link WallpaperManager}.
+ */
+final class DisabledWallpaperManager extends WallpaperManager {
+
+    private static final String TAG = DisabledWallpaperManager.class.getSimpleName();
+
+    // Don't need to worry about synchronization
+    private static DisabledWallpaperManager sInstance;
+
+    // TODO(b/138939803): STOPSHIP changed to false and/or remove it
+    private static final boolean DEBUG = true;
+
+    @NonNull
+    static DisabledWallpaperManager getInstance() {
+        if (sInstance == null) {
+            sInstance = new DisabledWallpaperManager();
+        }
+        return sInstance;
+    }
+
+    private DisabledWallpaperManager() {
+        super(null, null, null);
+    }
+
+    @Override
+    public boolean isWallpaperSupported() {
+        return false;
+    }
+
+    @Override
+    public boolean isSetWallpaperAllowed() {
+        return false;
+    }
+
+    // TODO(b/138939803): STOPSHIP methods below should not be necessary,
+    // callers should check if isWallpaperSupported(), consider removing them to keep this class
+    // simpler
+
+    private static <T> T unsupported() {
+        if (DEBUG) Log.w(TAG, "unsupported method called; returning null", new Exception());
+        return null;
+    }
+
+    private static boolean unsupportedBoolean() {
+        if (DEBUG) Log.w(TAG, "unsupported method called; returning false", new Exception());
+        return false;
+    }
+
+    @Override
+    public Drawable getDrawable() {
+        return unsupported();
+    }
+
+    @Override
+    public Drawable getBuiltInDrawable() {
+        return unsupported();
+    }
+
+    @Override
+    public Drawable getBuiltInDrawable(int which) {
+        return unsupported();
+    }
+
+    @Override
+    public Drawable getBuiltInDrawable(int outWidth, int outHeight, boolean scaleToFit,
+            float horizontalAlignment, float verticalAlignment) {
+        return unsupported();
+    }
+
+    @Override
+    public Drawable getBuiltInDrawable(int outWidth, int outHeight, boolean scaleToFit,
+            float horizontalAlignment, float verticalAlignment, int which) {
+        return unsupported();
+    }
+
+    @Override
+    public Drawable peekDrawable() {
+        return unsupported();
+    }
+
+    @Override
+    public Drawable getFastDrawable() {
+        return unsupported();
+    }
+
+    @Override
+    public Drawable peekFastDrawable() {
+        return unsupported();
+    }
+
+    @Override
+    public Bitmap getBitmap() {
+        return unsupported();
+    }
+
+    @Override
+    public Bitmap getBitmap(boolean hardware) {
+        return unsupported();
+    }
+
+    @Override
+    public Bitmap getBitmapAsUser(int userId, boolean hardware) {
+        return unsupported();
+    }
+
+    @Override
+    public ParcelFileDescriptor getWallpaperFile(int which) {
+        return unsupported();
+    }
+
+    @Override
+    public void addOnColorsChangedListener(OnColorsChangedListener listener, Handler handler) {
+        unsupported();
+    }
+
+    @Override
+    public void addOnColorsChangedListener(OnColorsChangedListener listener, Handler handler,
+            int userId) {
+        unsupported();
+    }
+
+    @Override
+    public void removeOnColorsChangedListener(OnColorsChangedListener callback) {
+        unsupported();
+    }
+
+    @Override
+    public void removeOnColorsChangedListener(OnColorsChangedListener callback, int userId) {
+        unsupported();
+    }
+
+    @Override
+    public WallpaperColors getWallpaperColors(int which) {
+        return unsupported();
+    }
+
+    @Override
+    public WallpaperColors getWallpaperColors(int which, int userId) {
+        return unsupported();
+    }
+
+    @Override
+    public ParcelFileDescriptor getWallpaperFile(int which, int userId) {
+        return unsupported();
+    }
+
+    @Override
+    public void forgetLoadedWallpaper() {
+        unsupported();
+    }
+
+    @Override
+    public WallpaperInfo getWallpaperInfo() {
+        return unsupported();
+    }
+
+    @Override
+    public WallpaperInfo getWallpaperInfo(int userId) {
+        return unsupported();
+    }
+
+    @Override
+    public int getWallpaperId(int which) {
+        return unsupported();
+    }
+
+    @Override
+    public int getWallpaperIdForUser(int which, int userId) {
+        return unsupported();
+    }
+
+    @Override
+    public Intent getCropAndSetWallpaperIntent(Uri imageUri) {
+        return unsupported();
+    }
+
+    @Override
+    public void setResource(int resid) throws IOException {
+        unsupported();
+    }
+
+    @Override
+    public int setResource(int resid, int which) throws IOException {
+        return unsupported();
+    }
+
+    @Override
+    public void setBitmap(Bitmap bitmap) throws IOException {
+        unsupported();
+    }
+
+    @Override
+    public int setBitmap(Bitmap fullImage, Rect visibleCropHint, boolean allowBackup)
+            throws IOException {
+        return unsupported();
+    }
+
+    @Override
+    public int setBitmap(Bitmap fullImage, Rect visibleCropHint, boolean allowBackup, int which)
+            throws IOException {
+        return unsupported();
+    }
+
+    @Override
+    public int setBitmap(Bitmap fullImage, Rect visibleCropHint, boolean allowBackup, int which,
+            int userId) throws IOException {
+        return unsupported();
+    }
+
+    @Override
+    public void setStream(InputStream bitmapData) throws IOException {
+        unsupported();
+    }
+
+    @Override
+    public int setStream(InputStream bitmapData, Rect visibleCropHint, boolean allowBackup)
+            throws IOException {
+        return unsupported();
+    }
+
+    @Override
+    public int setStream(InputStream bitmapData, Rect visibleCropHint, boolean allowBackup,
+            int which) throws IOException {
+        return unsupported();
+    }
+
+    @Override
+    public boolean hasResourceWallpaper(int resid) {
+        return unsupportedBoolean();
+    }
+
+    @Override
+    public int getDesiredMinimumWidth() {
+        return unsupported();
+    }
+
+    @Override
+    public int getDesiredMinimumHeight() {
+        return unsupported();
+    }
+
+    @Override
+    public void suggestDesiredDimensions(int minimumWidth, int minimumHeight) {
+        unsupported();
+    }
+
+    @Override
+    public void setDisplayPadding(Rect padding) {
+        unsupported();
+    }
+
+    @Override
+    public void setDisplayOffset(IBinder windowToken, int x, int y) {
+        unsupported();
+    }
+
+    @Override
+    public void clearWallpaper() {
+        unsupported();
+    }
+
+    @Override
+    public void clearWallpaper(int which, int userId) {
+        unsupported();
+    }
+
+    @Override
+    public boolean setWallpaperComponent(ComponentName name) {
+        return unsupportedBoolean();
+    }
+
+    @Override
+    public boolean setWallpaperComponent(ComponentName name, int userId) {
+        return unsupportedBoolean();
+    }
+
+    @Override
+    public void setWallpaperOffsets(IBinder windowToken, float xOffset, float yOffset) {
+        unsupported();
+    }
+
+    @Override
+    public void setWallpaperOffsetSteps(float xStep, float yStep) {
+        unsupported();
+    }
+
+    @Override
+    public void sendWallpaperCommand(IBinder windowToken, String action, int x, int y, int z,
+            Bundle extras) {
+        unsupported();
+    }
+
+    @Override
+    public void clearWallpaperOffsets(IBinder windowToken) {
+        unsupported();
+    }
+
+    @Override
+    public void clear() throws IOException {
+        unsupported();
+    }
+
+    @Override
+    public void clear(int which) throws IOException {
+        unsupported();
+    }
+
+    @Override
+    public boolean isWallpaperBackupEligible(int which) {
+        return unsupportedBoolean();
+    }
+}
index fe4b0d5..136e932 100644 (file)
@@ -694,11 +694,22 @@ final class SystemServiceRegistry {
             @Override
             public WallpaperManager createService(ContextImpl ctx)
                     throws ServiceNotFoundException {
-                final IBinder b;
-                if (ctx.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.P) {
-                    b = ServiceManager.getServiceOrThrow(Context.WALLPAPER_SERVICE);
-                } else {
-                    b = ServiceManager.getService(Context.WALLPAPER_SERVICE);
+                final IBinder b = ServiceManager.getService(Context.WALLPAPER_SERVICE);
+                if (b == null) {
+                    // There are 2 reason service can be null:
+                    // 1.Device doesn't support it - that's fine
+                    // 2.App is running on instant mode - should fail
+                    final boolean enabled = Resources.getSystem()
+                            .getBoolean(com.android.internal.R.bool.config_enableWallpaperService);
+                    if (!enabled) {
+                        // Life moves on...
+                        return DisabledWallpaperManager.getInstance();
+                    }
+                    if (ctx.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.P) {
+                        // Instant app
+                        throw new ServiceNotFoundException(Context.WALLPAPER_SERVICE);
+                    }
+                    // Bad state - WallpaperManager methods will throw exception
                 }
                 IWallpaperManager service = IWallpaperManager.Stub.asInterface(b);
                 return new WallpaperManager(service, ctx.getOuterContext(),
index 325a54b..d607ed6 100644 (file)
@@ -510,7 +510,9 @@ public class WallpaperManager {
 
     /*package*/ WallpaperManager(IWallpaperManager service, Context context, Handler handler) {
         mContext = context;
-        initGlobals(service, context.getMainLooper());
+        if (service != null) {
+            initGlobals(service, context.getMainLooper());
+        }
     }
 
     /**
index 36f5f96..5c0ddc1 100644 (file)
@@ -85,6 +85,10 @@ public class WallpaperBackupHelper extends FileBackupHelperBase implements Backu
      */
     @Override
     public void restoreEntity(BackupDataInputStream data) {
+        if (mWpm == null) {
+            Slog.w(TAG, "restoreEntity(): no wallpaper service");
+            return;
+        }
         final String key = data.getKey();
         if (isKeyInList(key, mKeys)) {
             if (key.equals(WALLPAPER_IMAGE_KEY)) {
index 3003ce8..f0da0d5 100644 (file)
@@ -73,8 +73,10 @@ public class ColorExtractor implements WallpaperManager.OnColorsChangedListener
         }
 
         mOnColorsChangedListeners = new ArrayList<>();
-        wallpaperManager.addOnColorsChangedListener(this, null /* handler */);
-        initExtractColors(wallpaperManager, immediately);
+        if (wallpaperManager.isWallpaperSupported()) {
+            wallpaperManager.addOnColorsChangedListener(this, null /* handler */);
+            initExtractColors(wallpaperManager, immediately);
+        }
     }
 
     private void initExtractColors(WallpaperManager wallpaperManager, boolean immediately) {
index d3e8b3d..3ca1f59 100644 (file)
@@ -68,9 +68,11 @@ public class SysuiColorExtractor extends ColorExtractor implements Dumpable,
         mBackdropColors.setMainColor(Color.BLACK);
 
         // Listen to all users instead of only the current one.
-        wallpaperManager.removeOnColorsChangedListener(this);
-        wallpaperManager.addOnColorsChangedListener(this, null /* handler */,
-                UserHandle.USER_ALL);
+        if (wallpaperManager.isWallpaperSupported()) {
+            wallpaperManager.removeOnColorsChangedListener(this);
+            wallpaperManager.addOnColorsChangedListener(this, null /* handler */,
+                    UserHandle.USER_ALL);
+        }
     }
 
     @Override
index d2023ec..dcb349b 100644 (file)
@@ -79,10 +79,13 @@ public class LockscreenWallpaper extends IWallpaperManagerCallback.Stub implemen
 
         IWallpaperManager service = IWallpaperManager.Stub.asInterface(
                 ServiceManager.getService(Context.WALLPAPER_SERVICE));
-        try {
-            service.setLockWallpaperCallback(this);
-        } catch (RemoteException e) {
-            Log.e(TAG, "System dead?" + e);
+        if (service != null) {
+            // Service is disabled on some devices like Automotive
+            try {
+                service.setLockWallpaperCallback(this);
+            } catch (RemoteException e) {
+                Log.e(TAG, "System dead?" + e);
+            }
         }
     }
 
@@ -108,6 +111,11 @@ public class LockscreenWallpaper extends IWallpaperManagerCallback.Stub implemen
     public LoaderResult loadBitmap(int currentUserId, UserHandle selectedUser) {
         // May be called on any thread - only use thread safe operations.
 
+        if (!mWallpaperManager.isWallpaperSupported()) {
+            // When wallpaper is not supported, show the system wallpaper
+            return LoaderResult.success(null);
+        }
+
         // Prefer the selected user (when specified) over the current user for the FLAG_SET_LOCK
         // wallpaper.
         final int lockWallpaperUserId =
index a87b416..aa7fce7 100644 (file)
@@ -485,15 +485,17 @@ public class StatusBar extends SystemUI implements DemoMode,
     protected NotificationMediaManager mMediaManager;
     protected NotificationLockscreenUserManager mLockscreenUserManager;
     protected NotificationRemoteInputManager mRemoteInputManager;
+    private boolean mWallpaperSupported;
 
     private final BroadcastReceiver mWallpaperChangedReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
-            WallpaperManager wallpaperManager = context.getSystemService(WallpaperManager.class);
-            if (wallpaperManager == null) {
-                Log.w(TAG, "WallpaperManager not available");
+            if (!mWallpaperSupported) {
+                // Receiver should not have been registered at all...
+                Log.wtf(TAG, "WallpaperManager not supported");
                 return;
             }
+            WallpaperManager wallpaperManager = context.getSystemService(WallpaperManager.class);
             WallpaperInfo info = wallpaperManager.getWallpaperInfo(UserHandle.USER_CURRENT);
             final boolean deviceSupportsAodWallpaper = mContext.getResources().getBoolean(
                     com.android.internal.R.bool.config_dozeSupportsAodWallpaper);
@@ -705,11 +707,18 @@ public class StatusBar extends SystemUI implements DemoMode,
 
         createAndAddWindows(result);
 
-        // Make sure we always have the most current wallpaper info.
-        IntentFilter wallpaperChangedFilter = new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED);
-        mContext.registerReceiverAsUser(mWallpaperChangedReceiver, UserHandle.ALL,
-                wallpaperChangedFilter, null /* broadcastPermission */, null /* scheduler */);
-        mWallpaperChangedReceiver.onReceive(mContext, null);
+        mWallpaperSupported =
+                mContext.getSystemService(WallpaperManager.class).isWallpaperSupported();
+
+        if (mWallpaperSupported) {
+            // Make sure we always have the most current wallpaper info.
+            IntentFilter wallpaperChangedFilter = new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED);
+            mContext.registerReceiverAsUser(mWallpaperChangedReceiver, UserHandle.ALL,
+                    wallpaperChangedFilter, null /* broadcastPermission */, null /* scheduler */);
+            mWallpaperChangedReceiver.onReceive(mContext, null);
+        } else if (DEBUG) {
+            Log.v(TAG, "start(): no wallpaper service ");
+        }
 
         // Set up the initial notification state. This needs to happen before CommandQueue.disable()
         setUpPresenter();
@@ -744,12 +753,14 @@ public class StatusBar extends SystemUI implements DemoMode,
         mContext.registerReceiver(mBannerActionBroadcastReceiver, internalFilter, PERMISSION_SELF,
                 null);
 
-        IWallpaperManager wallpaperManager = IWallpaperManager.Stub.asInterface(
-                ServiceManager.getService(Context.WALLPAPER_SERVICE));
-        try {
-            wallpaperManager.setInAmbientMode(false /* ambientMode */, 0L /* duration */);
-        } catch (RemoteException e) {
-            // Just pass, nothing critical.
+        if (mWallpaperSupported) {
+            IWallpaperManager wallpaperManager = IWallpaperManager.Stub.asInterface(
+                    ServiceManager.getService(Context.WALLPAPER_SERVICE));
+            try {
+                wallpaperManager.setInAmbientMode(false /* ambientMode */, 0L /* duration */);
+            } catch (RemoteException e) {
+                // Just pass, nothing critical.
+            }
         }
 
         // end old BaseStatusBar.start().
@@ -2354,6 +2365,7 @@ public class StatusBar extends SystemUI implements DemoMode,
         pw.println(Settings.Global.zenModeToString(Settings.Global.getInt(
                 mContext.getContentResolver(), Settings.Global.ZEN_MODE,
                 Settings.Global.ZEN_MODE_OFF)));
+        pw.print("  mWallpaperSupported= "); pw.println(mWallpaperSupported);
 
         if (mStatusBarView != null) {
             dumpBarTransitions(pw, "mStatusBarView", mStatusBarView.getBarTransitions());
@@ -2738,7 +2750,9 @@ public class StatusBar extends SystemUI implements DemoMode,
     public void setLockscreenUser(int newUserId) {
         mLockscreenWallpaper.setCurrentUser(newUserId);
         mScrimController.setCurrentUser(newUserId);
-        mWallpaperChangedReceiver.onReceive(mContext, null);
+        if (mWallpaperSupported) {
+            mWallpaperChangedReceiver.onReceive(mContext, null);
+        }
     }
 
     /**
index 99a9db3..b37c779 100644 (file)
@@ -2812,7 +2812,11 @@ public class DisplayPolicy {
         mHandler.post(() -> {
             final int displayId = getDisplayId();
             getStatusBarManagerInternal().onDisplayReady(displayId);
-            LocalServices.getService(WallpaperManagerInternal.class).onDisplayReady(displayId);
+            final WallpaperManagerInternal wpMgr = LocalServices
+                    .getService(WallpaperManagerInternal.class);
+            if (wpMgr != null) {
+                wpMgr.onDisplayReady(displayId);
+            }
         });
     }
 
index 97e003c..ae86b60 100644 (file)
@@ -1474,6 +1474,8 @@ public final class SystemServer {
                 traceBeginAndSlog("StartWallpaperManagerService");
                 mSystemServiceManager.startService(WALLPAPER_SERVICE_CLASS);
                 traceEnd();
+            } else {
+                Slog.i(TAG, "Wallpaper service disabled by config");
             }
 
             traceBeginAndSlog("StartAudioService");