summaryrefslogtreecommitdiffstats
path: root/core/java
diff options
context:
space:
mode:
authorChristopher Tate <ctate@android.com>2009-09-01 20:32:49 -0700
committerChristopher Tate <ctate@android.com>2009-09-01 20:59:36 -0700
commit5e1ab335e6e8fbfa19c64d53880a22f472010953 (patch)
tree4da429b3833ff29256d23f9e2e7f1b3a41715b65 /core/java
parentc937b5ce4ff2f39fd9c60f718f98550a932b62f0 (diff)
downloadframeworks_base-5e1ab335e6e8fbfa19c64d53880a22f472010953.zip
frameworks_base-5e1ab335e6e8fbfa19c64d53880a22f472010953.tar.gz
frameworks_base-5e1ab335e6e8fbfa19c64d53880a22f472010953.tar.bz2
Expand apps' control over the settings restore process
Applications can now specify two more aspects of the restore process: whether they need to run with their own custom Application subclass rather than being launched in the usual restricted mode during restore, and whether it's okay for the backup manager to kill the app process once restore has completed. The new manifest attributes for these are, respectively, android:restoreNeedsApplication and android:killAfterRestore. If unspecified in the manifest, restoreNeedsApplication is false, and killAfterRestore is true. In order to support kill-after-restore cleanly, this change also adds a new system-process-only interface to the Activity Manager, which will schedule a "commit suicide" event on the target app's main thread looper. The framework backup agents have been given the appropriate new backup attributes as well.
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/app/ActivityManagerNative.java23
-rw-r--r--core/java/android/app/ActivityThread.java13
-rw-r--r--core/java/android/app/ApplicationThreadNative.java17
-rw-r--r--core/java/android/app/IActivityManager.java2
-rw-r--r--core/java/android/app/IApplicationThread.java2
-rw-r--r--core/java/android/content/pm/ApplicationInfo.java27
-rw-r--r--core/java/android/content/pm/PackageParser.java14
7 files changed, 93 insertions, 5 deletions
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 1bb21b9..52d6891 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -1118,6 +1118,15 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
mi.writeToParcel(reply, 0);
return true;
}
+
+ case KILL_APPLICATION_PROCESS_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ String processName = data.readString();
+ int uid = data.readInt();
+ killApplicationProcess(processName, uid);
+ reply.writeNoException();
+ return true;
+ }
}
return super.onTransact(code, data, reply, flags);
@@ -2448,6 +2457,18 @@ class ActivityManagerProxy implements IActivityManager
data.recycle();
reply.recycle();
}
-
+
+ public void killApplicationProcess(String processName, int uid) throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeString(processName);
+ data.writeInt(uid);
+ mRemote.transact(KILL_APPLICATION_PROCESS_TRANSACTION, data, reply, 0);
+ reply.readException();
+ data.recycle();
+ reply.recycle();
+ }
+
private IBinder mRemote;
}
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index b4e57e0..8a26aba 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -1463,6 +1463,10 @@ public final class ActivityThread {
queueOrSendMessage(H.EXIT_APPLICATION, null);
}
+ public final void scheduleSuicide() {
+ queueOrSendMessage(H.SUICIDE, null);
+ }
+
public void requestThumbnail(IBinder token) {
queueOrSendMessage(H.REQUEST_THUMBNAIL, token);
}
@@ -1752,7 +1756,8 @@ public final class ActivityThread {
public static final int RELAUNCH_ACTIVITY = 126;
public static final int PROFILER_CONTROL = 127;
public static final int CREATE_BACKUP_AGENT = 128;
- public static final int DESTROY_BACKUP_AGENT = 129;
+ public static final int DESTROY_BACKUP_AGENT = 129;
+ public static final int SUICIDE = 130;
String codeToString(int code) {
if (localLOGV) {
switch (code) {
@@ -1786,6 +1791,7 @@ public final class ActivityThread {
case PROFILER_CONTROL: return "PROFILER_CONTROL";
case CREATE_BACKUP_AGENT: return "CREATE_BACKUP_AGENT";
case DESTROY_BACKUP_AGENT: return "DESTROY_BACKUP_AGENT";
+ case SUICIDE: return "SUICIDE";
}
}
return "(unknown)";
@@ -1894,6 +1900,11 @@ public final class ActivityThread {
case DESTROY_BACKUP_AGENT:
handleDestroyBackupAgent((CreateBackupAgentData)msg.obj);
break;
+ case SUICIDE:
+ {
+ Process.killProcess(Process.myPid());
+ }
+ break;
}
}
}
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index 15bf9ed..928981d 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -258,6 +258,13 @@ public abstract class ApplicationThreadNative extends Binder
return true;
}
+ case SCHEDULE_SUICIDE_TRANSACTION:
+ {
+ data.enforceInterface(IApplicationThread.descriptor);
+ scheduleSuicide();
+ return true;
+ }
+
case REQUEST_THUMBNAIL_TRANSACTION:
{
data.enforceInterface(IApplicationThread.descriptor);
@@ -652,7 +659,15 @@ class ApplicationThreadProxy implements IApplicationThread {
IBinder.FLAG_ONEWAY);
data.recycle();
}
-
+
+ public final void scheduleSuicide() throws RemoteException {
+ Parcel data = Parcel.obtain();
+ data.writeInterfaceToken(IApplicationThread.descriptor);
+ mRemote.transact(SCHEDULE_SUICIDE_TRANSACTION, data, null,
+ IBinder.FLAG_ONEWAY);
+ data.recycle();
+ }
+
public final void requestThumbnail(IBinder token)
throws RemoteException {
Parcel data = Parcel.obtain();
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 64daea9..98a8481 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -158,6 +158,7 @@ public interface IActivityManager extends IInterface {
throws RemoteException;
public void backupAgentCreated(String packageName, IBinder agent) throws RemoteException;
public void unbindBackupAgent(ApplicationInfo appInfo) throws RemoteException;
+ public void killApplicationProcess(String processName, int uid) throws RemoteException;
public boolean startInstrumentation(ComponentName className, String profileFile,
int flags, Bundle arguments, IInstrumentationWatcher watcher)
@@ -433,4 +434,5 @@ public interface IActivityManager extends IInterface {
int KILL_APPLICATION_WITH_UID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+95;
int CLOSE_SYSTEM_DIALOGS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+96;
int GET_PROCESS_MEMORY_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+97;
+ int KILL_APPLICATION_PROCESS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+98;
}
diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java
index da9a957..8dda898 100644
--- a/core/java/android/app/IApplicationThread.java
+++ b/core/java/android/app/IApplicationThread.java
@@ -83,6 +83,7 @@ public interface IApplicationThread extends IInterface {
IInstrumentationWatcher testWatcher, int debugMode, boolean restrictedBackupMode,
Configuration config, Map<String, IBinder> services) throws RemoteException;
void scheduleExit() throws RemoteException;
+ void scheduleSuicide() throws RemoteException;
void requestThumbnail(IBinder token) throws RemoteException;
void scheduleConfigurationChanged(Configuration config) throws RemoteException;
void updateTimeZone() throws RemoteException;
@@ -133,4 +134,5 @@ public interface IApplicationThread extends IInterface {
int SCHEDULE_CREATE_BACKUP_AGENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+29;
int SCHEDULE_DESTROY_BACKUP_AGENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+30;
int GET_MEMORY_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+31;
+ int SCHEDULE_SUICIDE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+32;
}
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 0a42a6f..8839f95 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -184,7 +184,29 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
* {@hide}
*/
public static final int FLAG_ALLOW_BACKUP = 1<<14;
-
+
+ /**
+ * Value for {@link #flags}: this is false if the application has set
+ * its android:killAfterRestore to false, true otherwise.
+ *
+ * <p>If android:allowBackup is set to false or no android:backupAgent
+ * is specified, this flag will be ignored.
+ *
+ * {@hide}
+ */
+ public static final int FLAG_KILL_AFTER_RESTORE = 1<<15;
+
+ /**
+ * Value for {@link #flags}: this is true if the application has set
+ * its android:restoreNeedsApplication to true, false otherwise.
+ *
+ * <p>If android:allowBackup is set to false or no android:backupAgent
+ * is specified, this flag will be ignored.
+ *
+ * {@hide}
+ */
+ public static final int FLAG_RESTORE_NEEDS_APPLICATION = 1<<16;
+
/**
* Flags associated with the application. Any combination of
* {@link #FLAG_SYSTEM}, {@link #FLAG_DEBUGGABLE}, {@link #FLAG_HAS_CODE},
@@ -193,7 +215,8 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
* {@link #FLAG_ALLOW_CLEAR_USER_DATA}, {@link #FLAG_UPDATED_SYSTEM_APP},
* {@link #FLAG_TEST_ONLY}, {@link #FLAG_SUPPORTS_SMALL_SCREENS},
* {@link #FLAG_SUPPORTS_NORMAL_SCREENS},
- * {@link #FLAG_SUPPORTS_LARGE_SCREENS}, {@link #FLAG_RESIZEABLE_FOR_SCREENS}.
+ * {@link #FLAG_SUPPORTS_LARGE_SCREENS}, {@link #FLAG_RESIZEABLE_FOR_SCREENS},
+ * {@link #FLAG_SUPPORTS_SCREEN_DENSITIES}.
*/
public int flags = 0;
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 4399df4..b4a6fee 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -1296,12 +1296,26 @@ public class PackageParser {
com.android.internal.R.styleable.AndroidManifestApplication_allowBackup, true);
if (allowBackup) {
ai.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
+
+ // backupAgent, killAfterRestore, and restoreNeedsApplication are only relevant
+ // if backup is possible for the given application.
String backupAgent = sa.getNonResourceString(
com.android.internal.R.styleable.AndroidManifestApplication_backupAgent);
if (backupAgent != null) {
ai.backupAgentName = buildClassName(pkgName, backupAgent, outError);
Log.v(TAG, "android:backupAgent = " + ai.backupAgentName
+ " from " + pkgName + "+" + backupAgent);
+
+ if (sa.getBoolean(
+ com.android.internal.R.styleable.AndroidManifestApplication_killAfterRestore,
+ true)) {
+ ai.flags |= ApplicationInfo.FLAG_KILL_AFTER_RESTORE;
+ }
+ if (sa.getBoolean(
+ com.android.internal.R.styleable.AndroidManifestApplication_restoreNeedsApplication,
+ false)) {
+ ai.flags |= ApplicationInfo.FLAG_RESTORE_NEEDS_APPLICATION;
+ }
}
}