Start implementing background restrictions for eph apps.

This implements the additional intended path for checking
allowed background operations, APP_START_MODE_DISABLED, which
doesn't allow an app to launch in the background at all.

Also change the semantics of delivering broadcasts to manifest
receivers to always restrict those, not changing based on
whether the app is currently idle.  This is the desired intended
behavior for apps as they explicitly update to work with
bg check.

And now that we have ephemerality associated with the uid state
in the activity manager, we can propagate this through the
relevant callbacks in IUidObserver so things watching these
changes can immediately determine whether they should do their
more aggressive shut down work for the uid rather than having
to walk through all their state looking for package associated
with that uid and whether they should be shut down.

Also remove the "lenient" bg check mode, since that was
just an early experiment that we won't actually use.

Add a new "make-idle" activity manager command to immediately
put a uid into the idle state (if possible) to make it easier
to test.

Test: manually against an eph app
Change-Id: I43a138ff281f69a9251d3f29ab6e13f48cff8ad6
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index 82897fb..2558045 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -1940,13 +1940,9 @@
         }
         for (int i = mPendingWhileIdleAlarms.size() - 1; i >= 0; i--) {
             final Alarm a = mPendingWhileIdleAlarms.get(i);
-            try {
-                if (a.uid == uid && ActivityManagerNative.getDefault().getAppStartMode(
-                        uid, a.packageName) == ActivityManager.APP_START_MODE_DISABLED) {
-                    // Don't set didRemove, since this doesn't impact the scheduled alarms.
-                    mPendingWhileIdleAlarms.remove(i);
-                }
-            } catch (RemoteException e) {
+            if (a.uid == uid) {
+                // Don't set didRemove, since this doesn't impact the scheduled alarms.
+                mPendingWhileIdleAlarms.remove(i);
             }
         }
 
@@ -2807,15 +2803,22 @@
         @Override public void onUidStateChanged(int uid, int procState) throws RemoteException {
         }
 
-        @Override public void onUidGone(int uid) throws RemoteException {
+        @Override public void onUidGone(int uid, boolean disabled) throws RemoteException {
+            if (disabled) {
+                synchronized (mLock) {
+                    removeForStoppedLocked(uid);
+                }
+            }
         }
 
         @Override public void onUidActive(int uid) throws RemoteException {
         }
 
-        @Override public void onUidIdle(int uid) throws RemoteException {
-            synchronized (mLock) {
-                removeForStoppedLocked(uid);
+        @Override public void onUidIdle(int uid, boolean disabled) throws RemoteException {
+            if (disabled) {
+                synchronized (mLock) {
+                    removeForStoppedLocked(uid);
+                }
             }
         }
     };
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index dc4a52d..136e02c 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -348,7 +348,7 @@
                 // Before going further -- if this app is not allowed to run in the
                 // background, then at this point we aren't going to let it period.
                 final int allowed = mAm.checkAllowBackgroundLocked(
-                        r.appInfo.uid, r.packageName, callingPid, true);
+                        r.appInfo.uid, r.packageName, callingPid, false);
                 if (allowed != ActivityManager.APP_START_MODE_NORMAL) {
                     Slog.w(TAG, "Background start not allowed: service "
                             + service + " to " + r.name.flattenToShortString()
@@ -594,7 +594,8 @@
             for (int i=services.mServicesByName.size()-1; i>=0; i--) {
                 ServiceRecord service = services.mServicesByName.valueAt(i);
                 if (service.appInfo.uid == uid && service.startRequested) {
-                    if (mAm.mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
+                    if (service.appInfo.isEphemeralApp() ||
+                            mAm.mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
                             uid, service.packageName) != AppOpsManager.MODE_ALLOWED) {
                         if (stopping == null) {
                             stopping = new ArrayList<>();
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index ca60f49..d7f6177 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -290,10 +290,8 @@
 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
-import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
 import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
 import static android.provider.Settings.System.FONT_SCALE;
-import static android.util.TypedValue.COMPLEX_UNIT_DIP;
 import static android.view.Display.DEFAULT_DISPLAY;
 
 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
@@ -1360,7 +1358,6 @@
     String mOrigDebugApp = null;
     boolean mOrigWaitForDebugger = false;
     boolean mAlwaysFinishActivities = false;
-    boolean mLenientBackgroundCheck = false;
     boolean mForceResizableActivities;
     boolean mSupportsMultiWindow;
     boolean mSupportsFreeformWindowManagement;
@@ -4145,7 +4142,7 @@
                             if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
                                         "UID idle uid=" + item.uid);
-                                observer.onUidIdle(item.uid);
+                                observer.onUidIdle(item.uid, item.ephemeral);
                             }
                             if (VALIDATE_UID_STATES && i == 0) {
                                 if (validateUid != null) {
@@ -4167,7 +4164,7 @@
                             if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
                                         "UID gone uid=" + item.uid);
-                                observer.onUidGone(item.uid);
+                                observer.onUidGone(item.uid, item.ephemeral);
                             }
                             if (reg.lastProcStates != null) {
                                 reg.lastProcStates.delete(item.uid);
@@ -7792,38 +7789,43 @@
 
     public int getAppStartMode(int uid, String packageName) {
         synchronized (this) {
-            return checkAllowBackgroundLocked(uid, packageName, -1, true);
+            return checkAllowBackgroundLocked(uid, packageName, -1, false);
         }
     }
 
     int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
-            boolean allowWhenForeground) {
+            boolean alwaysRestrict) {
         UidRecord uidRec = mActiveUids.get(uid);
-        if (!mLenientBackgroundCheck) {
-            if (!allowWhenForeground || uidRec == null
-                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
+        if (uidRec == null || alwaysRestrict || uidRec.idle) {
+            boolean ephemeral;
+            if (uidRec == null) {
+                ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
+                        UserHandle.getUserId(uid), packageName);
+            } else {
+                ephemeral = uidRec.ephemeral;
+            }
+
+            if (ephemeral) {
+                // We are hard-core about ephemeral apps not running in the background.
+                return ActivityManager.APP_START_MODE_DISABLED;
+            } else {
+                if (callingPid >= 0) {
+                    ProcessRecord proc;
+                    synchronized (mPidsSelfLocked) {
+                        proc = mPidsSelfLocked.get(callingPid);
+                    }
+                    if (proc != null && proc.curProcState
+                            < ActivityManager.PROCESS_STATE_RECEIVER) {
+                        // Whoever is instigating this is in the foreground, so we will allow it
+                        // to go through.
+                        return ActivityManager.APP_START_MODE_NORMAL;
+                    }
+                }
                 if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
                         packageName) != AppOpsManager.MODE_ALLOWED) {
                     return ActivityManager.APP_START_MODE_DELAYED;
                 }
             }
-
-        } else if (uidRec == null || uidRec.idle) {
-            if (callingPid >= 0) {
-                ProcessRecord proc;
-                synchronized (mPidsSelfLocked) {
-                    proc = mPidsSelfLocked.get(callingPid);
-                }
-                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
-                    // Whoever is instigating this is in the foreground, so we will allow it
-                    // to go through.
-                    return ActivityManager.APP_START_MODE_NORMAL;
-                }
-            }
-            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
-                    != AppOpsManager.MODE_ALLOWED) {
-                return ActivityManager.APP_START_MODE_DELAYED;
-            }
         }
         return ActivityManager.APP_START_MODE_NORMAL;
     }
@@ -11870,25 +11872,6 @@
     }
 
     @Override
-    public void setLenientBackgroundCheck(boolean enabled) {
-        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
-                "setLenientBackgroundCheck()");
-
-        long ident = Binder.clearCallingIdentity();
-        try {
-            Settings.Global.putInt(
-                    mContext.getContentResolver(),
-                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
-
-            synchronized (this) {
-                mLenientBackgroundCheck = enabled;
-            }
-        } finally {
-            Binder.restoreCallingIdentity(ident);
-        }
-    }
-
-    @Override
     public void setActivityController(IActivityController controller, boolean imAMonkey) {
         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
                 "setActivityController()");
@@ -12987,8 +12970,6 @@
         final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
         final boolean alwaysFinishActivities =
                 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
-        final boolean lenientBackgroundCheck =
-                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
         final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
         final boolean forceResizable = Settings.Global.getInt(
                 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
@@ -13009,7 +12990,6 @@
             mDebugApp = mOrigDebugApp = debugApp;
             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
             mAlwaysFinishActivities = alwaysFinishActivities;
-            mLenientBackgroundCheck = lenientBackgroundCheck;
             mSupportsLeanbackOnly = supportsLeanbackOnly;
             mForceResizableActivities = forceResizable;
             if (supportsMultiWindow || forceResizable) {
@@ -14782,9 +14762,8 @@
             }
         }
         if (dumpPackage == null) {
-            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
-                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
-                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
+            if (mAlwaysFinishActivities) {
+                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities);
             }
             if (mController != null) {
                 pw.println("  mController=" + mController
@@ -20709,6 +20688,7 @@
         pendingChange.change = change;
         pendingChange.processState = uidRec != null
                 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
+        pendingChange.ephemeral = uidRec.ephemeral;
 
         // Directly update the power manager, since we sit on top of it and it is critical
         // it be kept in sync (so wake locks will be held as soon as appropriate).
@@ -21076,8 +21056,11 @@
                 } else {
                     // Keeping this process, update its uid.
                     final UidRecord uidRec = app.uidRecord;
-                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
-                        uidRec.curProcState = app.curProcState;
+                    if (uidRec != null) {
+                        uidRec.ephemeral = app.info.isEphemeralApp();
+                        if (uidRec.curProcState > app.curProcState) {
+                            uidRec.curProcState = app.curProcState;
+                        }
                     }
                 }
 
@@ -21336,6 +21319,63 @@
         }
     }
 
+    @Override
+    public void makePackageIdle(String packageName, int userId) {
+        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
+                != PackageManager.PERMISSION_GRANTED) {
+            String msg = "Permission Denial: makePackageIdle() from pid="
+                    + Binder.getCallingPid()
+                    + ", uid=" + Binder.getCallingUid()
+                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
+            Slog.w(TAG, msg);
+            throw new SecurityException(msg);
+        }
+        final int callingPid = Binder.getCallingPid();
+        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
+                userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
+        long callingId = Binder.clearCallingIdentity();
+        synchronized(this) {
+            try {
+                IPackageManager pm = AppGlobals.getPackageManager();
+                int pkgUid = -1;
+                try {
+                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
+                            | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
+                } catch (RemoteException e) {
+                }
+                if (pkgUid == -1) {
+                    throw new IllegalArgumentException("Unknown package name " + packageName);
+                }
+
+                if (mLocalPowerManager != null) {
+                    mLocalPowerManager.startUidChanges();
+                }
+                final int appId = UserHandle.getAppId(pkgUid);
+                final int N = mActiveUids.size();
+                for (int i=N-1; i>=0; i--) {
+                    final UidRecord uidRec = mActiveUids.valueAt(i);
+                    final long bgTime = uidRec.lastBackgroundTime;
+                    if (bgTime > 0 && !uidRec.idle) {
+                        if (UserHandle.getAppId(uidRec.uid) == appId) {
+                            if (userId == UserHandle.USER_ALL ||
+                                    userId == UserHandle.getUserId(uidRec.uid)) {
+                                uidRec.idle = true;
+                                Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
+                                        + " from package " + packageName + " user " + userId);
+                                doStopUidLocked(uidRec.uid, uidRec);
+                            }
+                        }
+                    }
+                }
+            } finally {
+                if (mLocalPowerManager != null) {
+                    mLocalPowerManager.finishUidChanges();
+                }
+                Binder.restoreCallingIdentity(callingId);
+            }
+        }
+    }
+
     final void idleUids() {
         synchronized (this) {
             final int N = mActiveUids.size();
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index abeea74..52ad72d 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -169,6 +169,8 @@
                     return runKill(pw);
                 case "kill-all":
                     return runKillAll(pw);
+                case "make-idle":
+                    return runMakeIdle(pw);
                 case "monitor":
                     return runMonitor(pw);
                 case "hang":
@@ -205,8 +207,6 @@
                     return runTrackAssociations(pw);
                 case "untrack-associations":
                     return runUntrackAssociations(pw);
-                case "lenient-background-check":
-                    return runLenientBackgroundCheck(pw);
                 case "get-uid-state":
                     return getUidState(pw);
                 case "get-config":
@@ -853,6 +853,22 @@
         return 0;
     }
 
+    int runMakeIdle(PrintWriter pw) throws RemoteException {
+        int userId = UserHandle.USER_ALL;
+
+        String opt;
+        while ((opt = getNextOption()) != null) {
+            if (opt.equals("--user")) {
+                userId = UserHandle.parseUserArg(getNextArgRequired());
+            } else {
+                getErrPrintWriter().println("Error: Unknown option: " + opt);
+                return -1;
+            }
+        }
+        mInterface.makePackageIdle(getNextArgRequired(), userId);
+        return 0;
+    }
+
     static final class MyActivityController extends IActivityController.Stub {
         final IActivityManager mInterface;
         final PrintWriter mPw;
@@ -1432,22 +1448,6 @@
         return 0;
     }
 
-    int runLenientBackgroundCheck(PrintWriter pw) throws RemoteException {
-        String arg = getNextArg();
-        if (arg != null) {
-            boolean state = Boolean.valueOf(arg) || "1".equals(arg);
-            mInterface.setLenientBackgroundCheck(state);
-        }
-        synchronized (mInternal) {
-            if (mInternal.mLenientBackgroundCheck) {
-                pw.println("Lenient background check enabled");
-            } else {
-                pw.println("Lenient background check disabled");
-            }
-        }
-        return 0;
-    }
-
     int getUidState(PrintWriter pw) throws RemoteException {
         mInternal.enforceCallingPermission(android.Manifest.permission.DUMP,
                 "getUidState()");
@@ -2478,8 +2478,6 @@
             pw.println("      Enable association tracking.");
             pw.println("  untrack-associations");
             pw.println("      Disable and clear association tracking.");
-            pw.println("  lenient-background-check [<true|false>]");
-            pw.println("      Optionally controls lenient background check mode, returns current mode.");
             pw.println("  get-uid-state <UID>");
             pw.println("      Gets the process state of an app given its <UID>.");
             pw.println("  attach-agent <PROCESS> <FILE>");
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index 4e69162..8104a43 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -36,7 +36,6 @@
 import android.content.pm.ActivityInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
-import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
@@ -595,8 +594,12 @@
         }
         if (!skip) {
             final int allowed = mService.checkAllowBackgroundLocked(filter.receiverList.uid,
-                    filter.packageName, -1, true);
-            if (allowed == ActivityManager.APP_START_MODE_DISABLED) {
+                    filter.packageName, -1, false);
+            if (false && allowed == ActivityManager.APP_START_MODE_DISABLED) {
+                // XXX should we really not allow this?  It means that while we are
+                // keeping an ephemeral app cached, its registered receivers will stop
+                // receiving broadcasts after it goes idle...  so if it comes back to
+                // the foreground, it won't know what the current state of those broadcasts is.
                 Slog.w(TAG, "Background execution not allowed: receiving "
                         + r.intent
                         + " to " + filter.receiverList.app
@@ -1155,7 +1158,7 @@
             if (!skip) {
                 final int allowed = mService.checkAllowBackgroundLocked(
                         info.activityInfo.applicationInfo.uid, info.activityInfo.packageName, -1,
-                        false);
+                        true);
                 if (allowed != ActivityManager.APP_START_MODE_NORMAL) {
                     // We won't allow this receiver to be launched if the app has been
                     // completely disabled from launches, or it was not explicitly sent
diff --git a/services/core/java/com/android/server/am/UidRecord.java b/services/core/java/com/android/server/am/UidRecord.java
index d24c3a5..d1a15bd 100644
--- a/services/core/java/com/android/server/am/UidRecord.java
+++ b/services/core/java/com/android/server/am/UidRecord.java
@@ -29,6 +29,7 @@
     int curProcState;
     int setProcState = ActivityManager.PROCESS_STATE_NONEXISTENT;
     long lastBackgroundTime;
+    boolean ephemeral;
     boolean idle;
     int numProcs;
 
@@ -43,6 +44,7 @@
         int uid;
         int change;
         int processState;
+        boolean ephemeral;
     }
 
     ChangeItem pendingChange;
@@ -64,6 +66,9 @@
         UserHandle.formatUid(sb, uid);
         sb.append(' ');
         sb.append(ProcessList.makeProcStateString(curProcState));
+        if (ephemeral) {
+            sb.append(" ephemeral");
+        }
         if (lastBackgroundTime > 0) {
             sb.append(" bg:");
             TimeUtils.formatDuration(SystemClock.elapsedRealtime()-lastBackgroundTime, sb);
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
index df64447..b878099 100644
--- a/services/core/java/com/android/server/job/JobSchedulerService.java
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -426,7 +426,7 @@
                                             Slog.d(TAG, "Removing jobs for package " + pkgName
                                                     + " in user " + userId);
                                         }
-                                        cancelJobsForUid(pkgUid, true);
+                                        cancelJobsForUid(pkgUid);
                                     }
                                 } catch (RemoteException|IllegalArgumentException e) {
                                     /*
@@ -455,7 +455,7 @@
                     if (DEBUG) {
                         Slog.d(TAG, "Removing jobs for uid: " + uidRemoved);
                     }
-                    cancelJobsForUid(uidRemoved, true);
+                    cancelJobsForUid(uidRemoved);
                 }
             } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
                 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
@@ -509,15 +509,20 @@
             updateUidState(uid, procState);
         }
 
-        @Override public void onUidGone(int uid) throws RemoteException {
+        @Override public void onUidGone(int uid, boolean disabled) throws RemoteException {
             updateUidState(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
+            if (disabled) {
+                cancelJobsForUid(uid);
+            }
         }
 
         @Override public void onUidActive(int uid) throws RemoteException {
         }
 
-        @Override public void onUidIdle(int uid) throws RemoteException {
-            cancelJobsForUid(uid, false);
+        @Override public void onUidIdle(int uid, boolean disabled) throws RemoteException {
+            if (disabled) {
+                cancelJobsForUid(uid);
+            }
         }
     };
 
@@ -646,26 +651,15 @@
      * This will remove the job from the master list, and cancel the job if it was staged for
      * execution or being executed.
      * @param uid Uid to check against for removal of a job.
-     * @param forceAll If true, all jobs for the uid will be canceled; if false, only those
-     * whose apps are stopped.
+     *
      */
-    public void cancelJobsForUid(int uid, boolean forceAll) {
+    public void cancelJobsForUid(int uid) {
         List<JobStatus> jobsForUid;
         synchronized (mLock) {
             jobsForUid = mJobs.getJobsByUid(uid);
         }
         for (int i=0; i<jobsForUid.size(); i++) {
             JobStatus toRemove = jobsForUid.get(i);
-            if (!forceAll) {
-                String packageName = toRemove.getServiceComponent().getPackageName();
-                try {
-                    if (ActivityManagerNative.getDefault().getAppStartMode(uid, packageName)
-                            != ActivityManager.APP_START_MODE_DISABLED) {
-                        continue;
-                    }
-                } catch (RemoteException e) {
-                }
-            }
             cancelJobImpl(toRemove, null);
         }
     }
@@ -1698,7 +1692,7 @@
 
             long ident = Binder.clearCallingIdentity();
             try {
-                JobSchedulerService.this.cancelJobsForUid(uid, true);
+                JobSchedulerService.this.cancelJobsForUid(uid);
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index fd99f57..c1506b9 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -689,7 +689,7 @@
             }
         }
 
-        @Override public void onUidGone(int uid) throws RemoteException {
+        @Override public void onUidGone(int uid, boolean disabled) throws RemoteException {
             synchronized (mUidRulesFirstLock) {
                 removeUidStateUL(uid);
             }
@@ -698,7 +698,7 @@
         @Override public void onUidActive(int uid) throws RemoteException {
         }
 
-        @Override public void onUidIdle(int uid) throws RemoteException {
+        @Override public void onUidIdle(int uid, boolean disabled) throws RemoteException {
         }
     };
 
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 09b6177..79ef486 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -21257,6 +21257,14 @@
         }
 
         @Override
+        public boolean isPackageEphemeral(int userId, String packageName) {
+            synchronized (mPackages) {
+                PackageParser.Package p = mPackages.get(packageName);
+                return p != null ? p.applicationInfo.isEphemeralApp() : false;
+            }
+        }
+
+        @Override
         public boolean wasPackageEverLaunched(String packageName, int userId) {
             synchronized (mPackages) {
                 return mSettings.wasPackageEverLaunchedLPr(packageName, userId);
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index ad31a32..5a0bee1 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -467,7 +467,7 @@
         }
 
         @Override
-        public void onUidGone(int uid) throws RemoteException {
+        public void onUidGone(int uid, boolean disabled) throws RemoteException {
             handleOnUidStateChanged(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
         }
 
@@ -476,7 +476,7 @@
         }
 
         @Override
-        public void onUidIdle(int uid) throws RemoteException {
+        public void onUidIdle(int uid, boolean disabled) throws RemoteException {
         }
     };