Make wallpapers direct-boot aware.
If the user's wallpaper isn't direct-boot aware, wait around for
the user to be unlocked, instead of clearing the wallpaper.
Also switch a few classes to using SystemService lifecycle, since
events are dispatched faster than through broadcasts. Fix bug where
ContentService.systemReady() was never called, and make sure
EntropyMixer doesn't risk being GC'ed.
Bug: 26280055
Change-Id: I9fff468a439b868baa68cf11bb6ee9f7d52b7b5a
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 05e4245..4791818 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -91,6 +91,8 @@
import com.android.internal.util.Preconditions;
import com.android.server.FgThread;
import com.android.server.LocalServices;
+import com.android.server.SystemService;
+
import com.google.android.collect.Lists;
import com.google.android.collect.Sets;
@@ -127,9 +129,34 @@
public class AccountManagerService
extends IAccountManager.Stub
implements RegisteredServicesCacheListener<AuthenticatorDescription> {
-
private static final String TAG = "AccountManagerService";
+ public static class Lifecycle extends SystemService {
+ private AccountManagerService mService;
+
+ public Lifecycle(Context context) {
+ super(context);
+ }
+
+ @Override
+ public void onStart() {
+ mService = new AccountManagerService(getContext());
+ publishBinderService(Context.ACCOUNT_SERVICE, mService);
+ }
+
+ @Override
+ public void onBootPhase(int phase) {
+ if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
+ mService.systemReady();
+ }
+ }
+
+ @Override
+ public void onUnlockUser(int userHandle) {
+ mService.onUnlockUser(userHandle);
+ }
+ }
+
private static final String DATABASE_NAME = "accounts.db";
private static final int PRE_N_DATABASE_VERSION = 9;
private static final int CE_DATABASE_VERSION = 10;
@@ -340,15 +367,12 @@
IntentFilter userFilter = new IntentFilter();
userFilter.addAction(Intent.ACTION_USER_REMOVED);
- userFilter.addAction(Intent.ACTION_USER_UNLOCKED);
mContext.registerReceiverAsUser(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (Intent.ACTION_USER_REMOVED.equals(action)) {
onUserRemoved(intent);
- } else if (Intent.ACTION_USER_UNLOCKED.equals(action)) {
- onUserUnlocked(intent);
}
}
}, UserHandle.ALL, userFilter, null, null);
@@ -654,7 +678,10 @@
@VisibleForTesting
void onUserUnlocked(Intent intent) {
- int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
+ onUnlockUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1));
+ }
+
+ void onUnlockUser(int userId) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "onUserUnlocked " + userId);
}
diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index 6e7ea99..03eb019 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -77,7 +77,7 @@
static final boolean DEBUG = false;
public static class Lifecycle extends SystemService {
- private ContentService mContentService;
+ private ContentService mService;
public Lifecycle(Context context) {
super(context);
@@ -87,14 +87,21 @@
public void onStart() {
final boolean factoryTest = (FactoryTest
.getMode() == FactoryTest.FACTORY_TEST_LOW_LEVEL);
- mContentService = new ContentService(getContext(), factoryTest);
- publishBinderService(ContentResolver.CONTENT_SERVICE_NAME, mContentService);
+ mService = new ContentService(getContext(), factoryTest);
+ publishBinderService(ContentResolver.CONTENT_SERVICE_NAME, mService);
+ }
+
+ @Override
+ public void onBootPhase(int phase) {
+ if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
+ mService.systemReady();
+ }
}
@Override
public void onCleanupUser(int userHandle) {
- synchronized (mContentService.mCache) {
- mContentService.mCache.remove(userHandle);
+ synchronized (mService.mCache) {
+ mService.mCache.remove(userHandle);
}
}
}
@@ -265,7 +272,7 @@
localeFilter, null, null);
}
- public void systemReady() {
+ void systemReady() {
getSyncManager();
}
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index fe32104..ca1a7ac 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -16,9 +16,12 @@
package com.android.server.wallpaper;
-import static android.app.WallpaperManager.FLAG_SYSTEM;
import static android.app.WallpaperManager.FLAG_LOCK;
-import static android.os.ParcelFileDescriptor.*;
+import static android.app.WallpaperManager.FLAG_SYSTEM;
+import static android.os.ParcelFileDescriptor.MODE_CREATE;
+import static android.os.ParcelFileDescriptor.MODE_READ_ONLY;
+import static android.os.ParcelFileDescriptor.MODE_READ_WRITE;
+import static android.os.ParcelFileDescriptor.MODE_TRUNCATE;
import android.app.ActivityManager;
import android.app.ActivityManagerNative;
@@ -41,27 +44,26 @@
import android.content.ServiceConnection;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
-import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.UserInfo;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapRegionDecoder;
-import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Binder;
import android.os.Bundle;
import android.os.Environment;
+import android.os.FileObserver;
import android.os.FileUtils;
import android.os.IBinder;
import android.os.IRemoteCallback;
-import android.os.RemoteException;
-import android.os.FileObserver;
import android.os.ParcelFileDescriptor;
import android.os.RemoteCallbackList;
+import android.os.RemoteException;
import android.os.SELinux;
import android.os.ServiceManager;
import android.os.SystemClock;
@@ -79,35 +81,62 @@
import android.view.IWindowManager;
import android.view.WindowManager;
-import java.io.BufferedOutputStream;
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.PrintWriter;
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.List;
+import com.android.internal.R;
+import com.android.internal.content.PackageMonitor;
+import com.android.internal.util.FastXmlSerializer;
+import com.android.internal.util.JournaledFile;
+import com.android.server.EventLogTags;
+import com.android.server.SystemService;
+
+import libcore.io.IoUtils;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
-import com.android.internal.content.PackageMonitor;
-import com.android.internal.util.FastXmlSerializer;
-import com.android.internal.util.JournaledFile;
-import com.android.internal.R;
-import com.android.server.EventLogTags;
-
-import libcore.io.IoUtils;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.List;
public class WallpaperManagerService extends IWallpaperManager.Stub {
static final String TAG = "WallpaperManagerService";
static final boolean DEBUG = false;
+ public static class Lifecycle extends SystemService {
+ private WallpaperManagerService mService;
+
+ public Lifecycle(Context context) {
+ super(context);
+ }
+
+ @Override
+ public void onStart() {
+ mService = new WallpaperManagerService(getContext());
+ publishBinderService(Context.WALLPAPER_SERVICE, mService);
+ }
+
+ @Override
+ public void onBootPhase(int phase) {
+ if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
+ mService.systemReady();
+ }
+ }
+
+ @Override
+ public void onUnlockUser(int userHandle) {
+ mService.onUnlockUser(userHandle);
+ }
+ }
+
final Object mLock = new Object();
/**
@@ -417,6 +446,7 @@
final AppOpsManager mAppOpsManager;
WallpaperData mLastWallpaper;
IWallpaperManagerCallback mKeyguardListener;
+ boolean mWaitingForUnlock;
/**
* ID of the current wallpaper, changed every time anything sets a wallpaper.
@@ -744,8 +774,9 @@
if (wallpaper.wallpaperComponent != null
&& isPackageModified(wallpaper.wallpaperComponent.getPackageName())) {
try {
- mContext.getPackageManager().getServiceInfo(
- wallpaper.wallpaperComponent, 0);
+ mContext.getPackageManager().getServiceInfo(wallpaper.wallpaperComponent,
+ PackageManager.MATCH_DIRECT_BOOT_AWARE
+ | PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
} catch (NameNotFoundException e) {
Slog.w(TAG, "Wallpaper component gone, removing: "
+ wallpaper.wallpaperComponent);
@@ -755,8 +786,9 @@
if (wallpaper.nextWallpaperComponent != null
&& isPackageModified(wallpaper.nextWallpaperComponent.getPackageName())) {
try {
- mContext.getPackageManager().getServiceInfo(
- wallpaper.nextWallpaperComponent, 0);
+ mContext.getPackageManager().getServiceInfo(wallpaper.nextWallpaperComponent,
+ PackageManager.MATCH_DIRECT_BOOT_AWARE
+ | PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
} catch (NameNotFoundException e) {
wallpaper.nextWallpaperComponent = null;
}
@@ -793,7 +825,7 @@
}
}
- public void systemRunning() {
+ void systemReady() {
if (DEBUG) Slog.v(TAG, "systemReady");
WallpaperData wallpaper = mWallpaperMap.get(UserHandle.USER_SYSTEM);
// If we think we're going to be using the system image wallpaper imagery, make
@@ -828,7 +860,7 @@
mContext.registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
+ final String action = intent.getAction();
if (Intent.ACTION_USER_REMOVED.equals(action)) {
onRemoveUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
UserHandle.USER_NULL));
@@ -892,6 +924,14 @@
mLockWallpaperMap.remove(userId);
}
+ void onUnlockUser(int userId) {
+ synchronized (mLock) {
+ if (mCurrentUserId == userId && mWaitingForUnlock) {
+ switchUser(userId, null);
+ }
+ }
+ }
+
void onRemoveUser(int userId) {
if (userId < 1) return;
@@ -919,18 +959,34 @@
void switchWallpaper(WallpaperData wallpaper, IRemoteCallback reply) {
synchronized (mLock) {
- RuntimeException e = null;
- try {
- ComponentName cname = wallpaper.wallpaperComponent != null ?
- wallpaper.wallpaperComponent : wallpaper.nextWallpaperComponent;
- if (bindWallpaperComponentLocked(cname, true, false, wallpaper, reply)) {
- return;
+ mWaitingForUnlock = false;
+ final ComponentName cname = wallpaper.wallpaperComponent != null ?
+ wallpaper.wallpaperComponent : wallpaper.nextWallpaperComponent;
+ if (!bindWallpaperComponentLocked(cname, true, false, wallpaper, reply)) {
+ // We failed to bind the desired wallpaper, but that might
+ // happen if the wallpaper isn't direct-boot aware
+ ServiceInfo si = null;
+ try {
+ si = mIPackageManager.getServiceInfo(cname,
+ PackageManager.MATCH_DIRECT_BOOT_UNAWARE, wallpaper.userId);
+ } catch (RemoteException ignored) {
}
- } catch (RuntimeException e1) {
- e = e1;
+
+ if (si == null) {
+ Slog.w(TAG, "Failure starting previous wallpaper; clearing");
+ clearWallpaperLocked(false, FLAG_SYSTEM, wallpaper.userId, reply);
+ } else {
+ Slog.w(TAG, "Wallpaper isn't direct boot aware; using fallback until unlocked");
+ // We might end up persisting the current wallpaper data
+ // while locked, so pretend like the component was actually
+ // bound into place
+ wallpaper.wallpaperComponent = wallpaper.nextWallpaperComponent;
+ final WallpaperData fallback = new WallpaperData(wallpaper.userId,
+ WALLPAPER_LOCK_ORIG, WALLPAPER_LOCK_CROP);
+ bindWallpaperComponentLocked(mImageWallpaper, true, false, fallback, reply);
+ mWaitingForUnlock = true;
+ }
}
- Slog.w(TAG, "Failure starting previous wallpaper", e);
- clearWallpaperLocked(false, FLAG_SYSTEM, wallpaper.userId, reply);
}
}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index e7ae2b0..2f2ed1f 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -18,7 +18,6 @@
import android.app.ActivityManagerNative;
import android.app.ActivityThread;
-import android.app.IAlarmManager;
import android.app.INotificationManager;
import android.app.usage.UsageStatsManagerInternal;
import android.content.ComponentName;
@@ -55,13 +54,11 @@
import com.android.internal.os.ZygoteInit;
import com.android.internal.widget.ILockSettings;
import com.android.server.accessibility.AccessibilityManagerService;
-import com.android.server.accounts.AccountManagerService;
import com.android.server.am.ActivityManagerService;
import com.android.server.audio.AudioService;
import com.android.server.camera.CameraService;
import com.android.server.clipboard.ClipboardService;
import com.android.server.connectivity.MetricsLoggerService;
-import com.android.server.content.ContentService;
import com.android.server.devicepolicy.DevicePolicyManagerService;
import com.android.server.display.DisplayManagerService;
import com.android.server.dreams.DreamManagerService;
@@ -97,7 +94,6 @@
import com.android.server.twilight.TwilightService;
import com.android.server.usage.UsageStatsService;
import com.android.server.vr.VrManagerService;
-import com.android.server.wallpaper.WallpaperManagerService;
import com.android.server.webkit.WebViewUpdateService;
import com.android.server.wm.WindowManagerService;
@@ -157,8 +153,12 @@
"com.google.android.clockwork.ThermalObserver";
private static final String WEAR_BLUETOOTH_SERVICE_CLASS =
"com.google.android.clockwork.bluetooth.WearBluetoothService";
+ private static final String ACCOUNT_SERVICE_CLASS =
+ "com.android.server.accounts.AccountManagerService$Lifecycle";
private static final String CONTENT_SERVICE_CLASS =
"com.android.server.content.ContentService$Lifecycle";
+ private static final String WALLPAPER_SERVICE_CLASS =
+ "com.android.server.wallpaper.WallpaperManagerService$Lifecycle";
private static final String PERSISTENT_DATA_BLOCK_PROP = "ro.frp.pst";
@@ -187,6 +187,7 @@
private PackageManagerService mPackageManagerService;
private PackageManager mPackageManager;
private ContentResolver mContentResolver;
+ private EntropyMixer mEntropyMixer;
private boolean mOnlyCore;
private boolean mFirstBoot;
@@ -497,10 +498,7 @@
*/
private void startOtherServices() {
final Context context = mSystemContext;
- AccountManagerService accountManager = null;
- ContentService contentService = null;
VibratorService vibrator = null;
- IAlarmManager alarm = null;
IMountService mountService = null;
NetworkManagementService networkManagement = null;
NetworkStatsService networkStats = null;
@@ -516,8 +514,6 @@
TelephonyRegistry telephonyRegistry = null;
ConsumerIrService consumerIr = null;
MmsServiceBroker mmsService = null;
- EntropyMixer entropyMixer = null;
- VrManagerService vrManagerService = null;
HardwarePropertiesManagerService hardwarePropertiesService = null;
boolean disableStorage = SystemProperties.getBoolean("config.disable_storage", false);
@@ -556,7 +552,7 @@
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
traceBeginAndSlog("StartEntropyMixer");
- entropyMixer = new EntropyMixer(context);
+ mEntropyMixer = new EntropyMixer(context);
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
mContentResolver = context.getContentResolver();
@@ -566,13 +562,7 @@
// The AccountManager must come before the ContentService
traceBeginAndSlog("StartAccountManagerService");
- try {
- // TODO: seems like this should be disable-able, but req'd by ContentService
- accountManager = new AccountManagerService(context);
- ServiceManager.addService(Context.ACCOUNT_SERVICE, accountManager);
- } catch (Throwable e) {
- Slog.e(TAG, "Failure starting Account Manager", e);
- }
+ mSystemServiceManager.startService(ACCOUNT_SERVICE_CLASS);
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
traceBeginAndSlog("StartContentService");
@@ -593,9 +583,9 @@
ServiceManager.addService(Context.CONSUMER_IR_SERVICE, consumerIr);
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
+ traceBeginAndSlog("StartAlarmManagerService");
mSystemServiceManager.startService(AlarmManagerService.class);
- alarm = IAlarmManager.Stub.asInterface(
- ServiceManager.getService(Context.ALARM_SERVICE));
+ Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
traceBeginAndSlog("InitWatchdog");
final Watchdog watchdog = Watchdog.getInstance();
@@ -652,7 +642,6 @@
StatusBarManagerService statusBar = null;
INotificationManager notification = null;
- WallpaperManagerService wallpaper = null;
LocationManagerService location = null;
CountryDetectorService countryDetector = null;
ILockSettings lockSettings = null;
@@ -886,24 +875,6 @@
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
- Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "MakeAccountManagerServiceReady");
- try {
- if (accountManager != null)
- accountManager.systemReady();
- } catch (Throwable e) {
- reportWtf("making Account Manager Service ready", e);
- }
- Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
-
- Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "MakeContentServiceReady");
- try {
- if (contentService != null)
- contentService.systemReady();
- } catch (Throwable e) {
- reportWtf("making Content Service ready", e);
- }
- Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
-
mSystemServiceManager.startService(NotificationManagerService.class);
notification = INotificationManager.Stub.asInterface(
ServiceManager.getService(Context.NOTIFICATION_SERVICE));
@@ -946,12 +917,7 @@
if (!disableNonCoreServices && context.getResources().getBoolean(
R.bool.config_enableWallpaperService)) {
traceBeginAndSlog("StartWallpaperManagerService");
- try {
- wallpaper = new WallpaperManagerService(context);
- ServiceManager.addService(Context.WALLPAPER_SERVICE, wallpaper);
- } catch (Throwable e) {
- reportWtf("starting Wallpaper Service", e);
- }
+ mSystemServiceManager.startService(WALLPAPER_SERVICE_CLASS);
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
@@ -1278,12 +1244,10 @@
final NetworkPolicyManagerService networkPolicyF = networkPolicy;
final ConnectivityService connectivityF = connectivity;
final NetworkScoreService networkScoreF = networkScore;
- final WallpaperManagerService wallpaperF = wallpaper;
final LocationManagerService locationF = location;
final CountryDetectorService countryDetectorF = countryDetector;
final NetworkTimeUpdateService networkTimeUpdaterF = networkTimeUpdater;
final CommonTimeManagementService commonTimeMgmtServiceF = commonTimeMgmtService;
- final StatusBarManagerService statusBarF = statusBar;
final AssetAtlasService atlasF = atlas;
final InputManagerService inputManagerF = inputManager;
final TelephonyRegistry telephonyRegistryF = telephonyRegistry;
@@ -1371,11 +1335,6 @@
SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
try {
- if (wallpaperF != null) wallpaperF.systemRunning();
- } catch (Throwable e) {
- reportWtf("Notifying WallpaperService running", e);
- }
- try {
if (locationF != null) locationF.systemRunning();
} catch (Throwable e) {
reportWtf("Notifying Location Service running", e);