Add null check to updateHasAboveClientLocked

The same-process check in updateHasAboveClientLocked (see aosp/2577299)
was missing a null check: service's ProcessRecord is not guaranteed to
be set, for example if the client unbinds before the process hosting the
service is even started.

Test: atest MockingOomAdjusterTests
Change-Id: I220d9d1309cfc33316308bf805f4e34a0806a35d
Merged-In: Iee5024b8f13771bc98a39a20e5f96a89a4c79b4e
Merged-In: Id5aee1323b9b3b254e19e8a4e189c1fa4f9d96ea
diff --git a/services/core/java/com/android/server/am/ProcessServiceRecord.java b/services/core/java/com/android/server/am/ProcessServiceRecord.java
index 7ff6d11..1420671 100644
--- a/services/core/java/com/android/server/am/ProcessServiceRecord.java
+++ b/services/core/java/com/android/server/am/ProcessServiceRecord.java
@@ -341,8 +341,10 @@
         mHasAboveClient = false;
         for (int i = mConnections.size() - 1; i >= 0; i--) {
             ConnectionRecord cr = mConnections.valueAt(i);
-            if (cr.binding.service.app.mServices != this
-                    && cr.hasFlag(Context.BIND_ABOVE_CLIENT)) {
+
+            final boolean isSameProcess = cr.binding.service.app != null
+                    && cr.binding.service.app.mServices == this;
+            if (!isSameProcess && cr.hasFlag(Context.BIND_ABOVE_CLIENT)) {
                 mHasAboveClient = true;
                 break;
             }
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
index 0504344..732d0ce 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
@@ -2578,6 +2578,31 @@
         assertTrue(CACHED_APP_MAX_ADJ >= app3.mState.getSetAdj());
     }
 
+    @SuppressWarnings("GuardedBy")
+    @Test
+    public void testUpdateOomAdj_DoOne_AboveClient_NotStarted() {
+        ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
+                MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true));
+        doReturn(PROCESS_STATE_TOP).when(sService.mAtmInternal).getTopProcessState();
+        doReturn(app).when(sService).getTopApp();
+        sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
+        sService.mOomAdjuster.updateOomAdjLocked(app, OOM_ADJ_REASON_NONE);
+
+        assertEquals(FOREGROUND_APP_ADJ, app.mState.getSetAdj());
+
+        // Start binding to a service that isn't running yet.
+        ServiceRecord sr = makeServiceRecord(app);
+        sr.app = null;
+        bindService(null, app, sr, Context.BIND_ABOVE_CLIENT, mock(IBinder.class));
+
+        // Since sr.app is null, this service cannot be in the same process as the
+        // client so we expect the BIND_ABOVE_CLIENT adjustment to take effect.
+        app.mServices.updateHasAboveClientLocked();
+        sService.mOomAdjuster.updateOomAdjLocked(app, OOM_ADJ_REASON_NONE);
+        assertTrue(app.mServices.hasAboveClient());
+        assertNotEquals(FOREGROUND_APP_ADJ, app.mState.getSetAdj());
+    }
+
     private ProcessRecord makeDefaultProcessRecord(int pid, int uid, String processName,
             String packageName, boolean hasShownUi) {
         long now = SystemClock.uptimeMillis();