summaryrefslogtreecommitdiffstats
path: root/services/java/com/android/server/WallpaperManagerService.java
diff options
context:
space:
mode:
Diffstat (limited to 'services/java/com/android/server/WallpaperManagerService.java')
-rw-r--r--services/java/com/android/server/WallpaperManagerService.java222
1 files changed, 143 insertions, 79 deletions
diff --git a/services/java/com/android/server/WallpaperManagerService.java b/services/java/com/android/server/WallpaperManagerService.java
index 8a08277..b027c1f 100644
--- a/services/java/com/android/server/WallpaperManagerService.java
+++ b/services/java/com/android/server/WallpaperManagerService.java
@@ -16,9 +16,11 @@
package com.android.server;
-import static android.os.FileObserver.*;
import static android.os.ParcelFileDescriptor.*;
+import android.app.ActivityManagerNative;
+import android.app.AppGlobals;
+import android.app.IUserSwitchObserver;
import android.app.IWallpaperManager;
import android.app.IWallpaperManagerCallback;
import android.app.PendingIntent;
@@ -31,6 +33,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
+import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
@@ -41,6 +44,7 @@ import android.os.Bundle;
import android.os.Environment;
import android.os.FileUtils;
import android.os.IBinder;
+import android.os.IRemoteCallback;
import android.os.RemoteException;
import android.os.FileObserver;
import android.os.ParcelFileDescriptor;
@@ -48,7 +52,7 @@ import android.os.RemoteCallbackList;
import android.os.SELinux;
import android.os.ServiceManager;
import android.os.SystemClock;
-import android.os.UserId;
+import android.os.UserHandle;
import android.service.wallpaper.IWallpaperConnection;
import android.service.wallpaper.IWallpaperEngine;
import android.service.wallpaper.IWallpaperService;
@@ -77,7 +81,6 @@ 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";
@@ -90,8 +93,6 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
* restarting it vs. just reverting to the static wallpaper.
*/
static final long MIN_WALLPAPER_CRASH_TIME = 10000;
-
- static final File WALLPAPER_BASE_DIR = new File("/data/system/users");
static final String WALLPAPER = "wallpaper";
static final String WALLPAPER_INFO = "wallpaper_info.xml";
@@ -136,7 +137,7 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
mWallpaper.imageWallpaperPending = false;
}
bindWallpaperComponentLocked(mWallpaper.imageWallpaperComponent, true,
- false, mWallpaper);
+ false, mWallpaper, null);
saveSettingsLocked(mWallpaper);
}
}
@@ -146,6 +147,7 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
final Context mContext;
final IWindowManager mIWindowManager;
+ final IPackageManager mIPackageManager;
final MyPackageMonitor mMonitor;
WallpaperData mLastWallpaper;
@@ -213,12 +215,14 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
IWallpaperService mService;
IWallpaperEngine mEngine;
WallpaperData mWallpaper;
+ IRemoteCallback mReply;
public WallpaperConnection(WallpaperInfo info, WallpaperData wallpaper) {
mInfo = info;
mWallpaper = wallpaper;
}
-
+
+ @Override
public void onServiceConnected(ComponentName name, IBinder service) {
synchronized (mLock) {
if (mWallpaper.connection == this) {
@@ -234,6 +238,7 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
}
}
+ @Override
public void onServiceDisconnected(ComponentName name) {
synchronized (mLock) {
mService = null;
@@ -245,16 +250,35 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
> SystemClock.uptimeMillis()
&& mWallpaper.userId == mCurrentUserId) {
Slog.w(TAG, "Reverting to built-in wallpaper!");
- clearWallpaperLocked(true, mWallpaper.userId);
+ clearWallpaperLocked(true, mWallpaper.userId, null);
}
}
}
}
+ @Override
public void attachEngine(IWallpaperEngine engine) {
- mEngine = engine;
+ synchronized (mLock) {
+ mEngine = engine;
+ }
}
+ @Override
+ public void engineShown(IWallpaperEngine engine) {
+ synchronized (mLock) {
+ if (mReply != null) {
+ long ident = Binder.clearCallingIdentity();
+ try {
+ mReply.sendResult(null);
+ } catch (RemoteException e) {
+ Binder.restoreCallingIdentity(ident);
+ }
+ mReply = null;
+ }
+ }
+ }
+
+ @Override
public ParcelFileDescriptor setWallpaper(String name) {
synchronized (mLock) {
if (mWallpaper.connection == this) {
@@ -278,9 +302,10 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
clearWallpaperComponentLocked(wallpaper);
// Do this only for the current user's wallpaper
if (wallpaper.userId == mCurrentUserId
- && !bindWallpaperComponentLocked(comp, false, false, wallpaper)) {
+ && !bindWallpaperComponentLocked(comp, false, false,
+ wallpaper, null)) {
Slog.w(TAG, "Wallpaper no longer available; reverting to default");
- clearWallpaperLocked(false, wallpaper.userId);
+ clearWallpaperLocked(false, wallpaper.userId, null);
}
}
}
@@ -348,7 +373,7 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
if (doit) {
Slog.w(TAG, "Wallpaper uninstalled, removing: "
+ wallpaper.wallpaperComponent);
- clearWallpaperLocked(false, wallpaper.userId);
+ clearWallpaperLocked(false, wallpaper.userId, null);
}
}
}
@@ -368,7 +393,7 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
} catch (NameNotFoundException e) {
Slog.w(TAG, "Wallpaper component gone, removing: "
+ wallpaper.wallpaperComponent);
- clearWallpaperLocked(false, wallpaper.userId);
+ clearWallpaperLocked(false, wallpaper.userId, null);
}
}
if (wallpaper.nextWallpaperComponent != null
@@ -389,14 +414,15 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
mContext = context;
mIWindowManager = IWindowManager.Stub.asInterface(
ServiceManager.getService(Context.WINDOW_SERVICE));
+ mIPackageManager = AppGlobals.getPackageManager();
mMonitor = new MyPackageMonitor();
mMonitor.register(context, null, true);
- WALLPAPER_BASE_DIR.mkdirs();
- loadSettingsLocked(0);
+ getWallpaperDir(UserHandle.USER_OWNER).mkdirs();
+ loadSettingsLocked(UserHandle.USER_OWNER);
}
private static File getWallpaperDir(int userId) {
- return new File(WALLPAPER_BASE_DIR + "/" + userId);
+ return Environment.getUserSystemDirectory(userId);
}
@Override
@@ -410,29 +436,44 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
public void systemReady() {
if (DEBUG) Slog.v(TAG, "systemReady");
- WallpaperData wallpaper = mWallpaperMap.get(0);
- switchWallpaper(wallpaper);
+ WallpaperData wallpaper = mWallpaperMap.get(UserHandle.USER_OWNER);
+ switchWallpaper(wallpaper, null);
wallpaper.wallpaperObserver = new WallpaperObserver(wallpaper);
wallpaper.wallpaperObserver.startWatching();
IntentFilter userFilter = new IntentFilter();
- userFilter.addAction(Intent.ACTION_USER_SWITCHED);
userFilter.addAction(Intent.ACTION_USER_REMOVED);
mContext.registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
- if (Intent.ACTION_USER_SWITCHED.equals(action)) {
- switchUser(intent.getIntExtra(Intent.EXTRA_USERID, 0));
- } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
- removeUser(intent.getIntExtra(Intent.EXTRA_USERID, 0));
+ if (Intent.ACTION_USER_REMOVED.equals(action)) {
+ removeUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0));
}
}
}, userFilter);
+ try {
+ ActivityManagerNative.getDefault().registerUserSwitchObserver(
+ new IUserSwitchObserver.Stub() {
+ @Override
+ public void onUserSwitching(int newUserId, IRemoteCallback reply) {
+ switchUser(newUserId, reply);
+ }
+
+ @Override
+ public void onUserSwitchComplete(int newUserId) throws RemoteException {
+ }
+ });
+ } catch (RemoteException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
}
String getName() {
- return mWallpaperMap.get(0).name;
+ synchronized (mLock) {
+ return mWallpaperMap.get(0).name;
+ }
}
void removeUser(int userId) {
@@ -449,7 +490,7 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
}
}
- void switchUser(int userId) {
+ void switchUser(int userId, IRemoteCallback reply) {
synchronized (mLock) {
mCurrentUserId = userId;
WallpaperData wallpaper = mWallpaperMap.get(userId);
@@ -460,35 +501,35 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
wallpaper.wallpaperObserver = new WallpaperObserver(wallpaper);
wallpaper.wallpaperObserver.startWatching();
}
- switchWallpaper(wallpaper);
+ switchWallpaper(wallpaper, reply);
}
}
- void switchWallpaper(WallpaperData wallpaper) {
+ 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)) {
+ if (bindWallpaperComponentLocked(cname, true, false, wallpaper, reply)) {
return;
}
} catch (RuntimeException e1) {
e = e1;
}
Slog.w(TAG, "Failure starting previous wallpaper", e);
- clearWallpaperLocked(false, wallpaper.userId);
+ clearWallpaperLocked(false, wallpaper.userId, reply);
}
}
public void clearWallpaper() {
if (DEBUG) Slog.v(TAG, "clearWallpaper");
synchronized (mLock) {
- clearWallpaperLocked(false, UserId.getCallingUserId());
+ clearWallpaperLocked(false, UserHandle.getCallingUserId(), null);
}
}
- void clearWallpaperLocked(boolean defaultFailed, int userId) {
+ void clearWallpaperLocked(boolean defaultFailed, int userId, IRemoteCallback reply) {
WallpaperData wallpaper = mWallpaperMap.get(userId);
File f = new File(getWallpaperDir(userId), WALLPAPER);
if (f.exists()) {
@@ -501,7 +542,7 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
if (userId != mCurrentUserId) return;
if (bindWallpaperComponentLocked(defaultFailed
? wallpaper.imageWallpaperComponent
- : null, true, false, wallpaper)) {
+ : null, true, false, wallpaper, reply)) {
return;
}
} catch (IllegalArgumentException e1) {
@@ -516,21 +557,38 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
// wallpaper.
Slog.e(TAG, "Default wallpaper component not found!", e);
clearWallpaperComponentLocked(wallpaper);
+ if (reply != null) {
+ try {
+ reply.sendResult(null);
+ } catch (RemoteException e1) {
+ }
+ }
}
- 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");
+ public boolean hasNamedWallpaper(String name) {
+ synchronized (mLock) {
+ for (int i=0; i<mWallpaperMap.size(); i++) {
+ WallpaperData wd = mWallpaperMap.valueAt(i);
+ if (name.equals(wd.name)) {
+ return true;
+ }
+ }
}
+ return false;
+ }
+ public void setDimensionHints(int width, int height) throws RemoteException {
+ checkPermission(android.Manifest.permission.SET_WALLPAPER_HINTS);
synchronized (mLock) {
+ int userId = UserHandle.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");
+ }
+
if (width != wallpaper.width || height != wallpaper.height) {
wallpaper.width = width;
wallpaper.height = height;
@@ -552,14 +610,14 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
public int getWidthHint() throws RemoteException {
synchronized (mLock) {
- WallpaperData wallpaper = mWallpaperMap.get(UserId.getCallingUserId());
+ WallpaperData wallpaper = mWallpaperMap.get(UserHandle.getCallingUserId());
return wallpaper.width;
}
}
public int getHeightHint() throws RemoteException {
synchronized (mLock) {
- WallpaperData wallpaper = mWallpaperMap.get(UserId.getCallingUserId());
+ WallpaperData wallpaper = mWallpaperMap.get(UserHandle.getCallingUserId());
return wallpaper.height;
}
}
@@ -574,7 +632,7 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
if (callingUid == android.os.Process.SYSTEM_UID) {
wallpaperUserId = mCurrentUserId;
} else {
- wallpaperUserId = UserId.getUserId(callingUid);
+ wallpaperUserId = UserHandle.getUserId(callingUid);
}
WallpaperData wallpaper = mWallpaperMap.get(wallpaperUserId);
try {
@@ -597,7 +655,7 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
}
public WallpaperInfo getWallpaperInfo() {
- int userId = UserId.getCallingUserId();
+ int userId = UserHandle.getCallingUserId();
synchronized (mLock) {
WallpaperData wallpaper = mWallpaperMap.get(userId);
if (wallpaper.connection != null) {
@@ -608,14 +666,14 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
}
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) {
+ if (DEBUG) Slog.v(TAG, "setWallpaper");
+ int userId = UserHandle.getCallingUserId();
+ WallpaperData wallpaper = mWallpaperMap.get(userId);
+ if (wallpaper == null) {
+ throw new IllegalStateException("Wallpaper not yet initialized for user " + userId);
+ }
final long ident = Binder.clearCallingIdentity();
try {
ParcelFileDescriptor pfd = updateWallpaperBitmapLocked(name, wallpaper);
@@ -655,18 +713,18 @@ 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) {
+ if (DEBUG) Slog.v(TAG, "setWallpaperComponent name=" + name);
+ int userId = UserHandle.getCallingUserId();
+ WallpaperData wallpaper = mWallpaperMap.get(userId);
+ if (wallpaper == null) {
+ throw new IllegalStateException("Wallpaper not yet initialized for user " + userId);
+ }
final long ident = Binder.clearCallingIdentity();
try {
wallpaper.imageWallpaperPending = false;
- bindWallpaperComponentLocked(name, false, true, wallpaper);
+ bindWallpaperComponentLocked(name, false, true, wallpaper, null);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -674,7 +732,7 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
}
boolean bindWallpaperComponentLocked(ComponentName componentName, boolean force,
- boolean fromUser, WallpaperData wallpaper) {
+ boolean fromUser, WallpaperData wallpaper, IRemoteCallback reply) {
if (DEBUG) Slog.v(TAG, "bindWallpaperComponentLocked: componentName=" + componentName);
// Has the component changed?
if (!force) {
@@ -710,8 +768,9 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
if (DEBUG) Slog.v(TAG, "Using image wallpaper");
}
}
- ServiceInfo si = mContext.getPackageManager().getServiceInfo(componentName,
- PackageManager.GET_META_DATA | PackageManager.GET_PERMISSIONS);
+ int serviceUserId = wallpaper.userId;
+ ServiceInfo si = mIPackageManager.getServiceInfo(componentName,
+ PackageManager.GET_META_DATA | PackageManager.GET_PERMISSIONS, serviceUserId);
if (!android.Manifest.permission.BIND_WALLPAPER.equals(si.permission)) {
String msg = "Selected service does not require "
+ android.Manifest.permission.BIND_WALLPAPER
@@ -728,8 +787,10 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
Intent intent = new Intent(WallpaperService.SERVICE_INTERFACE);
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);
+ List<ResolveInfo> ris =
+ mIPackageManager.queryIntentServices(intent,
+ intent.resolveTypeIfNeeded(mContext.getContentResolver()),
+ PackageManager.GET_META_DATA, serviceUserId);
for (int i=0; i<ris.size(); i++) {
ServiceInfo rsi = ris.get(i).serviceInfo;
if (rsi.name.equals(si.name) &&
@@ -767,18 +828,13 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
if (DEBUG) Slog.v(TAG, "Binding to:" + componentName);
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(
+ intent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivityAsUser(
mContext, 0,
Intent.createChooser(new Intent(Intent.ACTION_SET_WALLPAPER),
mContext.getText(com.android.internal.R.string.chooser_wallpaper)),
- 0));
+ 0, null, new UserHandle(serviceUserId)));
if (!mContext.bindService(intent, newConn, Context.BIND_AUTO_CREATE, serviceUserId)) {
String msg = "Unable to bind service: "
+ componentName;
@@ -794,6 +850,7 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
wallpaper.wallpaperComponent = componentName;
wallpaper.connection = newConn;
wallpaper.lastDiedTime = SystemClock.uptimeMillis();
+ newConn.mReply = reply;
try {
if (wallpaper.userId == mCurrentUserId) {
if (DEBUG)
@@ -804,8 +861,8 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
}
} catch (RemoteException e) {
}
- } catch (PackageManager.NameNotFoundException e) {
- String msg = "Unknown component " + componentName;
+ } catch (RemoteException e) {
+ String msg = "Remote exception for " + componentName + "\n" + e;
if (fromUser) {
throw new IllegalArgumentException(msg);
}
@@ -817,6 +874,13 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
void detachWallpaperLocked(WallpaperData wallpaper) {
if (wallpaper.connection != null) {
+ if (wallpaper.connection.mReply != null) {
+ try {
+ wallpaper.connection.mReply.sendResult(null);
+ } catch (RemoteException e) {
+ }
+ wallpaper.connection.mReply = null;
+ }
if (wallpaper.connection.mEngine != null) {
try {
wallpaper.connection.mEngine.destroy();
@@ -849,7 +913,7 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
} catch (RemoteException e) {
Slog.w(TAG, "Failed attaching wallpaper; clearing", e);
if (!wallpaper.wallpaperUpdating) {
- bindWallpaperComponentLocked(null, false, false, wallpaper);
+ bindWallpaperComponentLocked(null, false, false, wallpaper, null);
}
}
}
@@ -867,7 +931,7 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
}
wallpaper.callbacks.finishBroadcast();
final Intent intent = new Intent(Intent.ACTION_WALLPAPER_CHANGED);
- mContext.sendBroadcast(intent);
+ mContext.sendBroadcastAsUser(intent, new UserHandle(mCurrentUserId));
}
private void checkPermission(String permission) {
@@ -878,7 +942,7 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
}
private static JournaledFile makeJournaledFile(int userId) {
- final String base = getWallpaperDir(userId) + "/" + WALLPAPER_INFO;
+ final String base = new File(getWallpaperDir(userId), WALLPAPER_INFO).getAbsolutePath();
return new JournaledFile(new File(base), new File(base + ".tmp"));
}
@@ -1032,11 +1096,11 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
if (wallpaper.nextWallpaperComponent != null
&& !wallpaper.nextWallpaperComponent.equals(wallpaper.imageWallpaperComponent)) {
if (!bindWallpaperComponentLocked(wallpaper.nextWallpaperComponent, false, false,
- wallpaper)) {
+ wallpaper, null)) {
// 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, wallpaper);
+ bindWallpaperComponentLocked(null, false, false, wallpaper, null);
}
success = true;
} else {
@@ -1052,7 +1116,7 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
if (DEBUG) Slog.v(TAG, "settingsRestored: success=" + success);
if (success) {
bindWallpaperComponentLocked(wallpaper.nextWallpaperComponent, false, false,
- wallpaper);
+ wallpaper, null);
}
}
}