donut snapshot

This commit is contained in:
Jean-Baptiste Queru
2009-07-29 14:25:07 -07:00
parent cf4550c319
commit a8675f67e3
326 changed files with 18109 additions and 5040 deletions

View File

@@ -32,6 +32,7 @@ import android.app.ActivityThread;
import android.app.AlertDialog;
import android.app.ApplicationErrorReport;
import android.app.Dialog;
import android.app.IActivityController;
import android.app.IActivityWatcher;
import android.app.IApplicationThread;
import android.app.IInstrumentationWatcher;
@@ -56,6 +57,7 @@ import android.content.pm.IPackageDataObserver;
import android.content.pm.IPackageManager;
import android.content.pm.InstrumentationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PathPermission;
import android.content.pm.ProviderInfo;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
@@ -75,6 +77,7 @@ import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.PowerManager;
import android.os.Process;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
@@ -824,8 +827,11 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
String mOrigDebugApp = null;
boolean mOrigWaitForDebugger = false;
boolean mAlwaysFinishActivities = false;
IActivityWatcher mWatcher = null;
IActivityController mController = null;
final RemoteCallbackList<IActivityWatcher> mWatchers
= new RemoteCallbackList<IActivityWatcher>();
/**
* Callback of last caller to {@link #requestPss}.
*/
@@ -1622,7 +1628,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
/**
* This is a simplified version of topRunningActivityLocked that provides a number of
* optional skip-over modes. It is intended for use with the ActivityWatcher hook only.
* optional skip-over modes. It is intended for use with the ActivityController hook only.
*
* @param token If non-null, any history records matching this token will be skipped.
* @param taskId If non-zero, we'll attempt to skip over records with the same task ID.
@@ -1727,10 +1733,9 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
}
ensurePackageDexOpt(r.intent.getComponent().getPackageName());
app.thread.scheduleLaunchActivity(new Intent(r.intent), r,
System.identityHashCode(r),
r.info, r.icicle, results, newIntents, !andResume,
isNextTransitionForward());
// Update usage stats for launched activity
updateUsageStats(r, true);
} catch (RemoteException e) {
if (r.launchFailed) {
// This is the second time we failed -- finish activity
@@ -2183,6 +2188,8 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
mHandler.sendMessage(msg);
}
reportResumedActivity(next);
next.thumbnail = null;
setFocusedActivityLocked(next);
next.resumeKeyDispatchingLocked();
@@ -2453,6 +2460,26 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
}
}
private void reportResumedActivity(HistoryRecord r) {
//Log.i(TAG, "**** REPORT RESUME: " + r);
final int identHash = System.identityHashCode(r);
updateUsageStats(r, true);
int i = mWatchers.beginBroadcast();
while (i > 0) {
i--;
IActivityWatcher w = mWatchers.getBroadcastItem(i);
if (w != null) {
try {
w.activityResuming(identHash);
} catch (RemoteException e) {
}
}
}
mWatchers.finishBroadcast();
}
/**
* Ensure that the top activity in the stack is resumed.
*
@@ -2641,10 +2668,10 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
EventLog.writeEvent(LOG_AM_RESUME_ACTIVITY,
System.identityHashCode(next),
next.task.taskId, next.shortComponentName);
updateUsageStats(next, true);
next.app.thread.scheduleResumeActivity(next,
isNextTransitionForward());
pauseIfSleepingLocked();
} catch (Exception e) {
@@ -3061,16 +3088,16 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
throw new SecurityException(msg);
}
if (mWatcher != null) {
if (mController != null) {
boolean abort = false;
try {
// The Intent we give to the watcher has the extra data
// stripped off, since it can contain private information.
Intent watchIntent = intent.cloneFilter();
abort = !mWatcher.activityStarting(watchIntent,
abort = !mController.activityStarting(watchIntent,
aInfo.applicationInfo.packageName);
} catch (RemoteException e) {
mWatcher = null;
mController = null;
}
if (abort) {
@@ -3495,8 +3522,6 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
intent = new Intent(intent);
// Collect information about the target of the Intent.
// Must do this before locking, because resolving the intent
// may require launching a process to run its content provider.
ActivityInfo aInfo;
try {
ResolveInfo rInfo =
@@ -3630,17 +3655,24 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
}
}
final int startActivityInPackage(int uid,
public final int startActivityInPackage(int uid,
Intent intent, String resolvedType, IBinder resultTo,
String resultWho, int requestCode, boolean onlyIfNeeded) {
// This is so super not safe, that only the system (or okay root)
// can do it.
final int callingUid = Binder.getCallingUid();
if (callingUid != 0 && callingUid != Process.myUid()) {
throw new SecurityException(
"startActivityInPackage only available to the system");
}
final boolean componentSpecified = intent.getComponent() != null;
// Don't modify the client's object!
intent = new Intent(intent);
// Collect information about the target of the Intent.
// Must do this before locking, because resolving the intent
// may require launching a process to run its content provider.
ActivityInfo aInfo;
try {
ResolveInfo rInfo =
@@ -3967,16 +3999,16 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
}
synchronized(this) {
if (mWatcher != null) {
if (mController != null) {
// Find the first activity that is not finishing.
HistoryRecord next = topRunningActivityLocked(token, 0);
if (next != null) {
// ask watcher if this is allowed
boolean resumeOK = true;
try {
resumeOK = mWatcher.activityResuming(next.packageName);
resumeOK = mController.activityResuming(next.packageName);
} catch (RemoteException e) {
mWatcher = null;
mController = null;
}
if (!resumeOK) {
@@ -4468,9 +4500,9 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
}
}
if (mWatcher != null) {
if (mController != null) {
try {
int res = mWatcher.appNotResponding(app.processName,
int res = mController.appNotResponding(app.processName,
app.pid, info.toString());
if (res != 0) {
if (res < 0) {
@@ -4486,7 +4518,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
}
}
} catch (RemoteException e) {
mWatcher = null;
mController = null;
}
}
@@ -6611,7 +6643,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
}
/**
* TODO: Add mWatcher hook
* TODO: Add mController hook
*/
public void moveTaskToFront(int task) {
enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
@@ -6756,7 +6788,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
// If we have a watcher, preflight the move before committing to it. First check
// for *other* available tasks, but if none are available, then try again allowing the
// current task to be selected.
if (mWatcher != null) {
if (mController != null) {
HistoryRecord next = topRunningActivityLocked(null, task);
if (next == null) {
next = topRunningActivityLocked(null, 0);
@@ -6765,9 +6797,9 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
// ask watcher if this is allowed
boolean moveOK = true;
try {
moveOK = mWatcher.activityResuming(next.packageName);
moveOK = mController.activityResuming(next.packageName);
} catch (RemoteException e) {
mWatcher = null;
mController = null;
}
if (!moveOK) {
return false;
@@ -7072,6 +7104,27 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
== PackageManager.PERMISSION_GRANTED) {
return null;
}
PathPermission[] pps = cpi.pathPermissions;
if (pps != null) {
int i = pps.length;
while (i > 0) {
i--;
PathPermission pp = pps[i];
if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
cpi.exported ? -1 : cpi.applicationInfo.uid)
== PackageManager.PERMISSION_GRANTED
&& mode == ParcelFileDescriptor.MODE_READ_ONLY || mode == -1) {
return null;
}
if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
cpi.exported ? -1 : cpi.applicationInfo.uid)
== PackageManager.PERMISSION_GRANTED) {
return null;
}
}
}
String msg = "Permission Denial: opening provider " + cpi.name
+ " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
+ ", uid=" + callingUid + ") requires "
@@ -7657,14 +7710,22 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
}
}
public void setActivityWatcher(IActivityWatcher watcher) {
public void setActivityController(IActivityController controller) {
enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
"setActivityWatcher()");
"setActivityController()");
synchronized (this) {
mWatcher = watcher;
mController = controller;
}
}
public void registerActivityWatcher(IActivityWatcher watcher) {
mWatchers.register(watcher);
}
public void unregisterActivityWatcher(IActivityWatcher watcher) {
mWatchers.unregister(watcher);
}
public final void enterSafeMode() {
synchronized(this) {
// It only makes sense to do this before the system is ready
@@ -8225,11 +8286,11 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
//Process.sendSignal(MY_PID, Process.SIGNAL_QUIT);
}
if (mWatcher != null) {
if (mController != null) {
try {
String name = r != null ? r.processName : null;
int pid = r != null ? r.pid : Binder.getCallingPid();
if (!mWatcher.appCrashed(name, pid,
if (!mController.appCrashed(name, pid,
shortMsg, longMsg, crashData)) {
Log.w(TAG, "Force-killing crashed app " + name
+ " at watcher's request");
@@ -8237,7 +8298,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
return 0;
}
} catch (RemoteException e) {
mWatcher = null;
mController = null;
}
}
@@ -8663,7 +8724,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
+ " mDebugTransient=" + mDebugTransient
+ " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
+ " mWatcher=" + mWatcher);
+ " mController=" + mController);
}
}
@@ -10810,6 +10871,29 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
}
/*
* Prevent non-system code (defined here to be non-persistent
* processes) from sending protected broadcasts.
*/
if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
|| callingUid == Process.SHELL_UID || callingUid == 0) {
// Always okay.
} else if (callerApp == null || !callerApp.persistent) {
try {
if (ActivityThread.getPackageManager().isProtectedBroadcast(
intent.getAction())) {
String msg = "Permission Denial: not allowed to send broadcast "
+ intent.getAction() + " from pid="
+ callingPid + ", uid=" + callingUid;
Log.w(TAG, msg);
throw new SecurityException(msg);
}
} catch (RemoteException e) {
Log.w(TAG, "Remote exception", e);
return BROADCAST_SUCCESS;
}
}
// Add to the sticky list if requested.
if (sticky) {
if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
@@ -11755,10 +11839,12 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
config.reqTouchScreen = mConfiguration.touchscreen;
config.reqKeyboardType = mConfiguration.keyboard;
config.reqNavigation = mConfiguration.navigation;
if (mConfiguration.navigation != Configuration.NAVIGATION_NONAV) {
if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
|| mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
}
if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED) {
if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
&& mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
}
}