Loading cmds/am/src/com/android/commands/am/Am.java +51 −13 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import android.view.IWindowManager; import java.io.File; import java.io.FileNotFoundException; import java.io.PrintStream; import java.net.URISyntaxException; import java.util.Iterator; import java.util.Set; Loading @@ -47,6 +48,7 @@ public class Am { private String mCurArgData; private boolean mDebugOption = false; private boolean mWaitOption = false; // These are magic strings understood by the Eclipse plugin. private static final String FATAL_ERROR_CODE = "Error type 1"; Loading Loading @@ -106,6 +108,7 @@ public class Am { boolean hasIntentInfo = false; mDebugOption = false; mWaitOption = false; Uri data = null; String type = null; Loading Loading @@ -153,6 +156,8 @@ public class Am { intent.setFlags(Integer.decode(str).intValue()); } else if (opt.equals("-D")) { mDebugOption = true; } else if (opt.equals("-W")) { mWaitOption = true; } else { System.err.println("Error: Unknown option: " + opt); showUsage(); Loading Loading @@ -199,58 +204,90 @@ public class Am { System.out.println("Starting: " + intent); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // XXX should do something to determine the MIME type. int res = mAm.startActivity(null, intent, intent.getType(), IActivityManager.WaitResult result = null; int res; if (mWaitOption) { result = mAm.startActivityAndWait(null, intent, intent.getType(), null, 0, null, null, 0, false, mDebugOption); res = result.result; } else { res = mAm.startActivity(null, intent, intent.getType(), null, 0, null, null, 0, false, mDebugOption); } PrintStream out = mWaitOption ? System.out : System.err; boolean launched = false; switch (res) { case IActivityManager.START_SUCCESS: launched = true; break; case IActivityManager.START_SWITCHES_CANCELED: System.err.println( launched = true; out.println( "Warning: Activity not started because the " + " current activity is being kept for the user."); break; case IActivityManager.START_DELIVERED_TO_TOP: System.err.println( launched = true; out.println( "Warning: Activity not started, intent has " + "been delivered to currently running " + "top-most instance."); break; case IActivityManager.START_RETURN_INTENT_TO_CALLER: System.err.println( launched = true; out.println( "Warning: Activity not started because intent " + "should be handled by the caller"); break; case IActivityManager.START_TASK_TO_FRONT: System.err.println( launched = true; out.println( "Warning: Activity not started, its current " + "task has been brought to the front"); break; case IActivityManager.START_INTENT_NOT_RESOLVED: System.err.println( out.println( "Error: Activity not started, unable to " + "resolve " + intent.toString()); break; case IActivityManager.START_CLASS_NOT_FOUND: System.err.println(NO_CLASS_ERROR_CODE); System.err.println("Error: Activity class " + out.println(NO_CLASS_ERROR_CODE); out.println("Error: Activity class " + intent.getComponent().toShortString() + " does not exist."); break; case IActivityManager.START_FORWARD_AND_REQUEST_CONFLICT: System.err.println( out.println( "Error: Activity not started, you requested to " + "both forward and receive its result"); break; case IActivityManager.START_PERMISSION_DENIED: System.err.println( out.println( "Error: Activity not started, you do not " + "have permission to access it."); break; default: System.err.println( out.println( "Error: Activity not started, unknown error code " + res); break; } if (mWaitOption && launched) { if (result == null) { result = new IActivityManager.WaitResult(); result.who = intent.getComponent(); } System.out.println("Status: " + (result.timeout ? "timeout" : "ok")); if (result.who != null) { System.out.println("Activity: " + result.who.flattenToShortString()); } if (result.thisTime >= 0) { System.out.println("ThisTime: " + result.thisTime); } if (result.totalTime >= 0) { System.out.println("TotalTime: " + result.totalTime); } System.out.println("Complete"); } } private void sendBroadcast() throws Exception { Loading Loading @@ -504,8 +541,9 @@ public class Am { System.err.println( "usage: am [subcommand] [options]\n" + "\n" + " start an Activity: am start [-D] <INTENT>\n" + " start an Activity: am start [-D] [-W] <INTENT>\n" + " -D: enable debugging\n" + " -W: wait for launch to complete\n" + "\n" + " start a Service: am startservice <INTENT>\n" + "\n" + Loading core/java/android/app/ActivityManagerNative.java +47 −0 Original line number Diff line number Diff line Loading @@ -146,6 +146,28 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM return true; } case START_ACTIVITY_AND_WAIT_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder b = data.readStrongBinder(); IApplicationThread app = ApplicationThreadNative.asInterface(b); Intent intent = Intent.CREATOR.createFromParcel(data); String resolvedType = data.readString(); Uri[] grantedUriPermissions = data.createTypedArray(Uri.CREATOR); int grantedMode = data.readInt(); IBinder resultTo = data.readStrongBinder(); String resultWho = data.readString(); int requestCode = data.readInt(); boolean onlyIfNeeded = data.readInt() != 0; boolean debug = data.readInt() != 0; WaitResult result = startActivityAndWait(app, intent, resolvedType, grantedUriPermissions, grantedMode, resultTo, resultWho, requestCode, onlyIfNeeded, debug); reply.writeNoException(); result.writeToParcel(reply, 0); return true; } case START_ACTIVITY_INTENT_SENDER_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); Loading Loading @@ -1238,6 +1260,31 @@ class ActivityManagerProxy implements IActivityManager data.recycle(); return result; } public WaitResult startActivityAndWait(IApplicationThread caller, Intent intent, String resolvedType, Uri[] grantedUriPermissions, int grantedMode, IBinder resultTo, String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeStrongBinder(caller != null ? caller.asBinder() : null); intent.writeToParcel(data, 0); data.writeString(resolvedType); data.writeTypedArray(grantedUriPermissions, 0); data.writeInt(grantedMode); data.writeStrongBinder(resultTo); data.writeString(resultWho); data.writeInt(requestCode); data.writeInt(onlyIfNeeded ? 1 : 0); data.writeInt(debug ? 1 : 0); mRemote.transact(START_ACTIVITY_AND_WAIT_TRANSACTION, data, reply, 0); reply.readException(); WaitResult result = WaitResult.CREATOR.createFromParcel(reply); reply.recycle(); data.recycle(); return result; } public int startActivityIntentSender(IApplicationThread caller, IntentSender intent, Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, Loading core/java/android/app/IActivityManager.java +48 −0 Original line number Diff line number Diff line Loading @@ -84,6 +84,10 @@ public interface IActivityManager extends IInterface { Intent intent, String resolvedType, Uri[] grantedUriPermissions, int grantedMode, IBinder resultTo, String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug) throws RemoteException; public WaitResult startActivityAndWait(IApplicationThread caller, Intent intent, String resolvedType, Uri[] grantedUriPermissions, int grantedMode, IBinder resultTo, String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug) throws RemoteException; public int startActivityIntentSender(IApplicationThread caller, IntentSender intent, Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, Loading Loading @@ -348,6 +352,49 @@ public interface IActivityManager extends IInterface { } }; /** Information returned after waiting for an activity start. */ public static class WaitResult implements Parcelable { public int result; public boolean timeout; public ComponentName who; public long thisTime; public long totalTime; public WaitResult() { } public int describeContents() { return 0; } public void writeToParcel(Parcel dest, int flags) { dest.writeInt(result); dest.writeInt(timeout ? 1 : 0); ComponentName.writeToParcel(who, dest); dest.writeLong(thisTime); dest.writeLong(totalTime); } public static final Parcelable.Creator<WaitResult> CREATOR = new Parcelable.Creator<WaitResult>() { public WaitResult createFromParcel(Parcel source) { return new WaitResult(source); } public WaitResult[] newArray(int size) { return new WaitResult[size]; } }; private WaitResult(Parcel source) { result = source.readInt(); timeout = source.readInt() != 0; who = ComponentName.readFromParcel(source); thisTime = source.readLong(); totalTime = source.readLong(); } }; String descriptor = "android.app.IActivityManager"; // Please keep these transaction codes the same -- they are also Loading Loading @@ -453,4 +500,5 @@ public interface IActivityManager extends IInterface { int HANDLE_APPLICATION_WTF_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+101; int KILL_BACKGROUND_PROCESSES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+102; int IS_USER_A_MONKEY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+103; int START_ACTIVITY_AND_WAIT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+104; } services/java/com/android/server/am/ActivityManagerService.java +102 −4 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import android.app.AlertDialog; import android.app.ApplicationErrorReport; import android.app.Dialog; import android.app.IActivityController; import android.app.IActivityManager; import android.app.IActivityWatcher; import android.app.IApplicationThread; import android.app.IInstrumentationWatcher; Loading Loading @@ -387,6 +388,18 @@ public final class ActivityManagerService extends ActivityManagerNative implemen final ArrayList<PendingActivityLaunch> mPendingActivityLaunches = new ArrayList<PendingActivityLaunch>(); /** * List of people waiting to find out about the next launched activity. */ final ArrayList<IActivityManager.WaitResult> mWaitingActivityLaunched = new ArrayList<IActivityManager.WaitResult>(); /** * List of people waiting to find out about the next visible activity. */ final ArrayList<IActivityManager.WaitResult> mWaitingActivityVisible = new ArrayList<IActivityManager.WaitResult>(); /** * List of all active broadcasts that are to be executed immediately * (without waiting for another broadcast to finish). Currently this only Loading Loading @@ -3559,11 +3572,38 @@ public final class ActivityManagerService extends ActivityManagerNative implemen return START_SUCCESS; } public final int startActivity(IApplicationThread caller, void reportActivityLaunchedLocked(boolean timeout, HistoryRecord r, long thisTime, long totalTime) { for (int i=mWaitingActivityLaunched.size()-1; i>=0; i--) { WaitResult w = mWaitingActivityLaunched.get(i); w.timeout = timeout; if (r != null) { w.who = new ComponentName(r.info.packageName, r.info.name); } w.thisTime = thisTime; w.totalTime = totalTime; } notify(); } void reportActivityVisibleLocked(HistoryRecord r) { for (int i=mWaitingActivityVisible.size()-1; i>=0; i--) { WaitResult w = mWaitingActivityVisible.get(i); w.timeout = false; if (r != null) { w.who = new ComponentName(r.info.packageName, r.info.name); } w.totalTime = SystemClock.uptimeMillis() - w.thisTime; w.thisTime = w.totalTime; } notify(); } private final int startActivityMayWait(IApplicationThread caller, Intent intent, String resolvedType, Uri[] grantedUriPermissions, int grantedMode, IBinder resultTo, String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug) { boolean debug, WaitResult outResult) { // Refuse possible leaked file descriptors if (intent != null && intent.hasFileDescriptors()) { throw new IllegalArgumentException("File descriptors passed in Intent"); Loading Loading @@ -3618,10 +3658,61 @@ public final class ActivityManagerService extends ActivityManagerNative implemen resultTo, resultWho, requestCode, callingPid, callingUid, onlyIfNeeded, componentSpecified); Binder.restoreCallingIdentity(origId); if (outResult != null) { outResult.result = res; if (res == IActivityManager.START_SUCCESS) { mWaitingActivityLaunched.add(outResult); do { try { wait(); } catch (InterruptedException e) { } } while (!outResult.timeout && outResult.who == null); } else if (res == IActivityManager.START_TASK_TO_FRONT) { HistoryRecord r = this.topRunningActivityLocked(null); if (r.nowVisible) { outResult.timeout = false; outResult.who = new ComponentName(r.info.packageName, r.info.name); outResult.totalTime = 0; outResult.thisTime = 0; } else { outResult.thisTime = SystemClock.uptimeMillis(); mWaitingActivityVisible.add(outResult); do { try { wait(); } catch (InterruptedException e) { } } while (!outResult.timeout && outResult.who == null); } } } return res; } } public final int startActivity(IApplicationThread caller, Intent intent, String resolvedType, Uri[] grantedUriPermissions, int grantedMode, IBinder resultTo, String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug) { return startActivityMayWait(caller, intent, resolvedType, grantedUriPermissions, grantedMode, resultTo, resultWho, requestCode, onlyIfNeeded, debug, null); } public final WaitResult startActivityAndWait(IApplicationThread caller, Intent intent, String resolvedType, Uri[] grantedUriPermissions, int grantedMode, IBinder resultTo, String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug) { WaitResult res = new WaitResult(); startActivityMayWait(caller, intent, resolvedType, grantedUriPermissions, grantedMode, resultTo, resultWho, requestCode, onlyIfNeeded, debug, res); return res; } public int startActivityIntentSender(IApplicationThread caller, IntentSender intent, Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, Loading Loading @@ -5505,6 +5596,10 @@ public final class ActivityManagerService extends ActivityManagerNative implemen if (index >= 0) { HistoryRecord r = (HistoryRecord)mHistory.get(index); if (fromTimeout) { reportActivityLaunchedLocked(fromTimeout, r, -1, -1); } // This is a hack to semi-deal with a race condition // in the client where it can be constructed with a // newer configuration from when we asked it to launch. Loading Loading @@ -5539,6 +5634,9 @@ public final class ActivityManagerService extends ActivityManagerNative implemen mBooted = true; enableScreen = true; } } else if (fromTimeout) { reportActivityLaunchedLocked(fromTimeout, null, -1, -1); } // Atomically retrieve all of the other things to do. Loading services/java/com/android/server/am/HistoryRecord.java +2 −0 Original line number Diff line number Diff line Loading @@ -387,12 +387,14 @@ class HistoryRecord extends IApplicationToken.Stub { sb.append(" ms)"); Log.i(ActivityManagerService.TAG, sb.toString()); } service.reportActivityLaunchedLocked(false, this, thisTime, totalTime); if (totalTime > 0) { service.mUsageStatsService.noteLaunchTime(realActivity, (int)totalTime); } startTime = 0; service.mInitialStartTime = 0; } service.reportActivityVisibleLocked(this); if (ActivityManagerService.DEBUG_SWITCH) Log.v( ActivityManagerService.TAG, "windowsVisible(): " + this); if (!nowVisible) { Loading Loading
cmds/am/src/com/android/commands/am/Am.java +51 −13 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import android.view.IWindowManager; import java.io.File; import java.io.FileNotFoundException; import java.io.PrintStream; import java.net.URISyntaxException; import java.util.Iterator; import java.util.Set; Loading @@ -47,6 +48,7 @@ public class Am { private String mCurArgData; private boolean mDebugOption = false; private boolean mWaitOption = false; // These are magic strings understood by the Eclipse plugin. private static final String FATAL_ERROR_CODE = "Error type 1"; Loading Loading @@ -106,6 +108,7 @@ public class Am { boolean hasIntentInfo = false; mDebugOption = false; mWaitOption = false; Uri data = null; String type = null; Loading Loading @@ -153,6 +156,8 @@ public class Am { intent.setFlags(Integer.decode(str).intValue()); } else if (opt.equals("-D")) { mDebugOption = true; } else if (opt.equals("-W")) { mWaitOption = true; } else { System.err.println("Error: Unknown option: " + opt); showUsage(); Loading Loading @@ -199,58 +204,90 @@ public class Am { System.out.println("Starting: " + intent); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // XXX should do something to determine the MIME type. int res = mAm.startActivity(null, intent, intent.getType(), IActivityManager.WaitResult result = null; int res; if (mWaitOption) { result = mAm.startActivityAndWait(null, intent, intent.getType(), null, 0, null, null, 0, false, mDebugOption); res = result.result; } else { res = mAm.startActivity(null, intent, intent.getType(), null, 0, null, null, 0, false, mDebugOption); } PrintStream out = mWaitOption ? System.out : System.err; boolean launched = false; switch (res) { case IActivityManager.START_SUCCESS: launched = true; break; case IActivityManager.START_SWITCHES_CANCELED: System.err.println( launched = true; out.println( "Warning: Activity not started because the " + " current activity is being kept for the user."); break; case IActivityManager.START_DELIVERED_TO_TOP: System.err.println( launched = true; out.println( "Warning: Activity not started, intent has " + "been delivered to currently running " + "top-most instance."); break; case IActivityManager.START_RETURN_INTENT_TO_CALLER: System.err.println( launched = true; out.println( "Warning: Activity not started because intent " + "should be handled by the caller"); break; case IActivityManager.START_TASK_TO_FRONT: System.err.println( launched = true; out.println( "Warning: Activity not started, its current " + "task has been brought to the front"); break; case IActivityManager.START_INTENT_NOT_RESOLVED: System.err.println( out.println( "Error: Activity not started, unable to " + "resolve " + intent.toString()); break; case IActivityManager.START_CLASS_NOT_FOUND: System.err.println(NO_CLASS_ERROR_CODE); System.err.println("Error: Activity class " + out.println(NO_CLASS_ERROR_CODE); out.println("Error: Activity class " + intent.getComponent().toShortString() + " does not exist."); break; case IActivityManager.START_FORWARD_AND_REQUEST_CONFLICT: System.err.println( out.println( "Error: Activity not started, you requested to " + "both forward and receive its result"); break; case IActivityManager.START_PERMISSION_DENIED: System.err.println( out.println( "Error: Activity not started, you do not " + "have permission to access it."); break; default: System.err.println( out.println( "Error: Activity not started, unknown error code " + res); break; } if (mWaitOption && launched) { if (result == null) { result = new IActivityManager.WaitResult(); result.who = intent.getComponent(); } System.out.println("Status: " + (result.timeout ? "timeout" : "ok")); if (result.who != null) { System.out.println("Activity: " + result.who.flattenToShortString()); } if (result.thisTime >= 0) { System.out.println("ThisTime: " + result.thisTime); } if (result.totalTime >= 0) { System.out.println("TotalTime: " + result.totalTime); } System.out.println("Complete"); } } private void sendBroadcast() throws Exception { Loading Loading @@ -504,8 +541,9 @@ public class Am { System.err.println( "usage: am [subcommand] [options]\n" + "\n" + " start an Activity: am start [-D] <INTENT>\n" + " start an Activity: am start [-D] [-W] <INTENT>\n" + " -D: enable debugging\n" + " -W: wait for launch to complete\n" + "\n" + " start a Service: am startservice <INTENT>\n" + "\n" + Loading
core/java/android/app/ActivityManagerNative.java +47 −0 Original line number Diff line number Diff line Loading @@ -146,6 +146,28 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM return true; } case START_ACTIVITY_AND_WAIT_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder b = data.readStrongBinder(); IApplicationThread app = ApplicationThreadNative.asInterface(b); Intent intent = Intent.CREATOR.createFromParcel(data); String resolvedType = data.readString(); Uri[] grantedUriPermissions = data.createTypedArray(Uri.CREATOR); int grantedMode = data.readInt(); IBinder resultTo = data.readStrongBinder(); String resultWho = data.readString(); int requestCode = data.readInt(); boolean onlyIfNeeded = data.readInt() != 0; boolean debug = data.readInt() != 0; WaitResult result = startActivityAndWait(app, intent, resolvedType, grantedUriPermissions, grantedMode, resultTo, resultWho, requestCode, onlyIfNeeded, debug); reply.writeNoException(); result.writeToParcel(reply, 0); return true; } case START_ACTIVITY_INTENT_SENDER_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); Loading Loading @@ -1238,6 +1260,31 @@ class ActivityManagerProxy implements IActivityManager data.recycle(); return result; } public WaitResult startActivityAndWait(IApplicationThread caller, Intent intent, String resolvedType, Uri[] grantedUriPermissions, int grantedMode, IBinder resultTo, String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeStrongBinder(caller != null ? caller.asBinder() : null); intent.writeToParcel(data, 0); data.writeString(resolvedType); data.writeTypedArray(grantedUriPermissions, 0); data.writeInt(grantedMode); data.writeStrongBinder(resultTo); data.writeString(resultWho); data.writeInt(requestCode); data.writeInt(onlyIfNeeded ? 1 : 0); data.writeInt(debug ? 1 : 0); mRemote.transact(START_ACTIVITY_AND_WAIT_TRANSACTION, data, reply, 0); reply.readException(); WaitResult result = WaitResult.CREATOR.createFromParcel(reply); reply.recycle(); data.recycle(); return result; } public int startActivityIntentSender(IApplicationThread caller, IntentSender intent, Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, Loading
core/java/android/app/IActivityManager.java +48 −0 Original line number Diff line number Diff line Loading @@ -84,6 +84,10 @@ public interface IActivityManager extends IInterface { Intent intent, String resolvedType, Uri[] grantedUriPermissions, int grantedMode, IBinder resultTo, String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug) throws RemoteException; public WaitResult startActivityAndWait(IApplicationThread caller, Intent intent, String resolvedType, Uri[] grantedUriPermissions, int grantedMode, IBinder resultTo, String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug) throws RemoteException; public int startActivityIntentSender(IApplicationThread caller, IntentSender intent, Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, Loading Loading @@ -348,6 +352,49 @@ public interface IActivityManager extends IInterface { } }; /** Information returned after waiting for an activity start. */ public static class WaitResult implements Parcelable { public int result; public boolean timeout; public ComponentName who; public long thisTime; public long totalTime; public WaitResult() { } public int describeContents() { return 0; } public void writeToParcel(Parcel dest, int flags) { dest.writeInt(result); dest.writeInt(timeout ? 1 : 0); ComponentName.writeToParcel(who, dest); dest.writeLong(thisTime); dest.writeLong(totalTime); } public static final Parcelable.Creator<WaitResult> CREATOR = new Parcelable.Creator<WaitResult>() { public WaitResult createFromParcel(Parcel source) { return new WaitResult(source); } public WaitResult[] newArray(int size) { return new WaitResult[size]; } }; private WaitResult(Parcel source) { result = source.readInt(); timeout = source.readInt() != 0; who = ComponentName.readFromParcel(source); thisTime = source.readLong(); totalTime = source.readLong(); } }; String descriptor = "android.app.IActivityManager"; // Please keep these transaction codes the same -- they are also Loading Loading @@ -453,4 +500,5 @@ public interface IActivityManager extends IInterface { int HANDLE_APPLICATION_WTF_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+101; int KILL_BACKGROUND_PROCESSES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+102; int IS_USER_A_MONKEY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+103; int START_ACTIVITY_AND_WAIT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+104; }
services/java/com/android/server/am/ActivityManagerService.java +102 −4 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import android.app.AlertDialog; import android.app.ApplicationErrorReport; import android.app.Dialog; import android.app.IActivityController; import android.app.IActivityManager; import android.app.IActivityWatcher; import android.app.IApplicationThread; import android.app.IInstrumentationWatcher; Loading Loading @@ -387,6 +388,18 @@ public final class ActivityManagerService extends ActivityManagerNative implemen final ArrayList<PendingActivityLaunch> mPendingActivityLaunches = new ArrayList<PendingActivityLaunch>(); /** * List of people waiting to find out about the next launched activity. */ final ArrayList<IActivityManager.WaitResult> mWaitingActivityLaunched = new ArrayList<IActivityManager.WaitResult>(); /** * List of people waiting to find out about the next visible activity. */ final ArrayList<IActivityManager.WaitResult> mWaitingActivityVisible = new ArrayList<IActivityManager.WaitResult>(); /** * List of all active broadcasts that are to be executed immediately * (without waiting for another broadcast to finish). Currently this only Loading Loading @@ -3559,11 +3572,38 @@ public final class ActivityManagerService extends ActivityManagerNative implemen return START_SUCCESS; } public final int startActivity(IApplicationThread caller, void reportActivityLaunchedLocked(boolean timeout, HistoryRecord r, long thisTime, long totalTime) { for (int i=mWaitingActivityLaunched.size()-1; i>=0; i--) { WaitResult w = mWaitingActivityLaunched.get(i); w.timeout = timeout; if (r != null) { w.who = new ComponentName(r.info.packageName, r.info.name); } w.thisTime = thisTime; w.totalTime = totalTime; } notify(); } void reportActivityVisibleLocked(HistoryRecord r) { for (int i=mWaitingActivityVisible.size()-1; i>=0; i--) { WaitResult w = mWaitingActivityVisible.get(i); w.timeout = false; if (r != null) { w.who = new ComponentName(r.info.packageName, r.info.name); } w.totalTime = SystemClock.uptimeMillis() - w.thisTime; w.thisTime = w.totalTime; } notify(); } private final int startActivityMayWait(IApplicationThread caller, Intent intent, String resolvedType, Uri[] grantedUriPermissions, int grantedMode, IBinder resultTo, String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug) { boolean debug, WaitResult outResult) { // Refuse possible leaked file descriptors if (intent != null && intent.hasFileDescriptors()) { throw new IllegalArgumentException("File descriptors passed in Intent"); Loading Loading @@ -3618,10 +3658,61 @@ public final class ActivityManagerService extends ActivityManagerNative implemen resultTo, resultWho, requestCode, callingPid, callingUid, onlyIfNeeded, componentSpecified); Binder.restoreCallingIdentity(origId); if (outResult != null) { outResult.result = res; if (res == IActivityManager.START_SUCCESS) { mWaitingActivityLaunched.add(outResult); do { try { wait(); } catch (InterruptedException e) { } } while (!outResult.timeout && outResult.who == null); } else if (res == IActivityManager.START_TASK_TO_FRONT) { HistoryRecord r = this.topRunningActivityLocked(null); if (r.nowVisible) { outResult.timeout = false; outResult.who = new ComponentName(r.info.packageName, r.info.name); outResult.totalTime = 0; outResult.thisTime = 0; } else { outResult.thisTime = SystemClock.uptimeMillis(); mWaitingActivityVisible.add(outResult); do { try { wait(); } catch (InterruptedException e) { } } while (!outResult.timeout && outResult.who == null); } } } return res; } } public final int startActivity(IApplicationThread caller, Intent intent, String resolvedType, Uri[] grantedUriPermissions, int grantedMode, IBinder resultTo, String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug) { return startActivityMayWait(caller, intent, resolvedType, grantedUriPermissions, grantedMode, resultTo, resultWho, requestCode, onlyIfNeeded, debug, null); } public final WaitResult startActivityAndWait(IApplicationThread caller, Intent intent, String resolvedType, Uri[] grantedUriPermissions, int grantedMode, IBinder resultTo, String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug) { WaitResult res = new WaitResult(); startActivityMayWait(caller, intent, resolvedType, grantedUriPermissions, grantedMode, resultTo, resultWho, requestCode, onlyIfNeeded, debug, res); return res; } public int startActivityIntentSender(IApplicationThread caller, IntentSender intent, Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, Loading Loading @@ -5505,6 +5596,10 @@ public final class ActivityManagerService extends ActivityManagerNative implemen if (index >= 0) { HistoryRecord r = (HistoryRecord)mHistory.get(index); if (fromTimeout) { reportActivityLaunchedLocked(fromTimeout, r, -1, -1); } // This is a hack to semi-deal with a race condition // in the client where it can be constructed with a // newer configuration from when we asked it to launch. Loading Loading @@ -5539,6 +5634,9 @@ public final class ActivityManagerService extends ActivityManagerNative implemen mBooted = true; enableScreen = true; } } else if (fromTimeout) { reportActivityLaunchedLocked(fromTimeout, null, -1, -1); } // Atomically retrieve all of the other things to do. Loading
services/java/com/android/server/am/HistoryRecord.java +2 −0 Original line number Diff line number Diff line Loading @@ -387,12 +387,14 @@ class HistoryRecord extends IApplicationToken.Stub { sb.append(" ms)"); Log.i(ActivityManagerService.TAG, sb.toString()); } service.reportActivityLaunchedLocked(false, this, thisTime, totalTime); if (totalTime > 0) { service.mUsageStatsService.noteLaunchTime(realActivity, (int)totalTime); } startTime = 0; service.mInitialStartTime = 0; } service.reportActivityVisibleLocked(this); if (ActivityManagerService.DEBUG_SWITCH) Log.v( ActivityManagerService.TAG, "windowsVisible(): " + this); if (!nowVisible) { Loading