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

Commit 09c916bc authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

Add bindService API to not bring ot foreground.

Add a new flag for bindService that tells the system to not bring the
target service's process in to the foreground scheduling class.  This is
used by the sync system to not cause the current sync adapter to come to
the foreground as it is running.

Also some small improvements to the debug output of the process list
of oom adj and scheduling info.
parent ea4823c1
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -32352,6 +32352,17 @@
 visibility="public"
>
</field>
<field name="BIND_NOT_FOREGROUND"
 type="int"
 transient="false"
 volatile="false"
 value="4"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="CLIPBOARD_SERVICE"
 type="java.lang.String"
 transient="false"
+12 −0
Original line number Diff line number Diff line
@@ -104,6 +104,18 @@ public abstract class Context {
     */
    public static final int BIND_DEBUG_UNBIND = 0x0002;

    /**
     * Flag for {@link #bindService}: don't allow this binding to raise
     * the target service's process to the foreground scheduling priority.
     * It will still be raised to the at least the same memory priority
     * as the client (so that its process will not be killable in any
     * situation where the client is not killable), but for CPU scheduling
     * purposes it may be left in the background.  This only has an impact
     * in the situation where the binding client is a foreground process
     * and the target service is in a background process.
     */
    public static final int BIND_NOT_FOREGROUND = 0x0004;

    /** Return an AssetManager instance for your application's package. */
    public abstract AssetManager getAssets();

+3 −2
Original line number Diff line number Diff line
@@ -557,7 +557,7 @@ class SyncManager implements OnAccountsUpdateListener {
        intent.setAction("android.content.SyncAdapter");
        intent.setComponent(syncAdapterInfo.componentName);
        mContext.bindService(intent, new InitializerServiceConnection(account, authority),
                Context.BIND_AUTO_CREATE);
                Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND);
    }

    private class InitializerServiceConnection implements ServiceConnection {
@@ -1145,7 +1145,8 @@ class SyncManager implements OnAccountsUpdateListener {
                    com.android.internal.R.string.sync_binding_label);
            intent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity(
                    mContext, 0, new Intent(Settings.ACTION_SYNC_SETTINGS), 0));
            return mContext.bindService(intent, this, Context.BIND_AUTO_CREATE);
            return mContext.bindService(intent, this,
                    Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND);
        }

        void unBindFromSyncAdapter() {
+101 −18
Original line number Diff line number Diff line
@@ -5258,7 +5258,8 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
        
        app.thread = thread;
        app.curAdj = app.setAdj = -100;
        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
        app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
        app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
        app.forcingToForeground = null;
        app.foregroundServices = false;
        app.debugging = false;
@@ -9133,7 +9134,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
                if (needSep) pw.println(" ");
                needSep = true;
                pw.println("  Running processes (most recent first):");
                dumpProcessList(pw, mLRUProcesses, "    ",
                dumpProcessList(pw, this, mLRUProcesses, "    ",
                        "App ", "PERS", true);
                needSep = true;
            }
@@ -9164,7 +9165,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
                if (needSep) pw.println(" ");
                needSep = true;
                pw.println("  Persisent processes that are starting:");
                dumpProcessList(pw, mPersistentStartingProcesses, "    ",
                dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
                        "Starting Norm", "Restarting PERS", false);
            }
@@ -9172,7 +9173,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
                if (needSep) pw.println(" ");
                needSep = true;
                pw.println("  Processes that are starting:");
                dumpProcessList(pw, mStartingProcesses, "    ",
                dumpProcessList(pw, this, mStartingProcesses, "    ",
                        "Starting Norm", "Starting PERS", false);
            }
@@ -9180,7 +9181,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
                if (needSep) pw.println(" ");
                needSep = true;
                pw.println("  Processes that are being removed:");
                dumpProcessList(pw, mRemovedProcesses, "    ",
                dumpProcessList(pw, this, mRemovedProcesses, "    ",
                        "Removed Norm", "Removed PERS", false);
            }
            
@@ -9188,7 +9189,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
                if (needSep) pw.println(" ");
                needSep = true;
                pw.println("  Processes that are on old until the system is ready:");
                dumpProcessList(pw, mProcessesOnHold, "    ",
                dumpProcessList(pw, this, mProcessesOnHold, "    ",
                        "OnHold Norm", "OnHold PERS", false);
            }
@@ -9617,7 +9618,16 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
        }
    }
    private static final int dumpProcessList(PrintWriter pw, List list,
    private static String buildOomTag(String prefix, String space, int val, int base) {
        if (val == base) {
            if (space == null) return prefix;
            return prefix + "  ";
        }
        return prefix + "+" + Integer.toString(val-base);
    }
    
    private static final int dumpProcessList(PrintWriter pw,
            ActivityManagerService service, List list,
            String prefix, String normalLabel, String persistentLabel,
            boolean inclOomAdj) {
        int numPers = 0;
@@ -9628,9 +9638,55 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
                      + " #" + i + ":");
                r.dump(pw, prefix + "  ");
            } else if (inclOomAdj) {
                pw.println(String.format("%s%s #%2d: adj=%4d/%d %s (%s)",
                String oomAdj;
                if (r.setAdj >= EMPTY_APP_ADJ) {
                    oomAdj = buildOomTag("empty", null, r.setAdj,
                            EMPTY_APP_ADJ);
                } else if (r.setAdj >= CONTENT_PROVIDER_ADJ) {
                    oomAdj = buildOomTag("cprov", null, r.setAdj,
                            CONTENT_PROVIDER_ADJ);
                } else if (r.setAdj >= HIDDEN_APP_MIN_ADJ) {
                    oomAdj = buildOomTag("hid", "  ", r.setAdj,
                            HIDDEN_APP_MIN_ADJ);
                } else if (r.setAdj >= service.HOME_APP_ADJ) {
                    oomAdj = buildOomTag("home ", null, r.setAdj,
                            service.HOME_APP_ADJ);
                } else if (r.setAdj >= service.SECONDARY_SERVER_ADJ) {
                    oomAdj = buildOomTag("svc", "  ", r.setAdj,
                            service.SECONDARY_SERVER_ADJ);
                } else if (r.setAdj >= service.BACKUP_APP_ADJ) {
                    oomAdj = buildOomTag("bckup", null, r.setAdj,
                            service.BACKUP_APP_ADJ);
                } else if (r.setAdj >= service.VISIBLE_APP_ADJ) {
                    oomAdj = buildOomTag("vis  ", null, r.setAdj,
                            service.VISIBLE_APP_ADJ);
                } else if (r.setAdj >= service.FOREGROUND_APP_ADJ) {
                    oomAdj = buildOomTag("fore ", null, r.setAdj,
                            service.FOREGROUND_APP_ADJ);
                } else if (r.setAdj >= CORE_SERVER_ADJ) {
                    oomAdj = buildOomTag("core ", null, r.setAdj,
                            CORE_SERVER_ADJ);
                } else if (r.setAdj >= SYSTEM_ADJ) {
                    oomAdj = buildOomTag("sys  ", null, r.setAdj,
                            SYSTEM_ADJ);
                } else {
                    oomAdj = Integer.toString(r.setAdj);
                }
                String schedGroup;
                switch (r.setSchedGroup) {
                    case Process.THREAD_GROUP_BG_NONINTERACTIVE:
                        schedGroup = "B";
                        break;
                    case Process.THREAD_GROUP_DEFAULT:
                        schedGroup = "F";
                        break;
                    default:
                        schedGroup = Integer.toString(r.setSchedGroup);
                        break;
                }
                pw.println(String.format("%s%s #%2d: adj=%s/%s %s (%s)",
                        prefix, (r.persistent ? persistentLabel : normalLabel),
                        i, r.setAdj, r.setSchedGroup, r.toString(), r.adjType));
                        i, oomAdj, schedGroup, r.toString(), r.adjType));
                if (r.adjSource != null || r.adjTarget != null) {
                    pw.println(prefix + "          " + r.adjTarget
                            + " used by " + r.adjSource);
@@ -13038,6 +13094,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
        if (app.thread == null) {
            app.adjSeq = mAdjSeq;
            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
            return (app.curAdj=EMPTY_APP_ADJ);
        }
@@ -13058,52 +13115,63 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
        // Determine the importance of the process, starting with most
        // important to least, and assign an appropriate OOM adjustment.
        int adj;
        int schedGroup;
        int N;
        if (app == TOP_APP) {
            // The last app on the list is the foreground app.
            adj = FOREGROUND_APP_ADJ;
            schedGroup = Process.THREAD_GROUP_DEFAULT;
            app.adjType = "top-activity";
        } else if (app.instrumentationClass != null) {
            // Don't want to kill running instrumentation.
            adj = FOREGROUND_APP_ADJ;
            schedGroup = Process.THREAD_GROUP_DEFAULT;
            app.adjType = "instrumentation";
        } else if (app.persistentActivities > 0) {
            // Special persistent activities...  shouldn't be used these days.
            adj = FOREGROUND_APP_ADJ;
            schedGroup = Process.THREAD_GROUP_DEFAULT;
            app.adjType = "persistent";
        } else if (app.curReceiver != null ||
                (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
            // An app that is currently receiving a broadcast also
            // counts as being in the foreground.
            adj = FOREGROUND_APP_ADJ;
            schedGroup = Process.THREAD_GROUP_DEFAULT;
            app.adjType = "broadcast";
        } else if (app.executingServices.size() > 0) {
            // An app that is currently executing a service callback also
            // counts as being in the foreground.
            adj = FOREGROUND_APP_ADJ;
            schedGroup = Process.THREAD_GROUP_DEFAULT;
            app.adjType = "exec-service";
        } else if (app.foregroundServices) {
            // The user is aware of this app, so make it visible.
            adj = VISIBLE_APP_ADJ;
            schedGroup = Process.THREAD_GROUP_DEFAULT;
            app.adjType = "foreground-service";
        } else if (app.forcingToForeground != null) {
            // The user is aware of this app, so make it visible.
            adj = VISIBLE_APP_ADJ;
            schedGroup = Process.THREAD_GROUP_DEFAULT;
            app.adjType = "force-foreground";
            app.adjSource = app.forcingToForeground;
        } else if (app == mHomeProcess) {
            // This process is hosting what we currently consider to be the
            // home app, so we don't want to let it go into the background.
            adj = HOME_APP_ADJ;
            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
            app.adjType = "home";
        } else if ((N=app.activities.size()) != 0) {
            // This app is in the background with paused activities.
            adj = hiddenAdj;
            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
            app.adjType = "bg-activities";
            for (int j=0; j<N; j++) {
                if (((HistoryRecord)app.activities.get(j)).visible) {
                    // This app has a visible activity!
                    adj = VISIBLE_APP_ADJ;
                    schedGroup = Process.THREAD_GROUP_DEFAULT;
                    app.adjType = "visible";
                    break;
                }
@@ -13111,6 +13179,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
        } else {
            // A very not-needed process.
            adj = EMPTY_APP_ADJ;
            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
            app.adjType = "empty";
        }
@@ -13120,7 +13189,6 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
        // infinite recursion.
        app.adjSeq = mAdjSeq;
        app.curRawAdj = adj;
        app.curAdj = adj <= app.maxAdj ? adj : app.maxAdj;
        if (mBackupTarget != null && app == mBackupTarget.app) {
            // If possible we want to avoid killing apps while they're being backed up
@@ -13131,7 +13199,8 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
            }
        }
        if (app.services.size() != 0 && adj > FOREGROUND_APP_ADJ) {
        if (app.services.size() != 0 && (adj > FOREGROUND_APP_ADJ
                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
            final long now = SystemClock.uptimeMillis();
            // This process is more important if the top activity is
            // bound to the service.
@@ -13149,7 +13218,8 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
                        }
                    }
                }
                if (s.connections.size() > 0 && adj > FOREGROUND_APP_ADJ) {
                if (s.connections.size() > 0 && (adj > FOREGROUND_APP_ADJ
                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
                    Iterator<ConnectionRecord> kt
                            = s.connections.values().iterator();
                    while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
@@ -13181,6 +13251,11 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
                                app.adjSource = cr.binding.client;
                                app.adjTarget = s.serviceInfo.name;
                            }
                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
                                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
                                    schedGroup = Process.THREAD_GROUP_DEFAULT;
                                }
                            }
                        }
                        HistoryRecord a = cr.activity;
                        //if (a != null) {
@@ -13190,6 +13265,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
                                (a.state == ActivityState.RESUMED
                                 || a.state == ActivityState.PAUSING)) {
                            adj = FOREGROUND_APP_ADJ;
                            schedGroup = Process.THREAD_GROUP_DEFAULT;
                            app.adjType = "service";
                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
                                    .REASON_SERVICE_IN_USE;
@@ -13211,9 +13287,11 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
            }
        }
        if (app.pubProviders.size() != 0 && adj > FOREGROUND_APP_ADJ) {
        if (app.pubProviders.size() != 0 && (adj > FOREGROUND_APP_ADJ
                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
            Iterator jt = app.pubProviders.values().iterator();
            while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) {
            while (jt.hasNext() && (adj > FOREGROUND_APP_ADJ
                    || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
                ContentProviderRecord cpr = (ContentProviderRecord)jt.next();
                if (cpr.clients.size() != 0) {
                    Iterator<ProcessRecord> kt = cpr.clients.iterator();
@@ -13242,6 +13320,9 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
                            app.adjSource = client;
                            app.adjTarget = cpr.info.name;
                        }
                        if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
                            schedGroup = Process.THREAD_GROUP_DEFAULT;
                        }
                    }
                }
                // If the provider has external (non-framework) process
@@ -13250,6 +13331,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
                if (cpr.externals != 0) {
                    if (adj > FOREGROUND_APP_ADJ) {
                        adj = FOREGROUND_APP_ADJ;
                        schedGroup = Process.THREAD_GROUP_DEFAULT;
                        app.adjType = "provider";
                        app.adjTarget = cpr.info.name;
                    }
@@ -13272,12 +13354,13 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
        if (adj > app.maxAdj) {
            adj = app.maxAdj;
            if (app.maxAdj <= VISIBLE_APP_ADJ) {
                schedGroup = Process.THREAD_GROUP_DEFAULT;
            }
        }
        app.curAdj = adj;
        app.curSchedGroup = adj > VISIBLE_APP_ADJ
                ? Process.THREAD_GROUP_BG_NONINTERACTIVE
                : Process.THREAD_GROUP_DEFAULT;
        app.curSchedGroup = schedGroup;
        
        return adj;
    }
@@ -13422,7 +13505,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
        int adj = computeOomAdjLocked(app, hiddenAdj, TOP_APP);
        if (app.pid != 0 && app.pid != MY_PID) {
        if ((app.pid != 0 && app.pid != MY_PID) || Process.supportsProcesses()) {
            if (app.curRawAdj != app.setRawAdj) {
                if (app.curRawAdj > FOREGROUND_APP_ADJ
                        && app.setRawAdj <= FOREGROUND_APP_ADJ) {