blob: 4a14cedbf9b39ac564d688d70bf912c8e1ae45f5 [file] [log] [blame]
package android.service.dreams;
import static android.provider.Settings.Secure.SCREENSAVER_COMPONENT;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import com.android.internal.view.IInputMethod;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.provider.Settings;
import android.util.Log;
import android.util.Slog;
import android.view.IWindowManager;
import android.view.WindowManager;
/**
*
* @hide
*
*/
public class DreamManagerService
extends IDreamManager.Stub
implements ServiceConnection
{
private static final boolean DEBUG = true;
private static final String TAG = "DreamManagerService";
final Object mLock = new Object[0];
private Context mContext;
private IWindowManager mIWindowManager;
private ComponentName mCurrentDreamComponent;
private IDreamService mCurrentDream;
private Binder mCurrentDreamToken;
public DreamManagerService(Context context) {
if (DEBUG) Slog.v(TAG, "DreamManagerService startup");
mContext = context;
mIWindowManager = IWindowManager.Stub.asInterface(
ServiceManager.getService(Context.WINDOW_SERVICE));
}
private void checkPermission(String permission) {
if (PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission(permission)) {
throw new SecurityException("Access denied to process: " + Binder.getCallingPid()
+ ", must have permission " + permission);
}
}
// IDreamManager method
public void dream() {
ComponentName name = getDreamComponent();
if (name != null) {
synchronized (mLock) {
final long ident = Binder.clearCallingIdentity();
try {
bindDreamComponentL(name, false);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
}
}
// IDreamManager method
public void setDreamComponent(ComponentName name) {
Settings.Secure.putString(mContext.getContentResolver(), SCREENSAVER_COMPONENT, name.flattenToString());
}
// IDreamManager method
public ComponentName getDreamComponent() {
// TODO(dsandler) don't load this every time, watch the value
String component = Settings.Secure.getString(mContext.getContentResolver(), SCREENSAVER_COMPONENT);
if (component == null) {
component = mContext.getResources().getString(
com.android.internal.R.string.config_defaultDreamComponent);
}
if (component != null) {
return ComponentName.unflattenFromString(component);
} else {
return null;
}
}
// IDreamManager method
public void testDream(ComponentName name) {
if (DEBUG) Slog.v(TAG, "startDream name=" + name
+ " pid=" + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
// checkPermission(android.Manifest.permission.SET_WALLPAPER_COMPONENT);
synchronized (mLock) {
final long ident = Binder.clearCallingIdentity();
try {
bindDreamComponentL(name, true);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
}
// IDreamManager method
public void awaken() {
if (DEBUG) Slog.v(TAG, "awaken()");
synchronized (mLock) {
if (mCurrentDream != null) {
mContext.unbindService(this);
}
}
}
public void bindDreamComponentL(ComponentName componentName, boolean test) {
if (DEBUG) Slog.v(TAG, "bindDreamComponent: componentName=" + componentName
+ " pid=" + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
Intent intent = new Intent(Intent.ACTION_MAIN)
.setComponent(componentName)
.addFlags(
Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
)
.putExtra("android.dreams.TEST", test);
if (!mContext.bindService(intent, this, Context.BIND_AUTO_CREATE)) {
Slog.w(TAG, "unable to bind service: " + componentName);
return;
}
mCurrentDreamComponent = componentName;
mCurrentDreamToken = new Binder();
try {
if (DEBUG) Slog.v(TAG, "Adding window token: " + mCurrentDreamToken
+ " for window type: " + WindowManager.LayoutParams.TYPE_DREAM);
mIWindowManager.addWindowToken(mCurrentDreamToken,
WindowManager.LayoutParams.TYPE_DREAM);
} catch (RemoteException e) {
Slog.w(TAG, "Unable to add window token. Proceed at your own risk.");
}
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
if (DEBUG) Slog.v(TAG, "connected to dream: " + name + " binder=" + service + " thread=" + Thread.currentThread().getId());
mCurrentDream = IDreamService.Stub.asInterface(service);
try {
if (DEBUG) Slog.v(TAG, "attaching with token:" + mCurrentDreamToken);
mCurrentDream.attach(mCurrentDreamToken);
} catch (RemoteException ex) {
Slog.w(TAG, "Unable to send window token to dream:" + ex);
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
if (DEBUG) Slog.v(TAG, "disconnected: " + name + " service: " + mCurrentDream);
mCurrentDream = null;
mCurrentDreamToken = null;
}
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
pw.println("Dreamland:");
pw.print(" component="); pw.println(mCurrentDreamComponent);
pw.print(" token="); pw.println(mCurrentDreamToken);
pw.print(" dream="); pw.println(mCurrentDream);
}
public void systemReady() {
if (DEBUG) Slog.v(TAG, "ready to dream!");
}
}