Loading api/current.txt +3 −0 Original line number Diff line number Diff line Loading @@ -3517,6 +3517,7 @@ package android.app { method public void postponeEnterTransition(); method public void recreate(); method public void registerForContextMenu(android.view.View); method public boolean releaseInstance(); method public final deprecated void removeDialog(int); method public void reportFullyDrawn(); method public boolean requestVisibleBehind(boolean); Loading Loading @@ -3636,7 +3637,9 @@ package android.app { public static class ActivityManager.AppTask { method public void finishAndRemoveTask(); method public android.app.ActivityManager.RecentTaskInfo getTaskInfo(); method public void moveToFront(); method public void setExcludeFromRecents(boolean); method public void startActivity(android.content.Context, android.content.Intent, android.os.Bundle); } public static class ActivityManager.MemoryInfo implements android.os.Parcelable { core/java/android/app/Activity.java +20 −0 Original line number Diff line number Diff line Loading @@ -4703,6 +4703,26 @@ public class Activity extends ContextThemeWrapper finish(true); } /** * Ask that the local app instance of this activity be released to free up its memory. * This is asking for the activity to be destroyed, but does <b>not</b> finish the activity -- * a new instance of the activity will later be re-created if needed due to the user * navigating back to it. * * @return Returns true if the activity was in a state that it has started the process * of destroying its current instance; returns false if for any reason this could not * be done: it is currently visible to the user, it is already being destroyed, it is * being finished, it hasn't yet saved its state, etc. */ public boolean releaseInstance() { try { return ActivityManagerNative.getDefault().releaseActivityInstance(mToken); } catch (RemoteException e) { // Empty } return false; } /** * Called when an activity you launched exits, giving you the requestCode * you started it with, the resultCode it returned, and any additional Loading core/java/android/app/ActivityManager.java +34 −0 Original line number Diff line number Diff line Loading @@ -2622,6 +2622,40 @@ public class ActivityManager { } } /** * Bring this task to the foreground. If it contains activities, they will be * brought to the foreground with it and their instances re-created if needed. * If it doesn't contain activities, the root activity of the task will be * re-launched. */ public void moveToFront() { try { mAppTaskImpl.moveToFront(); } catch (RemoteException e) { Slog.e(TAG, "Invalid AppTask", e); } } /** * Start an activity in this task. Brings the task to the foreground. If this task * is not currently active (that is, its id < 0), then the activity being started * needs to be started as a new task and the Intent's ComponentName must match the * base ComponenentName of the recent task entry. Otherwise, the activity being * started must <b>not</b> be launched as a new task -- not through explicit intent * flags nor implicitly as the singleTask or singleInstance launch modes. * * <p>See {@link Activity#startActivity(android.content.Intent, android.os.Bundle) * Activity.startActivity} for more information.</p> * * @param intent The Intent describing the new activity to be launched on the task. * @param options Optional launch options. */ public void startActivity(Context context, Intent intent, Bundle options) { ActivityThread thread = ActivityThread.currentActivityThread(); thread.getInstrumentation().execStartActivityFromAppTask(context, thread.getApplicationThread(), mAppTaskImpl, intent, options); } /** * Modify the {@link Intent#FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS} flag in the root * Intent of this AppTask. Loading core/java/android/app/ActivityManagerNative.java +39 −0 Original line number Diff line number Diff line Loading @@ -365,6 +365,23 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM return true; } case RELEASE_ACTIVITY_INSTANCE_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder token = data.readStrongBinder(); boolean res = releaseActivityInstance(token); reply.writeNoException(); reply.writeInt(res ? 1 : 0); return true; } case RELEASE_SOME_ACTIVITIES_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IApplicationThread app = ApplicationThreadNative.asInterface(data.readStrongBinder()); releaseSomeActivities(app); reply.writeNoException(); return true; } case WILL_ACTIVITY_BE_VISIBLE_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder token = data.readStrongBinder(); Loading Loading @@ -2661,6 +2678,28 @@ class ActivityManagerProxy implements IActivityManager data.recycle(); reply.recycle(); } public boolean releaseActivityInstance(IBinder token) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeStrongBinder(token); mRemote.transact(RELEASE_ACTIVITY_INSTANCE_TRANSACTION, data, reply, 0); reply.readException(); boolean res = reply.readInt() != 0; data.recycle(); reply.recycle(); return res; } public void releaseSomeActivities(IApplicationThread app) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeStrongBinder(app.asBinder()); mRemote.transact(RELEASE_SOME_ACTIVITIES_TRANSACTION, data, reply, 0); reply.readException(); data.recycle(); reply.recycle(); } public boolean willActivityBeVisible(IBinder token) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); Loading core/java/android/app/ActivityThread.java +34 −4 Original line number Diff line number Diff line Loading @@ -102,8 +102,6 @@ import com.android.org.conscrypt.OpenSSLSocketImpl; import com.android.org.conscrypt.TrustedCertificateStore; import com.google.android.collect.Lists; import dalvik.system.VMRuntime; import java.io.File; import java.io.FileDescriptor; import java.io.FileOutputStream; Loading Loading @@ -201,6 +199,7 @@ public final class ActivityThread { String mInstrumentedLibDir = null; boolean mSystemThread = false; boolean mJitEnabled = false; boolean mSomeActivitiesChanged = false; // These can be accessed by multiple threads; mPackages is the lock. // XXX For now we keep around information about all packages we have Loading Loading @@ -2353,6 +2352,7 @@ public final class ActivityThread { // If we are getting ready to gc after going to the background, well // we are back active so skip it. unscheduleGcIdler(); mSomeActivitiesChanged = true; if (r.profileFd != null) { mProfiler.setProfiler(r.profileFile, r.profileFd); Loading Loading @@ -2495,6 +2495,7 @@ public final class ActivityThread { public void handleCancelVisibleBehind(IBinder token) { ActivityClientRecord r = mActivities.get(token); if (r != null) { mSomeActivitiesChanged = true; final Activity activity = r.activity; if (activity.mVisibleBehind) { activity.mCalled = false; Loading Loading @@ -2984,6 +2985,7 @@ public final class ActivityThread { // If we are getting ready to gc after going to the background, well // we are back active so skip it. unscheduleGcIdler(); mSomeActivitiesChanged = true; // TODO Push resumeArgs into the activity for consideration ActivityClientRecord r = performResumeActivity(token, clearHide); Loading Loading @@ -3175,6 +3177,7 @@ public final class ActivityThread { ActivityManagerNative.getDefault().activityPaused(token, r.persistentState); } catch (RemoteException ex) { } mSomeActivitiesChanged = true; } } Loading Loading @@ -3413,6 +3416,7 @@ public final class ActivityThread { info.state = r.state; info.persistentState = r.persistentState; mH.post(info); mSomeActivitiesChanged = true; } final void performRestartActivity(IBinder token) { Loading Loading @@ -3446,6 +3450,7 @@ public final class ActivityThread { TAG, "Handle window " + r + " visibility: " + show); updateVisibility(r, show); } mSomeActivitiesChanged = true; } private void handleSleeping(IBinder token, boolean sleeping) { Loading Loading @@ -3743,6 +3748,7 @@ public final class ActivityThread { // If the system process has died, it's game over for everyone. } } mSomeActivitiesChanged = true; } public final void requestRelaunchActivity(IBinder token, Loading Loading @@ -3805,6 +3811,7 @@ public final class ActivityThread { // If we are getting ready to gc after going to the background, well // we are back active so skip it. unscheduleGcIdler(); mSomeActivitiesChanged = true; Configuration changedConfig = null; int configChanges = 0; Loading Loading @@ -4107,6 +4114,8 @@ public final class ActivityThread { performConfigurationChanged(r.activity, mCompatConfiguration); freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(mCompatConfiguration)); mSomeActivitiesChanged = true; } final void handleProfilerControl(boolean start, ProfilerControlData pcd, int profileType) { Loading Loading @@ -5045,12 +5054,33 @@ public final class ActivityThread { android.ddm.DdmHandleAppName.setAppName("<pre-initialized>", UserHandle.myUserId()); RuntimeInit.setApplicationObject(mAppThread.asBinder()); IActivityManager mgr = ActivityManagerNative.getDefault(); final IActivityManager mgr = ActivityManagerNative.getDefault(); try { mgr.attachApplication(mAppThread); } catch (RemoteException ex) { // Ignore } // Watch for getting close to heap limit. BinderInternal.addGcWatcher(new Runnable() { @Override public void run() { if (!mSomeActivitiesChanged) { return; } Runtime runtime = Runtime.getRuntime(); long dalvikMax = runtime.maxMemory(); long dalvikUsed = runtime.totalMemory() - runtime.freeMemory(); if (dalvikUsed > ((3*dalvikMax)/4)) { if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024) + " total=" + (runtime.totalMemory()/1024) + " used=" + (dalvikUsed/1024)); mSomeActivitiesChanged = false; try { mgr.releaseSomeActivities(mAppThread); } catch (RemoteException e) { } } } }); } else { // Don't set application object here -- if the system crashes, // we can't display an alert, we just want to die die die. Loading Loading
api/current.txt +3 −0 Original line number Diff line number Diff line Loading @@ -3517,6 +3517,7 @@ package android.app { method public void postponeEnterTransition(); method public void recreate(); method public void registerForContextMenu(android.view.View); method public boolean releaseInstance(); method public final deprecated void removeDialog(int); method public void reportFullyDrawn(); method public boolean requestVisibleBehind(boolean); Loading Loading @@ -3636,7 +3637,9 @@ package android.app { public static class ActivityManager.AppTask { method public void finishAndRemoveTask(); method public android.app.ActivityManager.RecentTaskInfo getTaskInfo(); method public void moveToFront(); method public void setExcludeFromRecents(boolean); method public void startActivity(android.content.Context, android.content.Intent, android.os.Bundle); } public static class ActivityManager.MemoryInfo implements android.os.Parcelable {
core/java/android/app/Activity.java +20 −0 Original line number Diff line number Diff line Loading @@ -4703,6 +4703,26 @@ public class Activity extends ContextThemeWrapper finish(true); } /** * Ask that the local app instance of this activity be released to free up its memory. * This is asking for the activity to be destroyed, but does <b>not</b> finish the activity -- * a new instance of the activity will later be re-created if needed due to the user * navigating back to it. * * @return Returns true if the activity was in a state that it has started the process * of destroying its current instance; returns false if for any reason this could not * be done: it is currently visible to the user, it is already being destroyed, it is * being finished, it hasn't yet saved its state, etc. */ public boolean releaseInstance() { try { return ActivityManagerNative.getDefault().releaseActivityInstance(mToken); } catch (RemoteException e) { // Empty } return false; } /** * Called when an activity you launched exits, giving you the requestCode * you started it with, the resultCode it returned, and any additional Loading
core/java/android/app/ActivityManager.java +34 −0 Original line number Diff line number Diff line Loading @@ -2622,6 +2622,40 @@ public class ActivityManager { } } /** * Bring this task to the foreground. If it contains activities, they will be * brought to the foreground with it and their instances re-created if needed. * If it doesn't contain activities, the root activity of the task will be * re-launched. */ public void moveToFront() { try { mAppTaskImpl.moveToFront(); } catch (RemoteException e) { Slog.e(TAG, "Invalid AppTask", e); } } /** * Start an activity in this task. Brings the task to the foreground. If this task * is not currently active (that is, its id < 0), then the activity being started * needs to be started as a new task and the Intent's ComponentName must match the * base ComponenentName of the recent task entry. Otherwise, the activity being * started must <b>not</b> be launched as a new task -- not through explicit intent * flags nor implicitly as the singleTask or singleInstance launch modes. * * <p>See {@link Activity#startActivity(android.content.Intent, android.os.Bundle) * Activity.startActivity} for more information.</p> * * @param intent The Intent describing the new activity to be launched on the task. * @param options Optional launch options. */ public void startActivity(Context context, Intent intent, Bundle options) { ActivityThread thread = ActivityThread.currentActivityThread(); thread.getInstrumentation().execStartActivityFromAppTask(context, thread.getApplicationThread(), mAppTaskImpl, intent, options); } /** * Modify the {@link Intent#FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS} flag in the root * Intent of this AppTask. Loading
core/java/android/app/ActivityManagerNative.java +39 −0 Original line number Diff line number Diff line Loading @@ -365,6 +365,23 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM return true; } case RELEASE_ACTIVITY_INSTANCE_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder token = data.readStrongBinder(); boolean res = releaseActivityInstance(token); reply.writeNoException(); reply.writeInt(res ? 1 : 0); return true; } case RELEASE_SOME_ACTIVITIES_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IApplicationThread app = ApplicationThreadNative.asInterface(data.readStrongBinder()); releaseSomeActivities(app); reply.writeNoException(); return true; } case WILL_ACTIVITY_BE_VISIBLE_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder token = data.readStrongBinder(); Loading Loading @@ -2661,6 +2678,28 @@ class ActivityManagerProxy implements IActivityManager data.recycle(); reply.recycle(); } public boolean releaseActivityInstance(IBinder token) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeStrongBinder(token); mRemote.transact(RELEASE_ACTIVITY_INSTANCE_TRANSACTION, data, reply, 0); reply.readException(); boolean res = reply.readInt() != 0; data.recycle(); reply.recycle(); return res; } public void releaseSomeActivities(IApplicationThread app) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeStrongBinder(app.asBinder()); mRemote.transact(RELEASE_SOME_ACTIVITIES_TRANSACTION, data, reply, 0); reply.readException(); data.recycle(); reply.recycle(); } public boolean willActivityBeVisible(IBinder token) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); Loading
core/java/android/app/ActivityThread.java +34 −4 Original line number Diff line number Diff line Loading @@ -102,8 +102,6 @@ import com.android.org.conscrypt.OpenSSLSocketImpl; import com.android.org.conscrypt.TrustedCertificateStore; import com.google.android.collect.Lists; import dalvik.system.VMRuntime; import java.io.File; import java.io.FileDescriptor; import java.io.FileOutputStream; Loading Loading @@ -201,6 +199,7 @@ public final class ActivityThread { String mInstrumentedLibDir = null; boolean mSystemThread = false; boolean mJitEnabled = false; boolean mSomeActivitiesChanged = false; // These can be accessed by multiple threads; mPackages is the lock. // XXX For now we keep around information about all packages we have Loading Loading @@ -2353,6 +2352,7 @@ public final class ActivityThread { // If we are getting ready to gc after going to the background, well // we are back active so skip it. unscheduleGcIdler(); mSomeActivitiesChanged = true; if (r.profileFd != null) { mProfiler.setProfiler(r.profileFile, r.profileFd); Loading Loading @@ -2495,6 +2495,7 @@ public final class ActivityThread { public void handleCancelVisibleBehind(IBinder token) { ActivityClientRecord r = mActivities.get(token); if (r != null) { mSomeActivitiesChanged = true; final Activity activity = r.activity; if (activity.mVisibleBehind) { activity.mCalled = false; Loading Loading @@ -2984,6 +2985,7 @@ public final class ActivityThread { // If we are getting ready to gc after going to the background, well // we are back active so skip it. unscheduleGcIdler(); mSomeActivitiesChanged = true; // TODO Push resumeArgs into the activity for consideration ActivityClientRecord r = performResumeActivity(token, clearHide); Loading Loading @@ -3175,6 +3177,7 @@ public final class ActivityThread { ActivityManagerNative.getDefault().activityPaused(token, r.persistentState); } catch (RemoteException ex) { } mSomeActivitiesChanged = true; } } Loading Loading @@ -3413,6 +3416,7 @@ public final class ActivityThread { info.state = r.state; info.persistentState = r.persistentState; mH.post(info); mSomeActivitiesChanged = true; } final void performRestartActivity(IBinder token) { Loading Loading @@ -3446,6 +3450,7 @@ public final class ActivityThread { TAG, "Handle window " + r + " visibility: " + show); updateVisibility(r, show); } mSomeActivitiesChanged = true; } private void handleSleeping(IBinder token, boolean sleeping) { Loading Loading @@ -3743,6 +3748,7 @@ public final class ActivityThread { // If the system process has died, it's game over for everyone. } } mSomeActivitiesChanged = true; } public final void requestRelaunchActivity(IBinder token, Loading Loading @@ -3805,6 +3811,7 @@ public final class ActivityThread { // If we are getting ready to gc after going to the background, well // we are back active so skip it. unscheduleGcIdler(); mSomeActivitiesChanged = true; Configuration changedConfig = null; int configChanges = 0; Loading Loading @@ -4107,6 +4114,8 @@ public final class ActivityThread { performConfigurationChanged(r.activity, mCompatConfiguration); freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(mCompatConfiguration)); mSomeActivitiesChanged = true; } final void handleProfilerControl(boolean start, ProfilerControlData pcd, int profileType) { Loading Loading @@ -5045,12 +5054,33 @@ public final class ActivityThread { android.ddm.DdmHandleAppName.setAppName("<pre-initialized>", UserHandle.myUserId()); RuntimeInit.setApplicationObject(mAppThread.asBinder()); IActivityManager mgr = ActivityManagerNative.getDefault(); final IActivityManager mgr = ActivityManagerNative.getDefault(); try { mgr.attachApplication(mAppThread); } catch (RemoteException ex) { // Ignore } // Watch for getting close to heap limit. BinderInternal.addGcWatcher(new Runnable() { @Override public void run() { if (!mSomeActivitiesChanged) { return; } Runtime runtime = Runtime.getRuntime(); long dalvikMax = runtime.maxMemory(); long dalvikUsed = runtime.totalMemory() - runtime.freeMemory(); if (dalvikUsed > ((3*dalvikMax)/4)) { if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024) + " total=" + (runtime.totalMemory()/1024) + " used=" + (dalvikUsed/1024)); mSomeActivitiesChanged = false; try { mgr.releaseSomeActivities(mAppThread); } catch (RemoteException e) { } } } }); } else { // Don't set application object here -- if the system crashes, // we can't display an alert, we just want to die die die. Loading