OSDN Git Service

Setting a wallpaper must be synchronous
authorChristopher Tate <ctate@google.com>
Tue, 29 Aug 2017 23:50:13 +0000 (16:50 -0700)
committerChristopher Tate <ctate@google.com>
Tue, 29 Aug 2017 23:50:13 +0000 (16:50 -0700)
Observable state needs to be fully established by the time the
caller is allowed to proceed, otherwise they might read stale
information.  In particular, we hadn't yet committed changes to
the backing store by the time observers were released, so they
could then read a stale generation number as the "current" state.

With this fix, the flaky CTS test is now reliably passing.

Test: cts-tradefed run cts-dev -m CtsAppTestCases -t android.app.cts.WallpaperManagerTest\#setBitmapTest
Bug: 65016846
Change-Id: I93fc690caedfbcd455a91625a3c67fff9168483b

services/core/java/com/android/server/wallpaper/WallpaperManagerService.java

index f6f5341..b963561 100644 (file)
@@ -280,14 +280,6 @@ public class WallpaperManagerService extends IWallpaperManager.Stub {
                                 Slog.v(TAG, "Crop done; invoking completion callback");
                             }
                             wallpaper.imageWallpaperPending = false;
-                            if (wallpaper.setComplete != null) {
-                                try {
-                                    wallpaper.setComplete.onWallpaperChanged();
-                                } catch (RemoteException e) {
-                                    // if this fails we don't really care; the setting app may just
-                                    // have crashed and that sort of thing is a fact of life.
-                                }
-                            }
                             if (sysWallpaperChanged) {
                                 // If this was the system wallpaper, rebind...
                                 bindWallpaperComponentLocked(mImageWallpaper, true,
@@ -311,6 +303,16 @@ public class WallpaperManagerService extends IWallpaperManager.Stub {
                             }
 
                             saveSettingsLocked(wallpaper.userId);
+
+                            // Publish completion *after* we've persisted the changes
+                            if (wallpaper.setComplete != null) {
+                                try {
+                                    wallpaper.setComplete.onWallpaperChanged();
+                                } catch (RemoteException e) {
+                                    // if this fails we don't really care; the setting app may just
+                                    // have crashed and that sort of thing is a fact of life.
+                                }
+                            }
                         }
                     }
                 }