Fixed
Status Update
Comments
ra...@google.com <ra...@google.com> #2
Project: platform/frameworks/support
Branch: androidx-master-dev
commit b90079595f33f58fece04026a97faa0d243acdb1
Author: Yuichi Araki <yaraki@google.com>
Date: Wed Sep 18 16:55:49 2019
Change the way to detect mismatch between POJO and query
This fixes cursor mismatch warnings with expandProjection.
Bug: 140759491
Test: QueryMethodProcessorTest
Change-Id: I7659002e5e0d1ef60fc1af2a625c0c36da0664d8
M room/compiler/src/main/kotlin/androidx/room/processor/QueryMethodProcessor.kt
M room/compiler/src/main/kotlin/androidx/room/solver/TypeAdapterStore.kt
M room/compiler/src/main/kotlin/androidx/room/solver/query/result/PojoRowAdapter.kt
M room/compiler/src/test/kotlin/androidx/room/processor/QueryMethodProcessorTest.kt
M room/compiler/src/test/kotlin/androidx/room/testing/TestProcessor.kt
https://android-review.googlesource.com/1123258
https://goto.google.com/android-sha1/b90079595f33f58fece04026a97faa0d243acdb1
Branch: androidx-master-dev
commit b90079595f33f58fece04026a97faa0d243acdb1
Author: Yuichi Araki <yaraki@google.com>
Date: Wed Sep 18 16:55:49 2019
Change the way to detect mismatch between POJO and query
This fixes cursor mismatch warnings with expandProjection.
Bug: 140759491
Test: QueryMethodProcessorTest
Change-Id: I7659002e5e0d1ef60fc1af2a625c0c36da0664d8
M room/compiler/src/main/kotlin/androidx/room/processor/QueryMethodProcessor.kt
M room/compiler/src/main/kotlin/androidx/room/solver/TypeAdapterStore.kt
M room/compiler/src/main/kotlin/androidx/room/solver/query/result/PojoRowAdapter.kt
M room/compiler/src/test/kotlin/androidx/room/processor/QueryMethodProcessorTest.kt
M room/compiler/src/test/kotlin/androidx/room/testing/TestProcessor.kt
ra...@google.com <ra...@google.com> #3
ar...@gmail.com <ar...@gmail.com> #4
Project: platform/frameworks/support
Branch: androidx-master-dev
commit bdde5a1a970ddc9007b28de4aa29d60ffa588f08
Author: Yigit Boyar <yboyar@google.com>
Date: Thu Apr 16 16:47:05 2020
Re-factor how errors are dismissed when query is re-written
This CL changes how we handle errors/warnings if query is
re-written.
There was a bug in expandProjection where we would report warnings
for things that Room already fixes automatically ( b/140759491 ).
The solution to that problem (I7659002e5e0d1ef60fc1af2a625c0c36da0664d8)
solved it by deferring validating of columns until after re-write
decision is made. Unfortunately, this required changing PojoRowAdapter
to have a dummy mapping until it is validating, make it hard to use
as it does have a non-null mapping which is not useful.
This CL partially reverts that change and instead rely on the log
deferring logic we have in Context. This way, we don't need to break
the stability of PojoRowAdapter while still having the ability to
drop warnings that room fixes. This will also play nicer when we
have different query re-writing options that can use more information
about the query results.
Bug: 153387066
Bug: 140759491
Test: existing tests pass
Change-Id: I2ec967c763d33d7a3ff02c1a13c6953b460d1e5f
M room/compiler/src/main/kotlin/androidx/room/log/RLog.kt
M room/compiler/src/main/kotlin/androidx/room/processor/QueryMethodProcessor.kt
M room/compiler/src/main/kotlin/androidx/room/solver/TypeAdapterStore.kt
M room/compiler/src/main/kotlin/androidx/room/solver/query/result/PojoRowAdapter.kt
https://android-review.googlesource.com/1288456
Branch: androidx-master-dev
commit bdde5a1a970ddc9007b28de4aa29d60ffa588f08
Author: Yigit Boyar <yboyar@google.com>
Date: Thu Apr 16 16:47:05 2020
Re-factor how errors are dismissed when query is re-written
This CL changes how we handle errors/warnings if query is
re-written.
There was a bug in expandProjection where we would report warnings
for things that Room already fixes automatically (
The solution to that problem (I7659002e5e0d1ef60fc1af2a625c0c36da0664d8)
solved it by deferring validating of columns until after re-write
decision is made. Unfortunately, this required changing PojoRowAdapter
to have a dummy mapping until it is validating, make it hard to use
as it does have a non-null mapping which is not useful.
This CL partially reverts that change and instead rely on the log
deferring logic we have in Context. This way, we don't need to break
the stability of PojoRowAdapter while still having the ability to
drop warnings that room fixes. This will also play nicer when we
have different query re-writing options that can use more information
about the query results.
Bug: 153387066
Bug: 140759491
Test: existing tests pass
Change-Id: I2ec967c763d33d7a3ff02c1a13c6953b460d1e5f
M room/compiler/src/main/kotlin/androidx/room/log/RLog.kt
M room/compiler/src/main/kotlin/androidx/room/processor/QueryMethodProcessor.kt
M room/compiler/src/main/kotlin/androidx/room/solver/TypeAdapterStore.kt
M room/compiler/src/main/kotlin/androidx/room/solver/query/result/PojoRowAdapter.kt
ra...@google.com <ra...@google.com> #5
beta03 is out.
en...@gmail.com <en...@gmail.com> #6
In beta03, the bug seems fixed when JobScheduler backend is used.
But the bug seems to remain when AlarmManager backend is used.
The following step-by-step fails for me on emulator "Nexus 7 (2012) API 22", but passes on emulator "Pixel 2 XL API 27".
STEP BY STEP:
1. Create a "Hello world" Android app using Android Studio wizard and add implementation("android.arch.work:work-runtime:1.0.0-beta03") to dependencies
2. Add the following to MainActivity.onCreate():
final String name = Long.toString(System.currentTimeMillis()); // To ensure fresh name each run
final OneTimeWorkRequest workRequest = new OneTimeWorkRequest.Builder(LogPrinter.class)
.setBackoffCriteria(BackoffPolicy.LINEAR, WorkRequest.MIN_BACKOFF_MILLIS, TimeUnit.MILLISECONDS)
.addTag(name)
.build();
Log.e("Repro", "Calling enqueueUniqueWork(" + name + ", ...)");
WorkManager.getInstance().enqueueUniqueWork(name, ExistingWorkPolicy.REPLACE, workRequest);
where LogPrinter.class doWork() is:
@NonNull
@Override
public Result doWork() {
Log.e("Repro", "doWork() called. Now swipe away app in App Switcher. Tags: " + getTags());
SystemClock.sleep(10000);
Log.e("Repro", "Too late, try again. Tags: " + getTags());
return Result.success();
}
3. Run the app and check adb logcat -s Repro
4. When you see "Now swipe away app in App Switcher", do that.
EXPECTED:
You should see "doWork() called ..." again after max 10 seconds (due to specified backoff time), since the WorkManager framework should ensure that the Worker that never was finished gets a chance to run again.
ACTUAL:
On API 22, you never see "doWork() called ..." again (Test fails).
On API 27, you do see "doWork() called ..." again (Test pass).
Let me know if you need more input.
Best regards,
Martin Nordholts
But the bug seems to remain when AlarmManager backend is used.
The following step-by-step fails for me on emulator "Nexus 7 (2012) API 22", but passes on emulator "Pixel 2 XL API 27".
STEP BY STEP:
1. Create a "Hello world" Android app using Android Studio wizard and add implementation("android.arch.work:work-runtime:1.0.0-beta03") to dependencies
2. Add the following to MainActivity.onCreate():
final String name = Long.toString(System.currentTimeMillis()); // To ensure fresh name each run
final OneTimeWorkRequest workRequest = new OneTimeWorkRequest.Builder(LogPrinter.class)
.setBackoffCriteria(BackoffPolicy.LINEAR, WorkRequest.MIN_BACKOFF_MILLIS, TimeUnit.MILLISECONDS)
.addTag(name)
.build();
Log.e("Repro", "Calling enqueueUniqueWork(" + name + ", ...)");
WorkManager.getInstance().enqueueUniqueWork(name, ExistingWorkPolicy.REPLACE, workRequest);
where LogPrinter.class doWork() is:
@NonNull
@Override
public Result doWork() {
Log.e("Repro", "doWork() called. Now swipe away app in App Switcher. Tags: " + getTags());
SystemClock.sleep(10000);
Log.e("Repro", "Too late, try again. Tags: " + getTags());
return Result.success();
}
3. Run the app and check adb logcat -s Repro
4. When you see "Now swipe away app in App Switcher", do that.
EXPECTED:
You should see "doWork() called ..." again after max 10 seconds (due to specified backoff time), since the WorkManager framework should ensure that the Worker that never was finished gets a chance to run again.
ACTUAL:
On API 22, you never see "doWork() called ..." again (Test fails).
On API 27, you do see "doWork() called ..." again (Test pass).
Let me know if you need more input.
Best regards,
Martin Nordholts
ra...@google.com <ra...@google.com> #7
When a swipe to dismiss happens you should see a message in logcat which looks like:
W/ActivityManager( 1532): Scheduling restart of crashed service androidx.work.integration.testapp/androidx.work.impl.background.systemalarm.SystemAlarmService in 47470ms
Service crashes are different from Worker retries or backoffs. So you won't see it in 10 seconds. It might take longer. Look at the logs for more info.
W/ActivityManager( 1532): Scheduling restart of crashed service androidx.work.integration.testapp/androidx.work.impl.background.systemalarm.SystemAlarmService in 47470ms
Service crashes are different from Worker retries or backoffs. So you won't see it in 10 seconds. It might take longer. Look at the logs for more info.
en...@gmail.com <en...@gmail.com> #8
Thanks for the tip, this helped me debug this further.
Turns out that if you see "Scheduling restart of crashed service", then yes, doWork() will be called after the specified time.
But the problem is that SystemAlarmService is not always scheduled to restart, because SystemAlarmService is not always running when the app is closed.
In fact, it seems to be quite rare for SystemAlarmService to run.
If you increase the sleep from 10000 to 20000 in my step-by-step instructions, and let 10 seconds pass between ""doWork() called .., " being logged and you closing the app, I think you'll be able to reproduce the problem, namely that doWork() never becomes called again (since SystemAlarmService is not scheduled for a restart, since it wasn't running when the app was closed).
Are you able to reproduce the problem with these extra instructions?
Turns out that if you see "Scheduling restart of crashed service", then yes, doWork() will be called after the specified time.
But the problem is that SystemAlarmService is not always scheduled to restart, because SystemAlarmService is not always running when the app is closed.
In fact, it seems to be quite rare for SystemAlarmService to run.
If you increase the sleep from 10000 to 20000 in my step-by-step instructions, and let 10 seconds pass between ""doWork() called .., " being logged and you closing the app, I think you'll be able to reproduce the problem, namely that doWork() never becomes called again (since SystemAlarmService is not scheduled for a restart, since it wasn't running when the app was closed).
Are you able to reproduce the problem with these extra instructions?
ra...@google.com <ra...@google.com> #9
Can you please turn on verbose logging and send us all the logs ? I am going to try and reproduce this on my end.
You will need to initialize WorkManager with a custom configuration for that.
* Remove the default WorkManager initializer using:
<provider
android:name="androidx.work.impl.WorkManagerInitializer"
android:authorities="${applicationId}.workmanager-init"
tools:node="remove"/>
* Initialize WorkManager in your own content provider or Application#onCreate() with a custom configuration
WorkManager.initialize(
applicationContext,
new Configuration.Builder().setMinimumLoggingLevel(Log.VERBOSE).build());
You will see a lot more WorkManager logs now.
You will need to initialize WorkManager with a custom configuration for that.
* Remove the default WorkManager initializer using:
<provider
android:name="androidx.work.impl.WorkManagerInitializer"
android:authorities="${applicationId}.workmanager-init"
tools:node="remove"/>
* Initialize WorkManager in your own content provider or Application#onCreate() with a custom configuration
WorkManager.initialize(
applicationContext,
new Configuration.Builder().setMinimumLoggingLevel(Log.VERBOSE).build());
You will see a lot more WorkManager logs now.
ra...@google.com <ra...@google.com> #10
I think I know what is going on. There are 2 competing schedulers that can pick up work. When the in-process scheduler picks up work and the process gets killed there is nothing else that can wake up to reschedule that Worker until the application is launched again.
en...@gmail.com <en...@gmail.com> #11
Thanks for looking into this more.
I've attached the logs I captured when reproducing the problem as follows:
1. Create a brand new Nexus 7 (2012) API 22 emulator to make sure the system does not have any old state that affects behavior, and start it, and let it boot up and rest a bit. Double-check that in Settings -> Storage, it doesn't say "running out of storage". If it does say that, reboot the emulator. That should get rid of the message. If you try to install the app when the device is in its strange "running out of storage state", you will get "stale dex" errors when installing the app. I'm using the x86 emulator on a 2018 MacBook Pro.
2. Start log capturing with this command: adb -s emulator-5554 logcat -T 0 -v threadtime -s '*:V' | tee ~/log-workmanager-repro-verbose-3.txt
3. Start the app, and after ~10 seconds, close it (I've increased sleep to 20 s)
4. Wait for a long enough time to convince yourself of that the Worker will never be scheduled again (I waited for > 10 minutes)
5. Stop logging.
For your convenience, I have inlined the log filtered with: grep -e Repro -e WM- -e Killing.*workmanager ~/log-workmanager-repro-verbose-3.txt
at the end of the mail. For full logs, see attached file.
The last line with 'Killing' is from me swiping away the app in the App Switcher.
Note that the logs have this line:
WM-SystemAlarmService: All commands completed in dispatcher
So it looks like even though SystemAlarmService was used to dispatch the Worker, the bug happened. ("All commands completed in dispatcher" means SystemAlarmService is about to do Service.stopSelf() as you probably know.)
Let me know if I can help you in any other way.
BR Martin
01-30 09:42:31.954 3613 3613 D WM-Schedulers: Created SystemAlarmScheduler
01-30 09:42:31.960 3613 3613 D WM-PackageManagerHelper: androidx.work.impl.background.systemalarm.SystemAlarmService enabled
01-30 09:42:31.970 3613 3632 D WM-ForceStopRunnable: Application was force-stopped, rescheduling.
01-30 09:42:31.993 3613 3613 E Repro : Calling enqueueUniqueWork(1548837751988, ...)
01-30 09:42:32.040 3613 3632 D WM-PackageManagerHelper: androidx.work.impl.background.systemalarm.RescheduleReceiver enabled
01-30 09:42:32.043 3613 3632 D WM-SystemAlarmScheduler: Scheduling work with workSpecId 576d2452-a559-4c85-b217-c954c6905d7e
01-30 09:42:32.046 3613 3632 D WM-Processor: Processor: processing 576d2452-a559-4c85-b217-c954c6905d7e
01-30 09:42:32.054 3613 3613 D WM-SystemAlarmDispatche: Adding command Intent { act=ACTION_SCHEDULE_WORK cmp=com.github.enselic.workmanagerfailedscheduling/androidx.work.impl.background.systemalarm.SystemAlarmService (has extras) } (1)
01-30 09:42:32.055 3613 3632 D WM-SystemAlarmDispatche: Processing command Intent { act=ACTION_SCHEDULE_WORK cmp=com.github.enselic.workmanagerfailedscheduling/androidx.work.impl.background.systemalarm.SystemAlarmService (has extras) }, 1
01-30 09:42:32.055 3613 3632 D WM-SystemAlarmDispatche: Acquiring operation wake lock (ACTION_SCHEDULE_WORK) WakeLock{4e8f358 held=false, refCount=0}
01-30 09:42:32.055 3613 3632 D WM-CommandHandler: Handling schedule work for 576d2452-a559-4c85-b217-c954c6905d7e
01-30 09:42:32.056 3613 3637 E Repro : doWork() called. Now swipe away app in App Switcher. Tags: [com.github.enselic.workmanagerfailedscheduling.LogPrinter, 1548837751988]
01-30 09:42:32.056 3613 3632 W WM-CommandHandler: Skipping scheduling 576d2452-a559-4c85-b217-c954c6905d7e because it is no longer enqueued
01-30 09:42:32.056 3613 3632 D WM-SystemAlarmDispatche: Releasing operation wake lock (ACTION_SCHEDULE_WORK) WakeLock{4e8f358 held=true, refCount=1}
01-30 09:42:32.096 3613 3613 D WM-SystemAlarmDispatche: Checking if commands are complete.
01-30 09:42:32.096 3613 3613 D WM-SystemAlarmDispatche: Removing command Intent { act=ACTION_SCHEDULE_WORK cmp=com.github.enselic.workmanagerfailedscheduling/androidx.work.impl.background.systemalarm.SystemAlarmService (has extras) }
01-30 09:42:32.096 3613 3613 D WM-SystemAlarmDispatche: No more commands & intents.
01-30 09:42:32.096 3613 3613 D WM-SystemAlarmService: All commands completed in dispatcher
01-30 09:42:43.607 1647 2397 I ActivityManager: Killing 3613:com.github.enselic.workmanagerfailedscheduling/u0a58 (adj 9): remove task
I've attached the logs I captured when reproducing the problem as follows:
1. Create a brand new Nexus 7 (2012) API 22 emulator to make sure the system does not have any old state that affects behavior, and start it, and let it boot up and rest a bit. Double-check that in Settings -> Storage, it doesn't say "running out of storage". If it does say that, reboot the emulator. That should get rid of the message. If you try to install the app when the device is in its strange "running out of storage state", you will get "stale dex" errors when installing the app. I'm using the x86 emulator on a 2018 MacBook Pro.
2. Start log capturing with this command: adb -s emulator-5554 logcat -T 0 -v threadtime -s '*:V' | tee ~/log-workmanager-repro-verbose-3.txt
3. Start the app, and after ~10 seconds, close it (I've increased sleep to 20 s)
4. Wait for a long enough time to convince yourself of that the Worker will never be scheduled again (I waited for > 10 minutes)
5. Stop logging.
For your convenience, I have inlined the log filtered with: grep -e Repro -e WM- -e Killing.*workmanager ~/log-workmanager-repro-verbose-3.txt
at the end of the mail. For full logs, see attached file.
The last line with 'Killing' is from me swiping away the app in the App Switcher.
Note that the logs have this line:
WM-SystemAlarmService: All commands completed in dispatcher
So it looks like even though SystemAlarmService was used to dispatch the Worker, the bug happened. ("All commands completed in dispatcher" means SystemAlarmService is about to do Service.stopSelf() as you probably know.)
Let me know if I can help you in any other way.
BR Martin
01-30 09:42:31.954 3613 3613 D WM-Schedulers: Created SystemAlarmScheduler
01-30 09:42:31.960 3613 3613 D WM-PackageManagerHelper: androidx.work.impl.background.systemalarm.SystemAlarmService enabled
01-30 09:42:31.970 3613 3632 D WM-ForceStopRunnable: Application was force-stopped, rescheduling.
01-30 09:42:31.993 3613 3613 E Repro : Calling enqueueUniqueWork(1548837751988, ...)
01-30 09:42:32.040 3613 3632 D WM-PackageManagerHelper: androidx.work.impl.background.systemalarm.RescheduleReceiver enabled
01-30 09:42:32.043 3613 3632 D WM-SystemAlarmScheduler: Scheduling work with workSpecId 576d2452-a559-4c85-b217-c954c6905d7e
01-30 09:42:32.046 3613 3632 D WM-Processor: Processor: processing 576d2452-a559-4c85-b217-c954c6905d7e
01-30 09:42:32.054 3613 3613 D WM-SystemAlarmDispatche: Adding command Intent { act=ACTION_SCHEDULE_WORK cmp=com.github.enselic.workmanagerfailedscheduling/androidx.work.impl.background.systemalarm.SystemAlarmService (has extras) } (1)
01-30 09:42:32.055 3613 3632 D WM-SystemAlarmDispatche: Processing command Intent { act=ACTION_SCHEDULE_WORK cmp=com.github.enselic.workmanagerfailedscheduling/androidx.work.impl.background.systemalarm.SystemAlarmService (has extras) }, 1
01-30 09:42:32.055 3613 3632 D WM-SystemAlarmDispatche: Acquiring operation wake lock (ACTION_SCHEDULE_WORK) WakeLock{4e8f358 held=false, refCount=0}
01-30 09:42:32.055 3613 3632 D WM-CommandHandler: Handling schedule work for 576d2452-a559-4c85-b217-c954c6905d7e
01-30 09:42:32.056 3613 3637 E Repro : doWork() called. Now swipe away app in App Switcher. Tags: [com.github.enselic.workmanagerfailedscheduling.LogPrinter, 1548837751988]
01-30 09:42:32.056 3613 3632 W WM-CommandHandler: Skipping scheduling 576d2452-a559-4c85-b217-c954c6905d7e because it is no longer enqueued
01-30 09:42:32.056 3613 3632 D WM-SystemAlarmDispatche: Releasing operation wake lock (ACTION_SCHEDULE_WORK) WakeLock{4e8f358 held=true, refCount=1}
01-30 09:42:32.096 3613 3613 D WM-SystemAlarmDispatche: Checking if commands are complete.
01-30 09:42:32.096 3613 3613 D WM-SystemAlarmDispatche: Removing command Intent { act=ACTION_SCHEDULE_WORK cmp=com.github.enselic.workmanagerfailedscheduling/androidx.work.impl.background.systemalarm.SystemAlarmService (has extras) }
01-30 09:42:32.096 3613 3613 D WM-SystemAlarmDispatche: No more commands & intents.
01-30 09:42:32.096 3613 3613 D WM-SystemAlarmService: All commands completed in dispatcher
01-30 09:42:43.607 1647 2397 I ActivityManager: Killing 3613:com.github.enselic.workmanagerfailedscheduling/u0a58 (adj 9): remove task
ra...@google.com <ra...@google.com> #12
Thanks for providing more information.. This is in line with a fix that I am working on. This should be fixed in the next beta.
https://android-review.googlesource.com/c/platform/frameworks/support/+/889837
ap...@google.com <ap...@google.com> #13
Project: platform/frameworks/support
Branch: androidx-master-dev
commit ebb4f87d732f66d01d1a4cf362bb11a815e80b74
Author: Rahul Ravikumar <rahulrav@google.com>
Date: Tue Jan 29 16:16:17 2019
Correctly retry work on process death when using AlarmManager based implementation.
* AlarmManager now schedules a Worker unless the WorkSpec#isFinished() is true.
* When AlarmManager gets worken up by ActivityManager to resume processing, we
correctly execute the Worker after a backoff period.
* We now correctly handle rescheduling in DelayMetCommandHandler. Previously the
only reason why this worked before was the call to Schedulers.schedule() in
WorkerWrapper inside the onWorkFinished() method.
* When delaying execution of Workers in WorkerWrapper we always reschedule givem
SystemJobScheduler does not schedule jobs where JobScheduler is already aware
of the jobId.
* Added a lot more logging in GreedyScheduler, SystemJobScheduler and SystemAlarmScheduler
to make debugging easier.
* Ran a lot of integration tests on API 22, 23 (double scheduling) and 28.
Look athttps://paste.googleplex.com/5709211287683072?raw
for more information. I also ran integration tests that cancel
workers to sanity check.
Fixes: b/123329850
Test: Added additional test cases in SystemAlarmDispatcherTest.
Change-Id: I1bcff1ebf5f60928a02e3e94e2e6ccaed0de47b1
M work/integration-tests/testapp/src/main/java/androidx/work/integration/testapp/MainActivity.java
A work/integration-tests/testapp/src/main/java/androidx/work/integration/testapp/RetryWorker.java
M work/integration-tests/testapp/src/main/res/layout/activity_main.xml
M work/integration-tests/testapp/src/main/res/values/strings.xml
M work/workmanager/src/androidTest/java/androidx/work/impl/WorkerWrapperTest.java
M work/workmanager/src/androidTest/java/androidx/work/impl/background/systemalarm/SystemAlarmDispatcherTest.java
M work/workmanager/src/main/java/androidx/work/impl/WorkerWrapper.java
M work/workmanager/src/main/java/androidx/work/impl/background/greedy/GreedyScheduler.java
M work/workmanager/src/main/java/androidx/work/impl/background/systemalarm/CommandHandler.java
M work/workmanager/src/main/java/androidx/work/impl/background/systemalarm/DelayMetCommandHandler.java
M work/workmanager/src/main/java/androidx/work/impl/background/systemjob/SystemJobScheduler.java
https://android-review.googlesource.com/889837
https://goto.google.com/android-sha1/ebb4f87d732f66d01d1a4cf362bb11a815e80b74
Branch: androidx-master-dev
commit ebb4f87d732f66d01d1a4cf362bb11a815e80b74
Author: Rahul Ravikumar <rahulrav@google.com>
Date: Tue Jan 29 16:16:17 2019
Correctly retry work on process death when using AlarmManager based implementation.
* AlarmManager now schedules a Worker unless the WorkSpec#isFinished() is true.
* When AlarmManager gets worken up by ActivityManager to resume processing, we
correctly execute the Worker after a backoff period.
* We now correctly handle rescheduling in DelayMetCommandHandler. Previously the
only reason why this worked before was the call to Schedulers.schedule() in
WorkerWrapper inside the onWorkFinished() method.
* When delaying execution of Workers in WorkerWrapper we always reschedule givem
SystemJobScheduler does not schedule jobs where JobScheduler is already aware
of the jobId.
* Added a lot more logging in GreedyScheduler, SystemJobScheduler and SystemAlarmScheduler
to make debugging easier.
* Ran a lot of integration tests on API 22, 23 (double scheduling) and 28.
Look at
for more information. I also ran integration tests that cancel
workers to sanity check.
Fixes:
Test: Added additional test cases in SystemAlarmDispatcherTest.
Change-Id: I1bcff1ebf5f60928a02e3e94e2e6ccaed0de47b1
M work/integration-tests/testapp/src/main/java/androidx/work/integration/testapp/MainActivity.java
A work/integration-tests/testapp/src/main/java/androidx/work/integration/testapp/RetryWorker.java
M work/integration-tests/testapp/src/main/res/layout/activity_main.xml
M work/integration-tests/testapp/src/main/res/values/strings.xml
M work/workmanager/src/androidTest/java/androidx/work/impl/WorkerWrapperTest.java
M work/workmanager/src/androidTest/java/androidx/work/impl/background/systemalarm/SystemAlarmDispatcherTest.java
M work/workmanager/src/main/java/androidx/work/impl/WorkerWrapper.java
M work/workmanager/src/main/java/androidx/work/impl/background/greedy/GreedyScheduler.java
M work/workmanager/src/main/java/androidx/work/impl/background/systemalarm/CommandHandler.java
M work/workmanager/src/main/java/androidx/work/impl/background/systemalarm/DelayMetCommandHandler.java
M work/workmanager/src/main/java/androidx/work/impl/background/systemjob/SystemJobScheduler.java
Description
Version used: 1.0.0-beta02
Devices/Android versions reproduced on: Pixel/Pie, Pixel2/Pie, Pixel3/Pie, Motorola Moto-G/Lollipop
Steps to reproduce:
Create a OneTimeWorkRequest like below, while it's running, close the app from app drawer. The first assumption that the enqueued task will run in background even when the app is closed is not true (Task is not started again even after an hour). Also the enqueued OneTimeWorkRequest won't start again on next app launch and stays in ENQUEUED state indefinitely.
private void startTestWork() {
Constraints testConstraints = new Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.setRequiresBatteryNotLow(true)
.build();
isMyWorkerRunning(TEST_WORKER_TAG);
OneTimeWorkRequest testOneTimeWorkRequest = new OneTimeWorkRequest
.Builder(TestWorker.class)
.addTag(TEST_WORKER_TAG)
.setInitialDelay(0, TimeUnit.SECONDS)
.setConstraints(testConstraints)
.build();
WorkManager.getInstance().enqueueUniqueWork(TEST_WORKER_TAG, ExistingWorkPolicy.KEEP,
testOneTimeWorkRequest);
}