summaryrefslogtreecommitdiffstats
path: root/services/java/com
diff options
context:
space:
mode:
authorAmith Yamasani <yamasani@google.com>2012-02-06 12:04:42 -0800
committerAmith Yamasani <yamasani@google.com>2012-02-10 14:34:07 -0800
commit37ce3a8af6faab675319d0803b288ab1dddc76be (patch)
tree4619ebc854dc7c5ebe641bc915599ab6715deed9 /services/java/com
parent11ca31729c05a5c82aa298fb52ddebbe08a26627 (diff)
downloadframeworks_base-37ce3a8af6faab675319d0803b288ab1dddc76be.zip
frameworks_base-37ce3a8af6faab675319d0803b288ab1dddc76be.tar.gz
frameworks_base-37ce3a8af6faab675319d0803b288ab1dddc76be.tar.bz2
Multi-user - wallpaper service
- Allow each user to have their own wallpaper (live or static). - Migrate old wallpaper on upgrade. - Update SystemBackupAgent to backup/restore from primary user's new wallpaper directory. Reduce dependency on Binder.getOrigCallingUser() by passing the userId for bindService. Change-Id: I19c8c3296d3d2efa7f28f951d4b84407489e2166
Diffstat (limited to 'services/java/com')
-rw-r--r--services/java/com/android/server/AppWidgetServiceImpl.java22
-rw-r--r--services/java/com/android/server/SystemBackupAgent.java26
-rw-r--r--services/java/com/android/server/WallpaperManagerService.java740
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java77
-rw-r--r--services/java/com/android/server/am/ProviderMap.java2
5 files changed, 550 insertions, 317 deletions
diff --git a/services/java/com/android/server/AppWidgetServiceImpl.java b/services/java/com/android/server/AppWidgetServiceImpl.java
index 250386f..41ede2e 100644
--- a/services/java/com/android/server/AppWidgetServiceImpl.java
+++ b/services/java/com/android/server/AppWidgetServiceImpl.java
@@ -573,12 +573,13 @@ class AppWidgetServiceImpl {
mBoundRemoteViewsServices.remove(key);
}
+ int userId = UserId.getUserId(id.provider.uid);
// Bind to the RemoteViewsService (which will trigger a callback to the
// RemoteViewsAdapter.onServiceConnected())
final long token = Binder.clearCallingIdentity();
try {
conn = new ServiceConnectionProxy(key, connection);
- mContext.bindService(intent, conn, Context.BIND_AUTO_CREATE);
+ mContext.bindService(intent, conn, Context.BIND_AUTO_CREATE, userId);
mBoundRemoteViewsServices.put(key, conn);
} finally {
Binder.restoreCallingIdentity(token);
@@ -638,11 +639,11 @@ class AppWidgetServiceImpl {
// Check if we need to destroy any services (if no other app widgets are
// referencing the same service)
- decrementAppWidgetServiceRefCount(appWidgetId);
+ decrementAppWidgetServiceRefCount(id);
}
// Destroys the cached factory on the RemoteViewsService's side related to the specified intent
- private void destroyRemoteViewsService(final Intent intent) {
+ private void destroyRemoteViewsService(final Intent intent, AppWidgetId id) {
final ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
@@ -663,11 +664,12 @@ class AppWidgetServiceImpl {
}
};
+ int userId = UserId.getUserId(id.provider.uid);
// Bind to the service and remove the static intent->factory mapping in the
// RemoteViewsService.
final long token = Binder.clearCallingIdentity();
try {
- mContext.bindService(intent, conn, Context.BIND_AUTO_CREATE);
+ mContext.bindService(intent, conn, Context.BIND_AUTO_CREATE, userId);
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -687,16 +689,16 @@ class AppWidgetServiceImpl {
// Subtracts from the ref-count for a given RemoteViewsService intent, prompting a delete if
// the ref-count reaches zero.
- private void decrementAppWidgetServiceRefCount(int appWidgetId) {
+ private void decrementAppWidgetServiceRefCount(AppWidgetId id) {
Iterator<FilterComparison> it = mRemoteViewsServicesAppWidgets.keySet().iterator();
while (it.hasNext()) {
final FilterComparison key = it.next();
final HashSet<Integer> ids = mRemoteViewsServicesAppWidgets.get(key);
- if (ids.remove(appWidgetId)) {
+ if (ids.remove(id.appWidgetId)) {
// If we have removed the last app widget referencing this service, then we
// should destroy it and remove it from this set
if (ids.isEmpty()) {
- destroyRemoteViewsService(key.getIntent());
+ destroyRemoteViewsService(key.getIntent(), id);
it.remove();
}
}
@@ -888,10 +890,11 @@ class AppWidgetServiceImpl {
}
};
+ int userId = UserId.getUserId(id.provider.uid);
// Bind to the service and call onDataSetChanged()
final long token = Binder.clearCallingIdentity();
try {
- mContext.bindService(intent, conn, Context.BIND_AUTO_CREATE);
+ mContext.bindService(intent, conn, Context.BIND_AUTO_CREATE, userId);
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -1343,7 +1346,6 @@ class AppWidgetServiceImpl {
void readStateFromFileLocked(FileInputStream stream) {
boolean success = false;
-
try {
XmlPullParser parser = Xml.newPullParser();
parser.setInput(stream, null);
@@ -1475,7 +1477,7 @@ class AppWidgetServiceImpl {
}
AtomicFile savedStateFile() {
- int userId = Binder.getOrigCallingUser();
+ int userId = UserId.getCallingUserId();
File dir = new File("/data/system/users/" + userId);
File settingsFile = new File(dir, SETTINGS_FILENAME);
if (!dir.exists()) {
diff --git a/services/java/com/android/server/SystemBackupAgent.java b/services/java/com/android/server/SystemBackupAgent.java
index da97089..a7a583c 100644
--- a/services/java/com/android/server/SystemBackupAgent.java
+++ b/services/java/com/android/server/SystemBackupAgent.java
@@ -44,12 +44,16 @@ public class SystemBackupAgent extends BackupAgentHelper {
private static final String WALLPAPER_IMAGE_FILENAME = "wallpaper";
private static final String WALLPAPER_INFO_FILENAME = "wallpaper_info.xml";
- private static final String WALLPAPER_IMAGE_DIR = "/data/data/com.android.settings/files";
- private static final String WALLPAPER_IMAGE = WALLPAPER_IMAGE_DIR + "/" + WALLPAPER_IMAGE_FILENAME;
-
- private static final String WALLPAPER_INFO_DIR = "/data/system";
- private static final String WALLPAPER_INFO = WALLPAPER_INFO_DIR + "/" + WALLPAPER_INFO_FILENAME;
+ // TODO: Will need to change if backing up non-primary user's wallpaper
+ private static final String WALLPAPER_IMAGE_DIR = "/data/system/users/0";
+ private static final String WALLPAPER_IMAGE = WallpaperBackupHelper.WALLPAPER_IMAGE;
+ // TODO: Will need to change if backing up non-primary user's wallpaper
+ private static final String WALLPAPER_INFO_DIR = "/data/system/users/0";
+ private static final String WALLPAPER_INFO = WallpaperBackupHelper.WALLPAPER_INFO;
+ // Use old keys to keep legacy data compatibility and avoid writing two wallpapers
+ private static final String WALLPAPER_IMAGE_KEY = WallpaperBackupHelper.WALLPAPER_IMAGE_KEY;
+ private static final String WALLPAPER_INFO_KEY = WallpaperBackupHelper.WALLPAPER_INFO_KEY;
@Override
public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
@@ -58,13 +62,15 @@ public class SystemBackupAgent extends BackupAgentHelper {
WallpaperManagerService wallpaper = (WallpaperManagerService)ServiceManager.getService(
Context.WALLPAPER_SERVICE);
String[] files = new String[] { WALLPAPER_IMAGE, WALLPAPER_INFO };
- if (wallpaper != null && wallpaper.mName != null && wallpaper.mName.length() > 0) {
+ String[] keys = new String[] { WALLPAPER_IMAGE_KEY, WALLPAPER_INFO_KEY };
+ if (wallpaper != null && wallpaper.getName() != null && wallpaper.getName().length() > 0) {
// When the wallpaper has a name, back up the info by itself.
// TODO: Don't rely on the innards of the service object like this!
// TODO: Send a delete for any stored wallpaper image in this case?
files = new String[] { WALLPAPER_INFO };
+ keys = new String[] { WALLPAPER_INFO_KEY };
}
- addHelper("wallpaper", new WallpaperBackupHelper(SystemBackupAgent.this, files));
+ addHelper("wallpaper", new WallpaperBackupHelper(SystemBackupAgent.this, files, keys));
super.onBackup(oldState, data, newState);
}
@@ -90,9 +96,11 @@ public class SystemBackupAgent extends BackupAgentHelper {
throws IOException {
// On restore, we also support a previous data schema "system_files"
addHelper("wallpaper", new WallpaperBackupHelper(SystemBackupAgent.this,
- new String[] { WALLPAPER_IMAGE, WALLPAPER_INFO }));
+ new String[] { WALLPAPER_IMAGE, WALLPAPER_INFO },
+ new String[] { WALLPAPER_IMAGE_KEY, WALLPAPER_INFO_KEY} ));
addHelper("system_files", new WallpaperBackupHelper(SystemBackupAgent.this,
- new String[] { WALLPAPER_IMAGE }));
+ new String[] { WALLPAPER_IMAGE },
+ new String[] { WALLPAPER_IMAGE_KEY} ));
try {
super.onRestore(data, appVersionCode, newState);
diff --git a/services/java/com/android/server/WallpaperManagerService.java b/services/java/com/android/server/WallpaperManagerService.java
index 4925a4e..8ee12bc 100644
--- a/services/java/com/android/server/WallpaperManagerService.java
+++ b/services/java/com/android/server/WallpaperManagerService.java
@@ -24,6 +24,7 @@ import android.app.IWallpaperManagerCallback;
import android.app.PendingIntent;
import android.app.WallpaperInfo;
import android.app.backup.BackupManager;
+import android.app.backup.WallpaperBackupHelper;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -43,11 +44,13 @@ import android.os.ParcelFileDescriptor;
import android.os.RemoteCallbackList;
import android.os.ServiceManager;
import android.os.SystemClock;
+import android.os.UserId;
import android.service.wallpaper.IWallpaperConnection;
import android.service.wallpaper.IWallpaperEngine;
import android.service.wallpaper.IWallpaperService;
import android.service.wallpaper.WallpaperService;
import android.util.Slog;
+import android.util.SparseArray;
import android.util.Xml;
import android.view.Display;
import android.view.IWindowManager;
@@ -70,6 +73,7 @@ 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.server.am.ActivityManagerService;
class WallpaperManagerService extends IWallpaperManager.Stub {
static final String TAG = "WallpaperService";
@@ -83,17 +87,9 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
*/
static final long MIN_WALLPAPER_CRASH_TIME = 10000;
- static final File WALLPAPER_DIR = new File(
- "/data/data/com.android.settings/files");
+ static final File WALLPAPER_BASE_DIR = new File("/data/system/users");
static final String WALLPAPER = "wallpaper";
- static final File WALLPAPER_FILE = new File(WALLPAPER_DIR, WALLPAPER);
-
- /**
- * List of callbacks registered they should each be notified
- * when the wallpaper is changed.
- */
- private final RemoteCallbackList<IWallpaperManagerCallback> mCallbacks
- = new RemoteCallbackList<IWallpaperManagerCallback>();
+ static final String WALLPAPER_INFO = "wallpaper_info.xml";
/**
* Observes the wallpaper for changes and notifies all IWallpaperServiceCallbacks
@@ -101,97 +97,135 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
* wallpaper set and is created for the first time. The CLOSE_WRITE is triggered
* everytime the wallpaper is changed.
*/
- private final FileObserver mWallpaperObserver = new FileObserver(
- WALLPAPER_DIR.getAbsolutePath(), CLOSE_WRITE | DELETE | DELETE_SELF) {
- @Override
- public void onEvent(int event, String path) {
- if (path == null) {
- return;
- }
- synchronized (mLock) {
- // changing the wallpaper means we'll need to back up the new one
- long origId = Binder.clearCallingIdentity();
- BackupManager bm = new BackupManager(mContext);
- bm.dataChanged();
- Binder.restoreCallingIdentity(origId);
-
- File changedFile = new File(WALLPAPER_DIR, path);
- if (WALLPAPER_FILE.equals(changedFile)) {
- notifyCallbacksLocked();
- if (mWallpaperComponent == null || event != CLOSE_WRITE
- || mImageWallpaperPending) {
- if (event == CLOSE_WRITE) {
- mImageWallpaperPending = false;
- }
- bindWallpaperComponentLocked(mImageWallpaperComponent,
- true, false);
- saveSettingsLocked();
- }
+ private class WallpaperObserver extends FileObserver {
+
+ final WallpaperData mWallpaper;
+ final File mWallpaperDir;
+ final File mWallpaperFile;
+
+ public WallpaperObserver(WallpaperData wallpaper) {
+ super(getWallpaperDir(wallpaper.userId).getAbsolutePath(),
+ CLOSE_WRITE | DELETE | DELETE_SELF);
+ mWallpaperDir = getWallpaperDir(wallpaper.userId);
+ mWallpaper = wallpaper;
+ mWallpaperFile = new File(mWallpaperDir, WALLPAPER);
+ }
+
+ @Override
+ public void onEvent(int event, String path) {
+ if (path == null) {
+ return;
+ }
+ synchronized (mLock) {
+ // changing the wallpaper means we'll need to back up the new one
+ long origId = Binder.clearCallingIdentity();
+ BackupManager bm = new BackupManager(mContext);
+ bm.dataChanged();
+ Binder.restoreCallingIdentity(origId);
+
+ File changedFile = new File(mWallpaperDir, path);
+ if (mWallpaperFile.equals(changedFile)) {
+ notifyCallbacksLocked(mWallpaper);
+ if (mWallpaper.wallpaperComponent == null || event != CLOSE_WRITE
+ || mWallpaper.imageWallpaperPending) {
+ if (event == CLOSE_WRITE) {
+ mWallpaper.imageWallpaperPending = false;
}
+ bindWallpaperComponentLocked(mWallpaper.imageWallpaperComponent, true,
+ false, mWallpaper);
+ saveSettingsLocked(mWallpaper);
}
}
- };
-
+ }
+ }
+ }
+
final Context mContext;
final IWindowManager mIWindowManager;
final MyPackageMonitor mMonitor;
+ WallpaperData mLastWallpaper;
- int mWidth = -1;
- int mHeight = -1;
+ SparseArray<WallpaperData> mWallpaperMap = new SparseArray<WallpaperData>();
- /**
- * Client is currently writing a new image wallpaper.
- */
- boolean mImageWallpaperPending;
+ int mCurrentUserId;
+
+ static class WallpaperData {
+
+ int userId;
+
+ File wallpaperFile;
+
+ /**
+ * Client is currently writing a new image wallpaper.
+ */
+ boolean imageWallpaperPending;
+
+ /**
+ * Resource name if using a picture from the wallpaper gallery
+ */
+ String name = "";
+
+ /**
+ * The component name of the currently set live wallpaper.
+ */
+ ComponentName wallpaperComponent;
+
+ /**
+ * The component name of the wallpaper that should be set next.
+ */
+ ComponentName nextWallpaperComponent;
+
+ /**
+ * Name of the component used to display bitmap wallpapers from either the gallery or
+ * built-in wallpapers.
+ */
+ ComponentName imageWallpaperComponent = new ComponentName("com.android.systemui",
+ "com.android.systemui.ImageWallpaper");
+
+ WallpaperConnection connection;
+ long lastDiedTime;
+ boolean wallpaperUpdating;
+ WallpaperObserver wallpaperObserver;
+
+ /**
+ * List of callbacks registered they should each be notified when the wallpaper is changed.
+ */
+ private RemoteCallbackList<IWallpaperManagerCallback> callbacks
+ = new RemoteCallbackList<IWallpaperManagerCallback>();
+
+ int width = -1;
+ int height = -1;
+
+ WallpaperData(int userId) {
+ this.userId = userId;
+ wallpaperFile = new File(getWallpaperDir(userId), WALLPAPER);
+ }
+ }
- /**
- * Resource name if using a picture from the wallpaper gallery
- */
- String mName = "";
-
- /**
- * The component name of the currently set live wallpaper.
- */
- ComponentName mWallpaperComponent;
-
- /**
- * The component name of the wallpaper that should be set next.
- */
- ComponentName mNextWallpaperComponent;
-
- /**
- * Name of the component used to display bitmap wallpapers from either the gallery or
- * built-in wallpapers.
- */
- ComponentName mImageWallpaperComponent = new ComponentName("com.android.systemui",
- "com.android.systemui.ImageWallpaper");
-
- WallpaperConnection mWallpaperConnection;
- long mLastDiedTime;
- boolean mWallpaperUpdating;
-
class WallpaperConnection extends IWallpaperConnection.Stub
implements ServiceConnection {
final WallpaperInfo mInfo;
final Binder mToken = new Binder();
IWallpaperService mService;
IWallpaperEngine mEngine;
+ WallpaperData mWallpaper;
- public WallpaperConnection(WallpaperInfo info) {
+ public WallpaperConnection(WallpaperInfo info, WallpaperData wallpaper) {
mInfo = info;
+ mWallpaper = wallpaper;
}
public void onServiceConnected(ComponentName name, IBinder service) {
synchronized (mLock) {
- if (mWallpaperConnection == this) {
- mLastDiedTime = SystemClock.uptimeMillis();
+ if (mWallpaper.connection == this) {
+ mWallpaper.lastDiedTime = SystemClock.uptimeMillis();
mService = IWallpaperService.Stub.asInterface(service);
- attachServiceLocked(this);
+ attachServiceLocked(this, mWallpaper);
// XXX should probably do saveSettingsLocked() later
// when we have an engine, but I'm not sure about
// locking there and anyway we always need to be able to
// recover if there is something wrong.
- saveSettingsLocked();
+ saveSettingsLocked(mWallpaper);
}
}
}
@@ -200,43 +234,50 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
synchronized (mLock) {
mService = null;
mEngine = null;
- if (mWallpaperConnection == this) {
- Slog.w(TAG, "Wallpaper service gone: " + mWallpaperComponent);
- if (!mWallpaperUpdating && (mLastDiedTime+MIN_WALLPAPER_CRASH_TIME)
- > SystemClock.uptimeMillis()) {
+ if (mWallpaper.connection == this) {
+ Slog.w(TAG, "Wallpaper service gone: " + mWallpaper.wallpaperComponent);
+ if (!mWallpaper.wallpaperUpdating
+ && (mWallpaper.lastDiedTime + MIN_WALLPAPER_CRASH_TIME)
+ > SystemClock.uptimeMillis()
+ && mWallpaper.userId == mCurrentUserId) {
Slog.w(TAG, "Reverting to built-in wallpaper!");
- clearWallpaperLocked(true);
+ clearWallpaperLocked(true, mWallpaper.userId);
}
}
}
}
-
+
public void attachEngine(IWallpaperEngine engine) {
mEngine = engine;
}
-
+
public ParcelFileDescriptor setWallpaper(String name) {
synchronized (mLock) {
- if (mWallpaperConnection == this) {
- return updateWallpaperBitmapLocked(name);
+ if (mWallpaper.connection == this) {
+ return updateWallpaperBitmapLocked(name, mWallpaper);
}
return null;
}
}
}
-
+
class MyPackageMonitor extends PackageMonitor {
@Override
public void onPackageUpdateFinished(String packageName, int uid) {
synchronized (mLock) {
- if (mWallpaperComponent != null &&
- mWallpaperComponent.getPackageName().equals(packageName)) {
- mWallpaperUpdating = false;
- ComponentName comp = mWallpaperComponent;
- clearWallpaperComponentLocked();
- if (!bindWallpaperComponentLocked(comp, false, false)) {
- Slog.w(TAG, "Wallpaper no longer available; reverting to default");
- clearWallpaperLocked(false);
+ for (int i = 0; i < mWallpaperMap.size(); i++) {
+ WallpaperData wallpaper = mWallpaperMap.valueAt(i);
+ if (wallpaper.wallpaperComponent != null
+ && wallpaper.wallpaperComponent.getPackageName().equals(packageName)) {
+ wallpaper.wallpaperUpdating = false;
+ ComponentName comp = wallpaper.wallpaperComponent;
+ clearWallpaperComponentLocked(wallpaper);
+ // Do this only for the current user's wallpaper
+ if (wallpaper.userId == mCurrentUserId
+ && !bindWallpaperComponentLocked(comp, false, false, wallpaper)) {
+ Slog.w(TAG, "Wallpaper no longer available; reverting to default");
+ clearWallpaperLocked(false, wallpaper.userId);
+ }
}
}
}
@@ -245,72 +286,91 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
@Override
public void onPackageModified(String packageName) {
synchronized (mLock) {
- if (mWallpaperComponent == null ||
- !mWallpaperComponent.getPackageName().equals(packageName)) {
- return;
+ for (int i = 0; i < mWallpaperMap.size(); i++) {
+ WallpaperData wallpaper = mWallpaperMap.valueAt(i);
+ if (wallpaper.wallpaperComponent == null
+ || !wallpaper.wallpaperComponent.getPackageName().equals(packageName)) {
+ continue;
+ }
+ doPackagesChanged(true, wallpaper);
}
}
- doPackagesChanged(true);
}
@Override
public void onPackageUpdateStarted(String packageName, int uid) {
synchronized (mLock) {
- if (mWallpaperComponent != null &&
- mWallpaperComponent.getPackageName().equals(packageName)) {
- mWallpaperUpdating = true;
+ for (int i = 0; i < mWallpaperMap.size(); i++) {
+ WallpaperData wallpaper = mWallpaperMap.valueAt(i);
+ if (wallpaper.wallpaperComponent != null
+ && wallpaper.wallpaperComponent.getPackageName().equals(packageName)) {
+ wallpaper.wallpaperUpdating = true;
+ }
}
}
}
@Override
public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
- return doPackagesChanged(doit);
+ boolean changed = false;
+ for (int i = 0; i < mWallpaperMap.size(); i++) {
+ WallpaperData wallpaper = mWallpaperMap.valueAt(i);
+ boolean res = doPackagesChanged(doit, wallpaper);
+ changed |= res;
+ }
+ return changed;
}
@Override
public void onSomePackagesChanged() {
- doPackagesChanged(true);
+ for (int i = 0; i < mWallpaperMap.size(); i++) {
+ WallpaperData wallpaper = mWallpaperMap.valueAt(i);
+ doPackagesChanged(true, wallpaper);
+ }
}
-
- boolean doPackagesChanged(boolean doit) {
+
+ boolean doPackagesChanged(boolean doit, WallpaperData wallpaper) {
boolean changed = false;
synchronized (mLock) {
- if (mWallpaperComponent != null) {
- int change = isPackageDisappearing(mWallpaperComponent.getPackageName());
+ if (wallpaper.wallpaperComponent != null) {
+ int change = isPackageDisappearing(wallpaper.wallpaperComponent
+ .getPackageName());
if (change == PACKAGE_PERMANENT_CHANGE
|| change == PACKAGE_TEMPORARY_CHANGE) {
changed = true;
if (doit) {
- Slog.w(TAG, "Wallpaper uninstalled, removing: " + mWallpaperComponent);
- clearWallpaperLocked(false);
+ Slog.w(TAG, "Wallpaper uninstalled, removing: "
+ + wallpaper.wallpaperComponent);
+ clearWallpaperLocked(false, wallpaper.userId);
}
}
}
- if (mNextWallpaperComponent != null) {
- int change = isPackageDisappearing(mNextWallpaperComponent.getPackageName());
+ if (wallpaper.nextWallpaperComponent != null) {
+ int change = isPackageDisappearing(wallpaper.nextWallpaperComponent
+ .getPackageName());
if (change == PACKAGE_PERMANENT_CHANGE
|| change == PACKAGE_TEMPORARY_CHANGE) {
- mNextWallpaperComponent = null;
+ wallpaper.nextWallpaperComponent = null;
}
}
- if (mWallpaperComponent != null
- && isPackageModified(mWallpaperComponent.getPackageName())) {
+ if (wallpaper.wallpaperComponent != null
+ && isPackageModified(wallpaper.wallpaperComponent.getPackageName())) {
try {
mContext.getPackageManager().getServiceInfo(
- mWallpaperComponent, 0);
+ wallpaper.wallpaperComponent, 0);
} catch (NameNotFoundException e) {
- Slog.w(TAG, "Wallpaper component gone, removing: " + mWallpaperComponent);
- clearWallpaperLocked(false);
+ Slog.w(TAG, "Wallpaper component gone, removing: "
+ + wallpaper.wallpaperComponent);
+ clearWallpaperLocked(false, wallpaper.userId);
}
}
- if (mNextWallpaperComponent != null
- && isPackageModified(mNextWallpaperComponent.getPackageName())) {
+ if (wallpaper.nextWallpaperComponent != null
+ && isPackageModified(wallpaper.nextWallpaperComponent.getPackageName())) {
try {
mContext.getPackageManager().getServiceInfo(
- mNextWallpaperComponent, 0);
+ wallpaper.nextWallpaperComponent, 0);
} catch (NameNotFoundException e) {
- mNextWallpaperComponent = null;
+ wallpaper.nextWallpaperComponent = null;
}
}
}
@@ -325,51 +385,110 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
ServiceManager.getService(Context.WINDOW_SERVICE));
mMonitor = new MyPackageMonitor();
mMonitor.register(context, true);
- WALLPAPER_DIR.mkdirs();
- loadSettingsLocked();
- mWallpaperObserver.startWatching();
+ WALLPAPER_BASE_DIR.mkdirs();
+ loadSettingsLocked(0);
}
+ private static File getWallpaperDir(int userId) {
+ return new File(WALLPAPER_BASE_DIR + "/" + userId);
+ }
+
@Override
protected void finalize() throws Throwable {
super.finalize();
- mWallpaperObserver.stopWatching();
+ for (int i = 0; i < mWallpaperMap.size(); i++) {
+ WallpaperData wallpaper = mWallpaperMap.valueAt(i);
+ wallpaper.wallpaperObserver.stopWatching();
+ }
}
public void systemReady() {
if (DEBUG) Slog.v(TAG, "systemReady");
+ WallpaperData wallpaper = mWallpaperMap.get(0);
+ switchWallpaper(wallpaper);
+ wallpaper.wallpaperObserver = new WallpaperObserver(wallpaper);
+ wallpaper.wallpaperObserver.startWatching();
+ ActivityManagerService ams = (ActivityManagerService) ServiceManager
+ .getService(Context.ACTIVITY_SERVICE);
+ ams.addUserListener(new ActivityManagerService.UserListener() {
+
+ @Override
+ public void onUserChanged(int userId) {
+ switchUser(userId);
+ }
+
+ @Override
+ public void onUserAdded(int userId) {
+ }
+
+ @Override
+ public void onUserRemoved(int userId) {
+ }
+
+ @Override
+ public void onUserLoggedOut(int userId) {
+ }
+
+ });
+ }
+
+ String getName() {
+ return mWallpaperMap.get(0).name;
+ }
+
+ void switchUser(int userId) {
+ synchronized (mLock) {
+ mCurrentUserId = userId;
+ WallpaperData wallpaper = mWallpaperMap.get(userId);
+ if (wallpaper == null) {
+ wallpaper = new WallpaperData(userId);
+ mWallpaperMap.put(userId, wallpaper);
+ loadSettingsLocked(userId);
+ wallpaper.wallpaperObserver = new WallpaperObserver(wallpaper);
+ wallpaper.wallpaperObserver.startWatching();
+ }
+ switchWallpaper(wallpaper);
+ }
+ }
+
+ void switchWallpaper(WallpaperData wallpaper) {
synchronized (mLock) {
RuntimeException e = null;
try {
- if (bindWallpaperComponentLocked(mNextWallpaperComponent, false, false)) {
+ ComponentName cname = wallpaper.wallpaperComponent != null ?
+ wallpaper.wallpaperComponent : wallpaper.nextWallpaperComponent;
+ if (bindWallpaperComponentLocked(cname, true, false, wallpaper)) {
return;
}
} catch (RuntimeException e1) {
e = e1;
}
Slog.w(TAG, "Failure starting previous wallpaper", e);
- clearWallpaperLocked(false);
+ clearWallpaperLocked(false, wallpaper.userId);
}
}
-
+
public void clearWallpaper() {
if (DEBUG) Slog.v(TAG, "clearWallpaper");
synchronized (mLock) {
- clearWallpaperLocked(false);
+ clearWallpaperLocked(false, UserId.getCallingUserId());
}
}
- public void clearWallpaperLocked(boolean defaultFailed) {
- File f = WALLPAPER_FILE;
+ void clearWallpaperLocked(boolean defaultFailed, int userId) {
+ WallpaperData wallpaper = mWallpaperMap.get(userId);
+ File f = new File(getWallpaperDir(userId), WALLPAPER);
if (f.exists()) {
f.delete();
}
final long ident = Binder.clearCallingIdentity();
RuntimeException e = null;
try {
- mImageWallpaperPending = false;
+ wallpaper.imageWallpaperPending = false;
+ if (userId != mCurrentUserId) return;
if (bindWallpaperComponentLocked(defaultFailed
- ? mImageWallpaperComponent : null, true, false)) {
+ ? wallpaper.imageWallpaperComponent
+ : null, true, false, wallpaper)) {
return;
}
} catch (IllegalArgumentException e1) {
@@ -383,29 +502,35 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
// let's not let it crash the system and just live with no
// wallpaper.
Slog.e(TAG, "Default wallpaper component not found!", e);
- clearWallpaperComponentLocked();
+ clearWallpaperComponentLocked(wallpaper);
}
public void setDimensionHints(int width, int height) throws RemoteException {
checkPermission(android.Manifest.permission.SET_WALLPAPER_HINTS);
+ int userId = UserId.getCallingUserId();
+ WallpaperData wallpaper = mWallpaperMap.get(userId);
+ if (wallpaper == null) {
+ throw new IllegalStateException("Wallpaper not yet initialized for user " + userId);
+ }
if (width <= 0 || height <= 0) {
throw new IllegalArgumentException("width and height must be > 0");
}
synchronized (mLock) {
- if (width != mWidth || height != mHeight) {
- mWidth = width;
- mHeight = height;
- saveSettingsLocked();
- if (mWallpaperConnection != null) {
- if (mWallpaperConnection.mEngine != null) {
+ if (width != wallpaper.width || height != wallpaper.height) {
+ wallpaper.width = width;
+ wallpaper.height = height;
+ saveSettingsLocked(wallpaper);
+ if (mCurrentUserId != userId) return; // Don't change the properties now
+ if (wallpaper.connection != null) {
+ if (wallpaper.connection.mEngine != null) {
try {
- mWallpaperConnection.mEngine.setDesiredSize(
+ wallpaper.connection.mEngine.setDesiredSize(
width, height);
} catch (RemoteException e) {
}
- notifyCallbacksLocked();
+ notifyCallbacksLocked(wallpaper);
}
}
}
@@ -414,26 +539,38 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
public int getWidthHint() throws RemoteException {
synchronized (mLock) {
- return mWidth;
+ WallpaperData wallpaper = mWallpaperMap.get(UserId.getCallingUserId());
+ return wallpaper.width;
}
}
public int getHeightHint() throws RemoteException {
synchronized (mLock) {
- return mHeight;
+ WallpaperData wallpaper = mWallpaperMap.get(UserId.getCallingUserId());
+ return wallpaper.height;
}
}
public ParcelFileDescriptor getWallpaper(IWallpaperManagerCallback cb,
Bundle outParams) {
synchronized (mLock) {
+ // This returns the current user's wallpaper, if called by a system service. Else it
+ // returns the wallpaper for the calling user.
+ int callingUid = Binder.getCallingUid();
+ int wallpaperUserId = 0;
+ if (callingUid == android.os.Process.SYSTEM_UID) {
+ wallpaperUserId = mCurrentUserId;
+ } else {
+ wallpaperUserId = UserId.getUserId(callingUid);
+ }
+ WallpaperData wallpaper = mWallpaperMap.get(wallpaperUserId);
try {
if (outParams != null) {
- outParams.putInt("width", mWidth);
- outParams.putInt("height", mHeight);
+ outParams.putInt("width", wallpaper.width);
+ outParams.putInt("height", wallpaper.height);
}
- mCallbacks.register(cb);
- File f = WALLPAPER_FILE;
+ wallpaper.callbacks.register(cb);
+ File f = new File(getWallpaperDir(wallpaperUserId), WALLPAPER);
if (!f.exists()) {
return null;
}
@@ -447,24 +584,30 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
}
public WallpaperInfo getWallpaperInfo() {
+ int userId = UserId.getCallingUserId();
synchronized (mLock) {
- if (mWallpaperConnection != null) {
- return mWallpaperConnection.mInfo;
+ WallpaperData wallpaper = mWallpaperMap.get(userId);
+ if (wallpaper.connection != null) {
+ return wallpaper.connection.mInfo;
}
return null;
}
}
-
+
public ParcelFileDescriptor setWallpaper(String name) {
if (DEBUG) Slog.v(TAG, "setWallpaper");
-
+ int userId = UserId.getCallingUserId();
+ WallpaperData wallpaper = mWallpaperMap.get(userId);
+ if (wallpaper == null) {
+ throw new IllegalStateException("Wallpaper not yet initialized for user " + userId);
+ }
checkPermission(android.Manifest.permission.SET_WALLPAPER);
synchronized (mLock) {
final long ident = Binder.clearCallingIdentity();
try {
- ParcelFileDescriptor pfd = updateWallpaperBitmapLocked(name);
+ ParcelFileDescriptor pfd = updateWallpaperBitmapLocked(name, wallpaper);
if (pfd != null) {
- mImageWallpaperPending = true;
+ wallpaper.imageWallpaperPending = true;
}
return pfd;
} finally {
@@ -473,19 +616,20 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
}
}
- ParcelFileDescriptor updateWallpaperBitmapLocked(String name) {
+ ParcelFileDescriptor updateWallpaperBitmapLocked(String name, WallpaperData wallpaper) {
if (name == null) name = "";
try {
- if (!WALLPAPER_DIR.exists()) {
- WALLPAPER_DIR.mkdir();
+ File dir = getWallpaperDir(wallpaper.userId);
+ if (!dir.exists()) {
+ dir.mkdir();
FileUtils.setPermissions(
- WALLPAPER_DIR.getPath(),
+ dir.getPath(),
FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
-1, -1);
}
- ParcelFileDescriptor fd = ParcelFileDescriptor.open(WALLPAPER_FILE,
+ ParcelFileDescriptor fd = ParcelFileDescriptor.open(new File(dir, WALLPAPER),
MODE_CREATE|MODE_READ_WRITE);
- mName = name;
+ wallpaper.name = name;
return fd;
} catch (FileNotFoundException e) {
Slog.w(TAG, "Error setting wallpaper", e);
@@ -495,31 +639,36 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
public void setWallpaperComponent(ComponentName name) {
if (DEBUG) Slog.v(TAG, "setWallpaperComponent name=" + name);
+ int userId = UserId.getCallingUserId();
+ WallpaperData wallpaper = mWallpaperMap.get(userId);
+ if (wallpaper == null) {
+ throw new IllegalStateException("Wallpaper not yet initialized for user " + userId);
+ }
checkPermission(android.Manifest.permission.SET_WALLPAPER_COMPONENT);
synchronized (mLock) {
final long ident = Binder.clearCallingIdentity();
try {
- mImageWallpaperPending = false;
- bindWallpaperComponentLocked(name, false, true);
+ wallpaper.imageWallpaperPending = false;
+ bindWallpaperComponentLocked(name, false, true, wallpaper);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
}
- boolean bindWallpaperComponentLocked(ComponentName componentName, boolean force, boolean fromUser) {
+ boolean bindWallpaperComponentLocked(ComponentName componentName, boolean force,
+ boolean fromUser, WallpaperData wallpaper) {
if (DEBUG) Slog.v(TAG, "bindWallpaperComponentLocked: componentName=" + componentName);
-
// Has the component changed?
if (!force) {
- if (mWallpaperConnection != null) {
- if (mWallpaperComponent == null) {
+ if (wallpaper.connection != null) {
+ if (wallpaper.wallpaperComponent == null) {
if (componentName == null) {
if (DEBUG) Slog.v(TAG, "bindWallpaperComponentLocked: still using default");
// Still using default wallpaper.
return true;
}
- } else if (mWallpaperComponent.equals(componentName)) {
+ } else if (wallpaper.wallpaperComponent.equals(componentName)) {
// Changing to same wallpaper.
if (DEBUG) Slog.v(TAG, "same wallpaper");
return true;
@@ -538,7 +687,7 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
}
if (componentName == null) {
// Fall back to static image wallpaper
- componentName = mImageWallpaperComponent;
+ componentName = wallpaper.imageWallpaperComponent;
//clearWallpaperComponentLocked();
//return;
if (DEBUG) Slog.v(TAG, "Using image wallpaper");
@@ -560,7 +709,7 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
WallpaperInfo wi = null;
Intent intent = new Intent(WallpaperService.SERVICE_INTERFACE);
- if (componentName != null && !componentName.equals(mImageWallpaperComponent)) {
+ if (componentName != null && !componentName.equals(wallpaper.imageWallpaperComponent)) {
// Make sure the selected service is actually a wallpaper service.
List<ResolveInfo> ris = mContext.getPackageManager()
.queryIntentServices(intent, PackageManager.GET_META_DATA);
@@ -599,8 +748,13 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
// Bind the service!
if (DEBUG) Slog.v(TAG, "Binding to:" + componentName);
- WallpaperConnection newConn = new WallpaperConnection(wi);
+ WallpaperConnection newConn = new WallpaperConnection(wi, wallpaper);
intent.setComponent(componentName);
+ int serviceUserId = wallpaper.userId;
+ // Because the image wallpaper is running in the system ui
+ if (componentName.equals(wallpaper.imageWallpaperComponent)) {
+ serviceUserId = 0;
+ }
intent.putExtra(Intent.EXTRA_CLIENT_LABEL,
com.android.internal.R.string.wallpaper_binding_label);
intent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity(
@@ -608,8 +762,7 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
Intent.createChooser(new Intent(Intent.ACTION_SET_WALLPAPER),
mContext.getText(com.android.internal.R.string.chooser_wallpaper)),
0));
- if (!mContext.bindService(intent, newConn,
- Context.BIND_AUTO_CREATE)) {
+ if (!mContext.bindService(intent, newConn, Context.BIND_AUTO_CREATE, serviceUserId)) {
String msg = "Unable to bind service: "
+ componentName;
if (fromUser) {
@@ -618,18 +771,22 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
Slog.w(TAG, msg);
return false;
}
-
- clearWallpaperComponentLocked();
- mWallpaperComponent = componentName;
- mWallpaperConnection = newConn;
- mLastDiedTime = SystemClock.uptimeMillis();
+ if (wallpaper.userId == mCurrentUserId && mLastWallpaper != null) {
+ detachWallpaperLocked(mLastWallpaper);
+ }
+ wallpaper.wallpaperComponent = componentName;
+ wallpaper.connection = newConn;
+ wallpaper.lastDiedTime = SystemClock.uptimeMillis();
try {
- if (DEBUG) Slog.v(TAG, "Adding window token: " + newConn.mToken);
- mIWindowManager.addWindowToken(newConn.mToken,
- WindowManager.LayoutParams.TYPE_WALLPAPER);
+ if (wallpaper.userId == mCurrentUserId) {
+ if (DEBUG)
+ Slog.v(TAG, "Adding window token: " + newConn.mToken);
+ mIWindowManager.addWindowToken(newConn.mToken,
+ WindowManager.LayoutParams.TYPE_WALLPAPER);
+ mLastWallpaper = wallpaper;
+ }
} catch (RemoteException e) {
}
-
} catch (PackageManager.NameNotFoundException e) {
String msg = "Unknown component " + componentName;
if (fromUser) {
@@ -640,54 +797,58 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
}
return true;
}
-
- void clearWallpaperComponentLocked() {
- mWallpaperComponent = null;
- if (mWallpaperConnection != null) {
- if (mWallpaperConnection.mEngine != null) {
+
+ void detachWallpaperLocked(WallpaperData wallpaper) {
+ if (wallpaper.connection != null) {
+ if (wallpaper.connection.mEngine != null) {
try {
- mWallpaperConnection.mEngine.destroy();
+ wallpaper.connection.mEngine.destroy();
} catch (RemoteException e) {
}
}
- mContext.unbindService(mWallpaperConnection);
+ mContext.unbindService(wallpaper.connection);
try {
- if (DEBUG) Slog.v(TAG, "Removing window token: "
- + mWallpaperConnection.mToken);
- mIWindowManager.removeWindowToken(mWallpaperConnection.mToken);
+ if (DEBUG)
+ Slog.v(TAG, "Removing window token: " + wallpaper.connection.mToken);
+ mIWindowManager.removeWindowToken(wallpaper.connection.mToken);
} catch (RemoteException e) {
}
- mWallpaperConnection.mService = null;
- mWallpaperConnection.mEngine = null;
- mWallpaperConnection = null;
+ wallpaper.connection.mService = null;
+ wallpaper.connection.mEngine = null;
+ wallpaper.connection = null;
}
}
-
- void attachServiceLocked(WallpaperConnection conn) {
+
+ void clearWallpaperComponentLocked(WallpaperData wallpaper) {
+ wallpaper.wallpaperComponent = null;
+ detachWallpaperLocked(wallpaper);
+ }
+
+ void attachServiceLocked(WallpaperConnection conn, WallpaperData wallpaper) {
try {
conn.mService.attach(conn, conn.mToken,
WindowManager.LayoutParams.TYPE_WALLPAPER, false,
- mWidth, mHeight);
+ wallpaper.width, wallpaper.height);
} catch (RemoteException e) {
Slog.w(TAG, "Failed attaching wallpaper; clearing", e);
- if (!mWallpaperUpdating) {
- bindWallpaperComponentLocked(null, false, false);
+ if (!wallpaper.wallpaperUpdating) {
+ bindWallpaperComponentLocked(null, false, false, wallpaper);
}
}
}
-
- private void notifyCallbacksLocked() {
- final int n = mCallbacks.beginBroadcast();
+
+ private void notifyCallbacksLocked(WallpaperData wallpaper) {
+ final int n = wallpaper.callbacks.beginBroadcast();
for (int i = 0; i < n; i++) {
try {
- mCallbacks.getBroadcastItem(i).onWallpaperChanged();
+ wallpaper.callbacks.getBroadcastItem(i).onWallpaperChanged();
} catch (RemoteException e) {
// The RemoteCallbackList will take care of removing
// the dead object for us.
}
}
- mCallbacks.finishBroadcast();
+ wallpaper.callbacks.finishBroadcast();
final Intent intent = new Intent(Intent.ACTION_WALLPAPER_CHANGED);
mContext.sendBroadcast(intent);
}
@@ -699,13 +860,13 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
}
}
- private static JournaledFile makeJournaledFile() {
- final String base = "/data/system/wallpaper_info.xml";
+ private static JournaledFile makeJournaledFile(int userId) {
+ final String base = "/data/system/users/" + userId + "/" + WALLPAPER_INFO;
return new JournaledFile(new File(base), new File(base + ".tmp"));
}
- private void saveSettingsLocked() {
- JournaledFile journal = makeJournaledFile();
+ private void saveSettingsLocked(WallpaperData wallpaper) {
+ JournaledFile journal = makeJournaledFile(wallpaper.userId);
FileOutputStream stream = null;
try {
stream = new FileOutputStream(journal.chooseForWrite(), false);
@@ -714,13 +875,13 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
out.startDocument(null, true);
out.startTag(null, "wp");
- out.attribute(null, "width", Integer.toString(mWidth));
- out.attribute(null, "height", Integer.toString(mHeight));
- out.attribute(null, "name", mName);
- if (mWallpaperComponent != null &&
- !mWallpaperComponent.equals(mImageWallpaperComponent)) {
+ out.attribute(null, "width", Integer.toString(wallpaper.width));
+ out.attribute(null, "height", Integer.toString(wallpaper.height));
+ out.attribute(null, "name", wallpaper.name);
+ if (wallpaper.wallpaperComponent != null
+ && !wallpaper.wallpaperComponent.equals(wallpaper.imageWallpaperComponent)) {
out.attribute(null, "component",
- mWallpaperComponent.flattenToShortString());
+ wallpaper.wallpaperComponent.flattenToShortString());
}
out.endTag(null, "wp");
@@ -739,12 +900,34 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
}
}
- private void loadSettingsLocked() {
+ private void migrateFromOld() {
+ File oldWallpaper = new File(WallpaperBackupHelper.WALLPAPER_IMAGE_KEY);
+ File oldInfo = new File(WallpaperBackupHelper.WALLPAPER_INFO_KEY);
+ if (oldWallpaper.exists()) {
+ File newWallpaper = new File(getWallpaperDir(0), WALLPAPER);
+ oldWallpaper.renameTo(newWallpaper);
+ }
+ if (oldInfo.exists()) {
+ File newInfo = new File(getWallpaperDir(0), WALLPAPER_INFO);
+ oldInfo.renameTo(newInfo);
+ }
+ }
+
+ private void loadSettingsLocked(int userId) {
if (DEBUG) Slog.v(TAG, "loadSettingsLocked");
- JournaledFile journal = makeJournaledFile();
+ JournaledFile journal = makeJournaledFile(userId);
FileInputStream stream = null;
File file = journal.chooseForRead();
+ if (!file.exists()) {
+ // This should only happen one time, when upgrading from a legacy system
+ migrateFromOld();
+ }
+ WallpaperData wallpaper = mWallpaperMap.get(userId);
+ if (wallpaper == null) {
+ wallpaper = new WallpaperData(userId);
+ mWallpaperMap.put(userId, wallpaper);
+ }
boolean success = false;
try {
stream = new FileInputStream(file);
@@ -757,23 +940,26 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
if (type == XmlPullParser.START_TAG) {
String tag = parser.getName();
if ("wp".equals(tag)) {
- mWidth = Integer.parseInt(parser.getAttributeValue(null, "width"));
- mHeight = Integer.parseInt(parser.getAttributeValue(null, "height"));
- mName = parser.getAttributeValue(null, "name");
+ wallpaper.width = Integer.parseInt(parser.getAttributeValue(null, "width"));
+ wallpaper.height = Integer.parseInt(parser
+ .getAttributeValue(null, "height"));
+ wallpaper.name = parser.getAttributeValue(null, "name");
String comp = parser.getAttributeValue(null, "component");
- mNextWallpaperComponent = comp != null
+ wallpaper.nextWallpaperComponent = comp != null
? ComponentName.unflattenFromString(comp)
: null;
- if (mNextWallpaperComponent == null ||
- "android".equals(mNextWallpaperComponent.getPackageName())) {
- mNextWallpaperComponent = mImageWallpaperComponent;
+ if (wallpaper.nextWallpaperComponent == null
+ || "android".equals(wallpaper.nextWallpaperComponent
+ .getPackageName())) {
+ wallpaper.nextWallpaperComponent = wallpaper.imageWallpaperComponent;
}
if (DEBUG) {
- Slog.v(TAG, "mWidth:" + mWidth);
- Slog.v(TAG, "mHeight:" + mHeight);
- Slog.v(TAG, "mName:" + mName);
- Slog.v(TAG, "mNextWallpaperComponent:" + mNextWallpaperComponent);
+ Slog.v(TAG, "mWidth:" + wallpaper.width);
+ Slog.v(TAG, "mHeight:" + wallpaper.height);
+ Slog.v(TAG, "mName:" + wallpaper.name);
+ Slog.v(TAG, "mNextWallpaperComponent:"
+ + wallpaper.nextWallpaperComponent);
}
}
}
@@ -799,70 +985,75 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
}
if (!success) {
- mWidth = -1;
- mHeight = -1;
- mName = "";
+ wallpaper.width = -1;
+ wallpaper.height = -1;
+ wallpaper.name = "";
}
// We always want to have some reasonable width hint.
WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
Display d = wm.getDefaultDisplay();
int baseSize = d.getMaximumSizeDimension();
- if (mWidth < baseSize) {
- mWidth = baseSize;
+ if (wallpaper.width < baseSize) {
+ wallpaper.width = baseSize;
}
- if (mHeight < baseSize) {
- mHeight = baseSize;
+ if (wallpaper.height < baseSize) {
+ wallpaper.height = baseSize;
}
}
// Called by SystemBackupAgent after files are restored to disk.
void settingsRestored() {
+ // TODO: If necessary, make it work for secondary users as well. This currently assumes
+ // restores only to the primary user
if (DEBUG) Slog.v(TAG, "settingsRestored");
-
+ WallpaperData wallpaper = null;
boolean success = false;
synchronized (mLock) {
- loadSettingsLocked();
- if (mNextWallpaperComponent != null &&
- !mNextWallpaperComponent.equals(mImageWallpaperComponent)) {
- if (!bindWallpaperComponentLocked(mNextWallpaperComponent, false, false)) {
+ loadSettingsLocked(0);
+ wallpaper = mWallpaperMap.get(0);
+ if (wallpaper.nextWallpaperComponent != null
+ && !wallpaper.nextWallpaperComponent.equals(wallpaper.imageWallpaperComponent)) {
+ if (!bindWallpaperComponentLocked(wallpaper.nextWallpaperComponent, false, false,
+ wallpaper)) {
// No such live wallpaper or other failure; fall back to the default
// live wallpaper (since the profile being restored indicated that the
// user had selected a live rather than static one).
- bindWallpaperComponentLocked(null, false, false);
+ bindWallpaperComponentLocked(null, false, false, wallpaper);
}
success = true;
} else {
// If there's a wallpaper name, we use that. If that can't be loaded, then we
// use the default.
- if ("".equals(mName)) {
+ if ("".equals(wallpaper.name)) {
if (DEBUG) Slog.v(TAG, "settingsRestored: name is empty");
success = true;
} else {
if (DEBUG) Slog.v(TAG, "settingsRestored: attempting to restore named resource");
- success = restoreNamedResourceLocked();
+ success = restoreNamedResourceLocked(wallpaper);
}
if (DEBUG) Slog.v(TAG, "settingsRestored: success=" + success);
if (success) {
- bindWallpaperComponentLocked(mNextWallpaperComponent, false, false);
+ bindWallpaperComponentLocked(wallpaper.nextWallpaperComponent, false, false,
+ wallpaper);
}
}
}
if (!success) {
- Slog.e(TAG, "Failed to restore wallpaper: '" + mName + "'");
- mName = "";
- WALLPAPER_FILE.delete();
+ Slog.e(TAG, "Failed to restore wallpaper: '" + wallpaper.name + "'");
+ wallpaper.name = "";
+ getWallpaperDir(0).delete();
}
synchronized (mLock) {
- saveSettingsLocked();
+ saveSettingsLocked(wallpaper);
}
}
- boolean restoreNamedResourceLocked() {
- if (mName.length() > 4 && "res:".equals(mName.substring(0, 4))) {
- String resName = mName.substring(4);
+ boolean restoreNamedResourceLocked(WallpaperData wallpaper) {
+ if (wallpaper.name.length() > 4 && "res:".equals(wallpaper.name.substring(0, 4))) {
+ String resName = wallpaper.name.substring(4);
String pkg = null;
int colon = resName.indexOf(':');
@@ -896,10 +1087,10 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
}
res = r.openRawResource(resId);
- if (WALLPAPER_FILE.exists()) {
- WALLPAPER_FILE.delete();
+ if (wallpaper.wallpaperFile.exists()) {
+ wallpaper.wallpaperFile.delete();
}
- fos = new FileOutputStream(WALLPAPER_FILE);
+ fos = new FileOutputStream(wallpaper.wallpaperFile);
byte[] buffer = new byte[32768];
int amt;
@@ -933,7 +1124,7 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
}
return false;
}
-
+
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
@@ -947,20 +1138,35 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
synchronized (mLock) {
pw.println("Current Wallpaper Service state:");
- pw.print(" mWidth="); pw.print(mWidth);
- pw.print(" mHeight="); pw.println(mHeight);
- pw.print(" mName="); pw.println(mName);
- pw.print(" mWallpaperComponent="); pw.println(mWallpaperComponent);
- if (mWallpaperConnection != null) {
- WallpaperConnection conn = mWallpaperConnection;
- pw.print(" Wallpaper connection ");
- pw.print(conn); pw.println(":");
- pw.print(" mInfo.component="); pw.println(conn.mInfo.getComponent());
- pw.print(" mToken="); pw.println(conn.mToken);
- pw.print(" mService="); pw.println(conn.mService);
- pw.print(" mEngine="); pw.println(conn.mEngine);
- pw.print(" mLastDiedTime=");
- pw.println(mLastDiedTime - SystemClock.uptimeMillis());
+ for (int i = 0; i < mWallpaperMap.size(); i++) {
+ WallpaperData wallpaper = mWallpaperMap.valueAt(i);
+ pw.println(" User " + wallpaper.userId + ":");
+ pw.print(" mWidth=");
+ pw.print(wallpaper.width);
+ pw.print(" mHeight=");
+ pw.println(wallpaper.height);
+ pw.print(" mName=");
+ pw.println(wallpaper.name);
+ pw.print(" mWallpaperComponent=");
+ pw.println(wallpaper.wallpaperComponent);
+ if (wallpaper.connection != null) {
+ WallpaperConnection conn = wallpaper.connection;
+ pw.print(" Wallpaper connection ");
+ pw.print(conn);
+ pw.println(":");
+ if (conn.mInfo != null) {
+ pw.print(" mInfo.component=");
+ pw.println(conn.mInfo.getComponent());
+ }
+ pw.print(" mToken=");
+ pw.println(conn.mToken);
+ pw.print(" mService=");
+ pw.println(conn.mService);
+ pw.print(" mEngine=");
+ pw.println(conn.mEngine);
+ pw.print(" mLastDiedTime=");
+ pw.println(wallpaper.lastDiedTime - SystemClock.uptimeMillis());
+ }
}
}
}
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 5a70dcf..f66b99b 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -49,6 +49,7 @@ import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
+import android.app.WallpaperManager;
import android.app.backup.IBackupManager;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
@@ -1363,24 +1364,6 @@ public final class ActivityManagerService extends ActivityManagerNative
*/
final ArrayList mCancelledThumbnails = new ArrayList();
- /**
- * All of the currently running global content providers. Keys are a
- * string containing the provider name and values are a
- * ContentProviderRecord object containing the data about it. Note
- * that a single provider may be published under multiple names, so
- * there may be multiple entries here for a single one in mProvidersByClass.
- */
- final HashMap<String, ContentProviderRecord> mProvidersByName
- = new HashMap<String, ContentProviderRecord>();
-
- /**
- * All of the currently running global content providers. Keys are a
- * string containing the provider's implementation class and values are a
- * ContentProviderRecord object containing the data about it.
- */
- final HashMap<ComponentName, ContentProviderRecord> mProvidersByClass
- = new HashMap<ComponentName, ContentProviderRecord>();
-
final ProviderMap mProviderMap = new ProviderMap();
/**
@@ -4434,7 +4417,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
- for (ContentProviderRecord provider : mProvidersByClass.values()) {
+ for (ContentProviderRecord provider : mProviderMap.getProvidersByClass(-1).values()) {
if (provider.info.packageName.equals(name)
&& (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
if (!doit) {
@@ -11361,18 +11344,18 @@ public final class ActivityManagerService extends ActivityManagerNative
}
private ServiceLookupResult retrieveServiceLocked(Intent service,
- String resolvedType, int callingPid, int callingUid) {
+ String resolvedType, int callingPid, int callingUid, int userId) {
ServiceRecord r = null;
if (DEBUG_SERVICE)
Slog.v(TAG, "retrieveServiceLocked: " + service + " type=" + resolvedType
- + " origCallingUid=" + callingUid);
+ + " callingUid=" + callingUid);
if (service.getComponent() != null) {
- r = mServiceMap.getServiceByName(service.getComponent(), Binder.getOrigCallingUser());
+ r = mServiceMap.getServiceByName(service.getComponent(), userId);
}
if (r == null) {
Intent.FilterComparison filter = new Intent.FilterComparison(service);
- r = mServiceMap.getServiceByIntent(filter, Binder.getOrigCallingUser());
+ r = mServiceMap.getServiceByIntent(filter, userId);
}
if (r == null) {
try {
@@ -11386,13 +11369,12 @@ public final class ActivityManagerService extends ActivityManagerNative
": not found");
return null;
}
- if (Binder.getOrigCallingUser() > 0) {
- sInfo.applicationInfo = getAppInfoForUser(sInfo.applicationInfo,
- Binder.getOrigCallingUser());
+ if (userId > 0) {
+ sInfo.applicationInfo = getAppInfoForUser(sInfo.applicationInfo, userId);
}
ComponentName name = new ComponentName(
sInfo.applicationInfo.packageName, sInfo.name);
- r = mServiceMap.getServiceByName(name, Binder.getOrigCallingUser());
+ r = mServiceMap.getServiceByName(name, userId);
if (r == null) {
Intent.FilterComparison filter = new Intent.FilterComparison(
service.cloneFilter());
@@ -11956,7 +11938,7 @@ public final class ActivityManagerService extends ActivityManagerNative
ServiceLookupResult res =
retrieveServiceLocked(service, resolvedType,
- callingPid, callingUid);
+ callingPid, callingUid, UserId.getUserId(callingUid));
if (res == null) {
return null;
}
@@ -12206,13 +12188,15 @@ public final class ActivityManagerService extends ActivityManagerNative
public int bindService(IApplicationThread caller, IBinder token,
Intent service, String resolvedType,
- IServiceConnection connection, int flags) {
+ IServiceConnection connection, int flags, int userId) {
enforceNotIsolatedCaller("bindService");
// Refuse possible leaked file descriptors
if (service != null && service.hasFileDescriptors() == true) {
throw new IllegalArgumentException("File descriptors passed in Intent");
}
+ checkValidCaller(Binder.getCallingUid(), userId);
+
synchronized(this) {
if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
+ " type=" + resolvedType + " conn=" + connection.asBinder()
@@ -12262,7 +12246,7 @@ public final class ActivityManagerService extends ActivityManagerNative
ServiceLookupResult res =
retrieveServiceLocked(service, resolvedType,
- Binder.getCallingPid(), Binder.getOrigCallingUid());
+ Binder.getCallingPid(), Binder.getCallingUid(), userId);
if (res == null) {
return 0;
}
@@ -15259,6 +15243,25 @@ public final class ActivityManagerService extends ActivityManagerNative
private int mCurrentUserId;
private SparseIntArray mLoggedInUsers = new SparseIntArray(5);
+ private ArrayList<UserListener> mUserListeners = new ArrayList<UserListener>(3);
+
+ public interface UserListener {
+ public void onUserChanged(int userId);
+
+ public void onUserAdded(int userId);
+
+ public void onUserRemoved(int userId);
+
+ public void onUserLoggedOut(int userId);
+ }
+
+ public void addUserListener(UserListener listener) {
+ synchronized (this) {
+ if (!mUserListeners.contains(listener)) {
+ mUserListeners.add(listener);
+ }
+ }
+ }
public boolean switchUser(int userId) {
final int callingUid = Binder.getCallingUid();
@@ -15269,6 +15272,8 @@ public final class ActivityManagerService extends ActivityManagerNative
if (mCurrentUserId == userId)
return true;
+ ArrayList<UserListener> listeners;
+
synchronized (this) {
// Check if user is already logged in, otherwise check if user exists first before
// adding to the list of logged in users.
@@ -15284,6 +15289,12 @@ public final class ActivityManagerService extends ActivityManagerNative
if (!haveActivities) {
startHomeActivityLocked(userId);
}
+
+ listeners = (ArrayList<UserListener>) mUserListeners.clone();
+ }
+ // Inform the listeners
+ for (UserListener listener : listeners) {
+ listener.onUserChanged(userId);
}
return true;
}
@@ -15303,6 +15314,12 @@ public final class ActivityManagerService extends ActivityManagerNative
return false;
}
+ private void checkValidCaller(int uid, int userId) {
+ if (UserId.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
+
+ throw new SecurityException("Caller uid=" + uid
+ + " is not privileged to communicate with user=" + userId);
+ }
private int applyUserId(int uid, int userId) {
return UserId.getUid(userId, uid);
diff --git a/services/java/com/android/server/am/ProviderMap.java b/services/java/com/android/server/am/ProviderMap.java
index 06353f6..2021e0d 100644
--- a/services/java/com/android/server/am/ProviderMap.java
+++ b/services/java/com/android/server/am/ProviderMap.java
@@ -158,7 +158,7 @@ public class ProviderMap {
}
}
- private HashMap<ComponentName, ContentProviderRecord> getProvidersByClass(int optionalUserId) {
+ HashMap<ComponentName, ContentProviderRecord> getProvidersByClass(int optionalUserId) {
final int userId = optionalUserId >= 0
? optionalUserId : Binder.getOrigCallingUser();
final HashMap<ComponentName, ContentProviderRecord> map = mProvidersByClassPerUser.get(userId);