Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4610545d authored by Dianne Hackborn's avatar Dianne Hackborn Committed by Android (Google) Code Review
Browse files

Merge "Fix issue #16311398: Limit number of documents a process can open" into lmp-dev

parents 15741d0e 89ad456e
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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);
@@ -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 {
+20 −0
Original line number Diff line number Diff line
@@ -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
+34 −0
Original line number Diff line number Diff line
@@ -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.
+39 −0
Original line number Diff line number Diff line
@@ -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();
@@ -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();
+34 −4
Original line number Diff line number Diff line
@@ -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;
@@ -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
@@ -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);
@@ -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;
@@ -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);
@@ -3175,6 +3177,7 @@ public final class ActivityThread {
                ActivityManagerNative.getDefault().activityPaused(token, r.persistentState);
            } catch (RemoteException ex) {
            }
            mSomeActivitiesChanged = true;
        }
    }

@@ -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) {
@@ -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) {
@@ -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,
@@ -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;
@@ -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) {
@@ -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