GreedyScheduler will only pick up `WorkRequest`s when running in the default app process.

Test: Added unit tests and ran integration tests.
Fixes: b/138418082
Change-Id: I1fc7a8bf2cb998de5d0629f5b9d29cac1957ad6f
diff --git a/work/workmanager/src/androidTest/java/androidx/work/impl/background/greedy/GreedySchedulerTest.java b/work/workmanager/src/androidTest/java/androidx/work/impl/background/greedy/GreedySchedulerTest.java
index 99d2a83..d79fc01 100644
--- a/work/workmanager/src/androidTest/java/androidx/work/impl/background/greedy/GreedySchedulerTest.java
+++ b/work/workmanager/src/androidTest/java/androidx/work/impl/background/greedy/GreedySchedulerTest.java
@@ -23,6 +23,8 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.content.Context;
+
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SdkSuppress;
 import androidx.test.filters.SmallTest;
@@ -51,6 +53,7 @@
 
     private static final String TEST_ID = "test";
 
+    private Context mContext;
     private WorkManagerImpl mWorkManagerImpl;
     private Processor mMockProcessor;
     private WorkConstraintsTracker mMockWorkConstraintsTracker;
@@ -58,13 +61,17 @@
 
     @Before
     public void setUp() {
+        mContext = mock(Context.class);
         TaskExecutor taskExecutor = mock(TaskExecutor.class);
         mWorkManagerImpl = mock(WorkManagerImpl.class);
         mMockProcessor = mock(Processor.class);
         mMockWorkConstraintsTracker = mock(WorkConstraintsTracker.class);
         when(mWorkManagerImpl.getProcessor()).thenReturn(mMockProcessor);
         when(mWorkManagerImpl.getWorkTaskExecutor()).thenReturn(taskExecutor);
-        mGreedyScheduler = new GreedyScheduler(mWorkManagerImpl, mMockWorkConstraintsTracker);
+        mGreedyScheduler = new GreedyScheduler(
+                mContext,
+                mWorkManagerImpl,
+                mMockWorkConstraintsTracker);
     }
 
     @Test
@@ -168,4 +175,16 @@
         }
         verify(mMockProcessor, times(1)).addExecutionListener(mGreedyScheduler);
     }
+
+    @Test
+    @SmallTest
+    public void testGreedyScheduler_ignoresRequestsInADifferentProcess() {
+        // Context.getSystemService() returns null so no work should be executed.
+        when(mContext.getPackageName()).thenReturn("packageName");
+        OneTimeWorkRequest work = new OneTimeWorkRequest.Builder(TestWorker.class).build();
+        WorkSpec workSpec = getWorkSpec(work);
+        mGreedyScheduler.schedule(workSpec);
+        verify(mMockProcessor, times(0)).addExecutionListener(mGreedyScheduler);
+        verify(mMockWorkConstraintsTracker, never()).replace(ArgumentMatchers.<WorkSpec>anyList());
+    }
 }
diff --git a/work/workmanager/src/main/java/androidx/work/impl/background/greedy/GreedyScheduler.java b/work/workmanager/src/main/java/androidx/work/impl/background/greedy/GreedyScheduler.java
index c54c6f9..47c6005 100644
--- a/work/workmanager/src/main/java/androidx/work/impl/background/greedy/GreedyScheduler.java
+++ b/work/workmanager/src/main/java/androidx/work/impl/background/greedy/GreedyScheduler.java
@@ -16,12 +16,16 @@
 
 package androidx.work.impl.background.greedy;
 
+import static android.content.Context.ACTIVITY_SERVICE;
 import static android.os.Build.VERSION.SDK_INT;
 
+import android.app.ActivityManager;
 import android.content.Context;
+import android.os.Process;
 import android.text.TextUtils;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.annotation.RestrictTo;
 import androidx.annotation.VisibleForTesting;
 import androidx.work.Logger;
@@ -49,31 +53,50 @@
 
     private static final String TAG = Logger.tagWithPrefix("GreedyScheduler");
 
-    private WorkManagerImpl mWorkManagerImpl;
-    private WorkConstraintsTracker mWorkConstraintsTracker;
+    private final Context mContext;
+    private final WorkManagerImpl mWorkManagerImpl;
+    private final WorkConstraintsTracker mWorkConstraintsTracker;
     private List<WorkSpec> mConstrainedWorkSpecs = new ArrayList<>();
     private boolean mRegisteredExecutionListener;
     private final Object mLock;
 
-    public GreedyScheduler(Context context,
-            TaskExecutor taskExecutor,
-            WorkManagerImpl workManagerImpl) {
+    // Internal State
+    private String mProcessName;
 
+    public GreedyScheduler(
+            @NonNull Context context,
+            @NonNull TaskExecutor taskExecutor,
+            @NonNull WorkManagerImpl workManagerImpl) {
+        mContext = context;
         mWorkManagerImpl = workManagerImpl;
         mWorkConstraintsTracker = new WorkConstraintsTracker(context, taskExecutor, this);
         mLock = new Object();
+        mProcessName = getProcessName();
     }
 
     @VisibleForTesting
-    public GreedyScheduler(WorkManagerImpl workManagerImpl,
-            WorkConstraintsTracker workConstraintsTracker) {
+    public GreedyScheduler(
+            @NonNull Context context,
+            @NonNull WorkManagerImpl workManagerImpl,
+            @NonNull WorkConstraintsTracker workConstraintsTracker) {
+        mContext = context;
         mWorkManagerImpl = workManagerImpl;
         mWorkConstraintsTracker = workConstraintsTracker;
         mLock = new Object();
+        mProcessName = getProcessName();
     }
 
     @Override
     public void schedule(@NonNull WorkSpec... workSpecs) {
+        // Package name is the default process name
+        if (!TextUtils.equals(mContext.getPackageName(), mProcessName)) {
+            Logger.get().info(
+                    TAG,
+                    String.format("Ignoring schedule request (Running in process %s)", mProcessName)
+            );
+            return;
+        }
+
         registerExecutionListenerIfNeeded();
 
         // Keep track of the list of new WorkSpecs whose constraints need to be tracked.
@@ -82,7 +105,7 @@
         // are updating mConstrainedWorkSpecs.
         List<WorkSpec> constrainedWorkSpecs = new ArrayList<>();
         List<String> constrainedWorkSpecIds = new ArrayList<>();
-        for (WorkSpec workSpec: workSpecs) {
+        for (WorkSpec workSpec : workSpecs) {
             if (workSpec.state == WorkInfo.State.ENQUEUED
                     && !workSpec.isPeriodic()
                     && workSpec.initialDelay == 0L
@@ -177,4 +200,24 @@
             mRegisteredExecutionListener = true;
         }
     }
+
+    @Nullable
+    private String getProcessName() {
+        int pid = Process.myPid();
+        ActivityManager am =
+                (ActivityManager) mContext.getSystemService(ACTIVITY_SERVICE);
+
+        if (am != null) {
+            List<ActivityManager.RunningAppProcessInfo> processes = am.getRunningAppProcesses();
+            if (processes != null && !processes.isEmpty()) {
+                for (ActivityManager.RunningAppProcessInfo process : processes) {
+                    if (process.pid == pid) {
+                        return process.processName;
+                    }
+                }
+            }
+        }
+
+        return null;
+    }
 }