1b8909f2c9c62261181e8270be8de44a69ac2b75fXyan Bhatnagar/* 2da315bf9331a3ead74483bd0d38fd331f4a96088Sumir Kataria * Copyright 2017 The Android Open Source Project 3b8909f2c9c62261181e8270be8de44a69ac2b75fXyan Bhatnagar * 4b8909f2c9c62261181e8270be8de44a69ac2b75fXyan Bhatnagar * Licensed under the Apache License, Version 2.0 (the "License"); 5b8909f2c9c62261181e8270be8de44a69ac2b75fXyan Bhatnagar * you may not use this file except in compliance with the License. 6b8909f2c9c62261181e8270be8de44a69ac2b75fXyan Bhatnagar * You may obtain a copy of the License at 7b8909f2c9c62261181e8270be8de44a69ac2b75fXyan Bhatnagar * 8b8909f2c9c62261181e8270be8de44a69ac2b75fXyan Bhatnagar * http://www.apache.org/licenses/LICENSE-2.0 9b8909f2c9c62261181e8270be8de44a69ac2b75fXyan Bhatnagar * 10b8909f2c9c62261181e8270be8de44a69ac2b75fXyan Bhatnagar * Unless required by applicable law or agreed to in writing, software 11b8909f2c9c62261181e8270be8de44a69ac2b75fXyan Bhatnagar * distributed under the License is distributed on an "AS IS" BASIS, 12b8909f2c9c62261181e8270be8de44a69ac2b75fXyan Bhatnagar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b8909f2c9c62261181e8270be8de44a69ac2b75fXyan Bhatnagar * See the License for the specific language governing permissions and 14b8909f2c9c62261181e8270be8de44a69ac2b75fXyan Bhatnagar * limitations under the License. 15b8909f2c9c62261181e8270be8de44a69ac2b75fXyan Bhatnagar */ 16b8909f2c9c62261181e8270be8de44a69ac2b75fXyan Bhatnagar 17564e43098c323d1a90be53c190b8fdbdde973505Sumir Katariapackage androidx.work.impl; 18b8909f2c9c62261181e8270be8de44a69ac2b75fXyan Bhatnagar 195b84f5ce59c65703ce6d5cdb1133185cd93e1862Sumir Katariaimport static androidx.work.State.CANCELLED; 20564e43098c323d1a90be53c190b8fdbdde973505Sumir Katariaimport static androidx.work.State.ENQUEUED; 21564e43098c323d1a90be53c190b8fdbdde973505Sumir Katariaimport static androidx.work.State.FAILED; 22564e43098c323d1a90be53c190b8fdbdde973505Sumir Katariaimport static androidx.work.State.RUNNING; 23564e43098c323d1a90be53c190b8fdbdde973505Sumir Katariaimport static androidx.work.State.SUCCEEDED; 2463ccec5104c970c3d93dd67c7f829d6a8cf8abbdXyan Bhatnagar 25b8909f2c9c62261181e8270be8de44a69ac2b75fXyan Bhatnagarimport android.content.Context; 26b8909f2c9c62261181e8270be8de44a69ac2b75fXyan Bhatnagarimport android.support.annotation.NonNull; 27d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumarimport android.support.annotation.Nullable; 282881509622c5dd8064f414075ce60060dbac688fSumir Katariaimport android.support.annotation.RestrictTo; 29d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumarimport android.support.annotation.VisibleForTesting; 30f6d484674fd8f2c3a0bc6a8b5117769a3c9b3640Xyan Bhatnagarimport android.support.annotation.WorkerThread; 31b8909f2c9c62261181e8270be8de44a69ac2b75fXyan Bhatnagarimport android.util.Log; 32b8909f2c9c62261181e8270be8de44a69ac2b75fXyan Bhatnagar 33e326592ec414dfe4c002e2840d9fc4aef0ee8747Rahul Ravikumarimport androidx.work.Configuration; 3464e6bd86c786f1cb1b0c3dbc2b5307cca5c0d1f6Sumir Katariaimport androidx.work.Data; 35564e43098c323d1a90be53c190b8fdbdde973505Sumir Katariaimport androidx.work.InputMerger; 36564e43098c323d1a90be53c190b8fdbdde973505Sumir Katariaimport androidx.work.State; 37564e43098c323d1a90be53c190b8fdbdde973505Sumir Katariaimport androidx.work.Worker; 38564e43098c323d1a90be53c190b8fdbdde973505Sumir Katariaimport androidx.work.impl.model.DependencyDao; 39564e43098c323d1a90be53c190b8fdbdde973505Sumir Katariaimport androidx.work.impl.model.WorkSpec; 40564e43098c323d1a90be53c190b8fdbdde973505Sumir Katariaimport androidx.work.impl.model.WorkSpecDao; 417b5c560e4098585f73564951621060de708e441fSumir Katariaimport androidx.work.impl.model.WorkTagDao; 42564e43098c323d1a90be53c190b8fdbdde973505Sumir Katariaimport androidx.work.impl.utils.taskexecutor.WorkManagerTaskExecutor; 43564e43098c323d1a90be53c190b8fdbdde973505Sumir Kataria 44b5728f4e1a4b3f4f1fabf033b1363ca6b1cffdefSumir Katariaimport java.lang.reflect.Method; 45b5728f4e1a4b3f4f1fabf033b1363ca6b1cffdefSumir Katariaimport java.util.ArrayList; 46b5728f4e1a4b3f4f1fabf033b1363ca6b1cffdefSumir Katariaimport java.util.List; 47dd5f33cd6b98eba208ac7c69d3d6314d3115e2d2Sumir Katariaimport java.util.UUID; 48b5728f4e1a4b3f4f1fabf033b1363ca6b1cffdefSumir Kataria 49b8909f2c9c62261181e8270be8de44a69ac2b75fXyan Bhatnagar/** 50b8909f2c9c62261181e8270be8de44a69ac2b75fXyan Bhatnagar * A runnable that looks up the {@link WorkSpec} from the database for a given id, instantiates 51b8909f2c9c62261181e8270be8de44a69ac2b75fXyan Bhatnagar * its Worker, and then calls it. 522881509622c5dd8064f414075ce60060dbac688fSumir Kataria * 532881509622c5dd8064f414075ce60060dbac688fSumir Kataria * @hide 54b8909f2c9c62261181e8270be8de44a69ac2b75fXyan Bhatnagar */ 552881509622c5dd8064f414075ce60060dbac688fSumir Kataria@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) 56115eb6a640a0addca15460a2a994e21692a3ffefSumir Katariapublic class WorkerWrapper implements Runnable { 5763ccec5104c970c3d93dd67c7f829d6a8cf8abbdXyan Bhatnagar 58b8909f2c9c62261181e8270be8de44a69ac2b75fXyan Bhatnagar private static final String TAG = "WorkerWrapper"; 59b8909f2c9c62261181e8270be8de44a69ac2b75fXyan Bhatnagar private Context mAppContext; 60b8909f2c9c62261181e8270be8de44a69ac2b75fXyan Bhatnagar private String mWorkSpecId; 61dc31aa85682ec4cb14784d393b4b70ff4da5d43dXyan Bhatnagar private ExecutionListener mListener; 62137c84c9c8212a44ee81c238a1a2271637ffa24bSumir Kataria private List<Scheduler> mSchedulers; 637b5c560e4098585f73564951621060de708e441fSumir Kataria private Extras.RuntimeExtras mRuntimeExtras; 64fdd887fead7d32e5e69e94d6b2ebe9770b2ec5bbXyan Bhatnagar private WorkSpec mWorkSpec; 656ae802c24782090d816f3950869a446344206e55Sumir Kataria Worker mWorker; 669e63790830c817be832dd4f7de2b483c2f555363Sumir Kataria 67e326592ec414dfe4c002e2840d9fc4aef0ee8747Rahul Ravikumar private Configuration mConfiguration; 689e63790830c817be832dd4f7de2b483c2f555363Sumir Kataria private WorkDatabase mWorkDatabase; 69fdd887fead7d32e5e69e94d6b2ebe9770b2ec5bbXyan Bhatnagar private WorkSpecDao mWorkSpecDao; 70fdd887fead7d32e5e69e94d6b2ebe9770b2ec5bbXyan Bhatnagar private DependencyDao mDependencyDao; 717b5c560e4098585f73564951621060de708e441fSumir Kataria private WorkTagDao mWorkTagDao; 72969025c012f4a8bd7bccda7216d76fc4636590feXyan Bhatnagar 73b0a0d7b4910f8733c04bc9dd98ec05da7247bdceSumir Kataria private volatile boolean mInterrupted; 74b0a0d7b4910f8733c04bc9dd98ec05da7247bdceSumir Kataria 75969025c012f4a8bd7bccda7216d76fc4636590feXyan Bhatnagar private WorkerWrapper(Builder builder) { 76969025c012f4a8bd7bccda7216d76fc4636590feXyan Bhatnagar mAppContext = builder.mAppContext; 77969025c012f4a8bd7bccda7216d76fc4636590feXyan Bhatnagar mWorkSpecId = builder.mWorkSpecId; 78969025c012f4a8bd7bccda7216d76fc4636590feXyan Bhatnagar mListener = builder.mListener; 79137c84c9c8212a44ee81c238a1a2271637ffa24bSumir Kataria mSchedulers = builder.mSchedulers; 80681a8d809fe41189c9d590d33b986b98170e4963Sumir Kataria mRuntimeExtras = builder.mRuntimeExtras; 81d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar mWorker = builder.mWorker; 829e63790830c817be832dd4f7de2b483c2f555363Sumir Kataria 83e326592ec414dfe4c002e2840d9fc4aef0ee8747Rahul Ravikumar mConfiguration = builder.mConfiguration; 849e63790830c817be832dd4f7de2b483c2f555363Sumir Kataria mWorkDatabase = builder.mWorkDatabase; 85fdd887fead7d32e5e69e94d6b2ebe9770b2ec5bbXyan Bhatnagar mWorkSpecDao = mWorkDatabase.workSpecDao(); 86fdd887fead7d32e5e69e94d6b2ebe9770b2ec5bbXyan Bhatnagar mDependencyDao = mWorkDatabase.dependencyDao(); 877b5c560e4098585f73564951621060de708e441fSumir Kataria mWorkTagDao = mWorkDatabase.workTagDao(); 88b8909f2c9c62261181e8270be8de44a69ac2b75fXyan Bhatnagar } 89b8909f2c9c62261181e8270be8de44a69ac2b75fXyan Bhatnagar 90f6d484674fd8f2c3a0bc6a8b5117769a3c9b3640Xyan Bhatnagar @WorkerThread 91b8909f2c9c62261181e8270be8de44a69ac2b75fXyan Bhatnagar @Override 92b8909f2c9c62261181e8270be8de44a69ac2b75fXyan Bhatnagar public void run() { 93b0a0d7b4910f8733c04bc9dd98ec05da7247bdceSumir Kataria if (tryCheckForInterruptionAndNotify()) { 94b0a0d7b4910f8733c04bc9dd98ec05da7247bdceSumir Kataria return; 95b0a0d7b4910f8733c04bc9dd98ec05da7247bdceSumir Kataria } 96b0a0d7b4910f8733c04bc9dd98ec05da7247bdceSumir Kataria 97fdd887fead7d32e5e69e94d6b2ebe9770b2ec5bbXyan Bhatnagar mWorkSpec = mWorkSpecDao.getWorkSpec(mWorkSpecId); 98fdd887fead7d32e5e69e94d6b2ebe9770b2ec5bbXyan Bhatnagar if (mWorkSpec == null) { 99697d6a4a3797bc71d0dd8685937a318e9934066bRahul Ravikumar Log.e(TAG, String.format("Didn't find WorkSpec for id %s", mWorkSpecId)); 100fb351fb5fe9af0af6c37aa282ce3a3325d311425Rahul Ravikumar notifyListener(false, false); 101b8909f2c9c62261181e8270be8de44a69ac2b75fXyan Bhatnagar return; 102b8909f2c9c62261181e8270be8de44a69ac2b75fXyan Bhatnagar } 103b8909f2c9c62261181e8270be8de44a69ac2b75fXyan Bhatnagar 104dcbf20db18e3e93a13e9fa75fa4b723255b87c54Sumir Kataria // Do a quick check to make sure we don't need to bail out in case this work is already 105dcbf20db18e3e93a13e9fa75fa4b723255b87c54Sumir Kataria // running, finished, or is blocked. 106b5728f4e1a4b3f4f1fabf033b1363ca6b1cffdefSumir Kataria if (mWorkSpec.state != ENQUEUED) { 1073557457daf57a3248c72320243263a0387687085Xyan Bhatnagar notifyIncorrectStatus(); 1083557457daf57a3248c72320243263a0387687085Xyan Bhatnagar return; 109b8909f2c9c62261181e8270be8de44a69ac2b75fXyan Bhatnagar } 110b8909f2c9c62261181e8270be8de44a69ac2b75fXyan Bhatnagar 111dcbf20db18e3e93a13e9fa75fa4b723255b87c54Sumir Kataria // Merge inputs. This can be potentially expensive code, so this should not be done inside 112dcbf20db18e3e93a13e9fa75fa4b723255b87c54Sumir Kataria // a database transaction. 11364e6bd86c786f1cb1b0c3dbc2b5307cca5c0d1f6Sumir Kataria Data input; 11449cacea720fca909dfbcbd9c7642a05f3ddee400Sumir Kataria if (mWorkSpec.isPeriodic()) { 11564e6bd86c786f1cb1b0c3dbc2b5307cca5c0d1f6Sumir Kataria input = mWorkSpec.input; 11649cacea720fca909dfbcbd9c7642a05f3ddee400Sumir Kataria } else { 117b5728f4e1a4b3f4f1fabf033b1363ca6b1cffdefSumir Kataria InputMerger inputMerger = InputMerger.fromClassName(mWorkSpec.inputMergerClassName); 1183557457daf57a3248c72320243263a0387687085Xyan Bhatnagar if (inputMerger == null) { 119697d6a4a3797bc71d0dd8685937a318e9934066bRahul Ravikumar Log.e(TAG, String.format("Could not create Input Merger %s", 120697d6a4a3797bc71d0dd8685937a318e9934066bRahul Ravikumar mWorkSpec.inputMergerClassName)); 1213557457daf57a3248c72320243263a0387687085Xyan Bhatnagar setFailedAndNotify(); 1223557457daf57a3248c72320243263a0387687085Xyan Bhatnagar return; 1233557457daf57a3248c72320243263a0387687085Xyan Bhatnagar } 12464e6bd86c786f1cb1b0c3dbc2b5307cca5c0d1f6Sumir Kataria List<Data> inputs = new ArrayList<>(); 12564e6bd86c786f1cb1b0c3dbc2b5307cca5c0d1f6Sumir Kataria inputs.add(mWorkSpec.input); 12649cacea720fca909dfbcbd9c7642a05f3ddee400Sumir Kataria inputs.addAll(mWorkSpecDao.getInputsFromPrerequisites(mWorkSpecId)); 12764e6bd86c786f1cb1b0c3dbc2b5307cca5c0d1f6Sumir Kataria input = inputMerger.merge(inputs); 12849cacea720fca909dfbcbd9c7642a05f3ddee400Sumir Kataria } 129a48d7acf791f20ed5afc8bc8d8c66eebd9fbfd5bSumir Kataria 130b24ef38a0b526b524e3e6a7849f62f934a6ad58cSumir Kataria Extras extras = new Extras( 131b24ef38a0b526b524e3e6a7849f62f934a6ad58cSumir Kataria input, 132b24ef38a0b526b524e3e6a7849f62f934a6ad58cSumir Kataria mWorkTagDao.getTagsForWorkSpecId(mWorkSpecId), 133b24ef38a0b526b524e3e6a7849f62f934a6ad58cSumir Kataria mRuntimeExtras, 134b24ef38a0b526b524e3e6a7849f62f934a6ad58cSumir Kataria mWorkSpec.runAttemptCount); 1357b5c560e4098585f73564951621060de708e441fSumir Kataria 136d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar // Not always creating a worker here, as the WorkerWrapper.Builder can set a worker override 137d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar // in test mode. 138d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar if (mWorker == null) { 1397b5c560e4098585f73564951621060de708e441fSumir Kataria mWorker = workerFromWorkSpec(mAppContext, mWorkSpec, extras); 140d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar } 1413557457daf57a3248c72320243263a0387687085Xyan Bhatnagar 1421e9589d6482d2690e2eabb21f732377d268a5c05Sumir Kataria if (mWorker == null) { 143697d6a4a3797bc71d0dd8685937a318e9934066bRahul Ravikumar Log.e(TAG, String.format("Could for create Worker %s", mWorkSpec.workerClassName)); 1443557457daf57a3248c72320243263a0387687085Xyan Bhatnagar setFailedAndNotify(); 145b8909f2c9c62261181e8270be8de44a69ac2b75fXyan Bhatnagar return; 146b8909f2c9c62261181e8270be8de44a69ac2b75fXyan Bhatnagar } 147b8909f2c9c62261181e8270be8de44a69ac2b75fXyan Bhatnagar 148dcbf20db18e3e93a13e9fa75fa4b723255b87c54Sumir Kataria // Try to set the work to the running state. Note that this may fail because another thread 149dcbf20db18e3e93a13e9fa75fa4b723255b87c54Sumir Kataria // may have modified the DB since we checked last at the top of this function. 150dcbf20db18e3e93a13e9fa75fa4b723255b87c54Sumir Kataria if (trySetRunning()) { 151b0a0d7b4910f8733c04bc9dd98ec05da7247bdceSumir Kataria if (tryCheckForInterruptionAndNotify()) { 152b0a0d7b4910f8733c04bc9dd98ec05da7247bdceSumir Kataria return; 153b0a0d7b4910f8733c04bc9dd98ec05da7247bdceSumir Kataria } 154b0a0d7b4910f8733c04bc9dd98ec05da7247bdceSumir Kataria 15511a7c26af63674a21787696e509e9a43d0bd7acfSumir Kataria Worker.Result result; 1563f0c0fbaf4be127488fc900d915d1c966813a4e6Sumir Kataria try { 1573f0c0fbaf4be127488fc900d915d1c966813a4e6Sumir Kataria result = mWorker.doWork(); 1583f0c0fbaf4be127488fc900d915d1c966813a4e6Sumir Kataria } catch (Exception | Error e) { 15911a7c26af63674a21787696e509e9a43d0bd7acfSumir Kataria result = Worker.Result.FAILURE; 1603f0c0fbaf4be127488fc900d915d1c966813a4e6Sumir Kataria } 161b0a0d7b4910f8733c04bc9dd98ec05da7247bdceSumir Kataria 162dcbf20db18e3e93a13e9fa75fa4b723255b87c54Sumir Kataria try { 163b0a0d7b4910f8733c04bc9dd98ec05da7247bdceSumir Kataria mWorkDatabase.beginTransaction(); 164b0a0d7b4910f8733c04bc9dd98ec05da7247bdceSumir Kataria if (!tryCheckForInterruptionAndNotify()) { 165b0a0d7b4910f8733c04bc9dd98ec05da7247bdceSumir Kataria State state = mWorkSpecDao.getState(mWorkSpecId); 166d874811ee5f3275e6022115a03aa6001dc1830a9Sumir Kataria if (state == null) { 1671b87cb6abe29d752f0594bf5afe96fcd8f4e9ae2Rahul Ravikumar // state can be null here with a REPLACE on beginUniqueWork(). 1681b87cb6abe29d752f0594bf5afe96fcd8f4e9ae2Rahul Ravikumar // Treat it as a failure, and rescheduleAndNotify() will 1691b87cb6abe29d752f0594bf5afe96fcd8f4e9ae2Rahul Ravikumar // turn into a no-op. We still need to notify potential observers 1701b87cb6abe29d752f0594bf5afe96fcd8f4e9ae2Rahul Ravikumar // holding on to wake locks on our behalf. 171d874811ee5f3275e6022115a03aa6001dc1830a9Sumir Kataria notifyListener(false, false); 172d874811ee5f3275e6022115a03aa6001dc1830a9Sumir Kataria } else if (state == RUNNING) { 173d874811ee5f3275e6022115a03aa6001dc1830a9Sumir Kataria handleResult(result); 174d874811ee5f3275e6022115a03aa6001dc1830a9Sumir Kataria } else if (!state.isFinished()) { 175b0a0d7b4910f8733c04bc9dd98ec05da7247bdceSumir Kataria rescheduleAndNotify(); 176b0a0d7b4910f8733c04bc9dd98ec05da7247bdceSumir Kataria } 177b0a0d7b4910f8733c04bc9dd98ec05da7247bdceSumir Kataria mWorkDatabase.setTransactionSuccessful(); 178dcbf20db18e3e93a13e9fa75fa4b723255b87c54Sumir Kataria } 179b0a0d7b4910f8733c04bc9dd98ec05da7247bdceSumir Kataria } finally { 180b0a0d7b4910f8733c04bc9dd98ec05da7247bdceSumir Kataria mWorkDatabase.endTransaction(); 1812ace67d8c1383f7c33940d48817fd4d362105641Sumir Kataria } 182dcbf20db18e3e93a13e9fa75fa4b723255b87c54Sumir Kataria } else { 183dcbf20db18e3e93a13e9fa75fa4b723255b87c54Sumir Kataria notifyIncorrectStatus(); 1843557457daf57a3248c72320243263a0387687085Xyan Bhatnagar } 1853557457daf57a3248c72320243263a0387687085Xyan Bhatnagar } 1863557457daf57a3248c72320243263a0387687085Xyan Bhatnagar 187b0a0d7b4910f8733c04bc9dd98ec05da7247bdceSumir Kataria /** 188b0a0d7b4910f8733c04bc9dd98ec05da7247bdceSumir Kataria * @hide 189b0a0d7b4910f8733c04bc9dd98ec05da7247bdceSumir Kataria */ 190b0a0d7b4910f8733c04bc9dd98ec05da7247bdceSumir Kataria @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) 1915d373d376edddb57cd822dd06ed54f97ef949586Sumir Kataria public void interrupt(boolean cancelled) { 192b0a0d7b4910f8733c04bc9dd98ec05da7247bdceSumir Kataria mInterrupted = true; 193bf4f4f72fd27f110b95cc9867fb5dc695d2689b1Sumir Kataria // Worker can be null if run() hasn't been called yet. 194bf4f4f72fd27f110b95cc9867fb5dc695d2689b1Sumir Kataria if (mWorker != null) { 1955d373d376edddb57cd822dd06ed54f97ef949586Sumir Kataria mWorker.stop(cancelled); 196bf4f4f72fd27f110b95cc9867fb5dc695d2689b1Sumir Kataria } 197b0a0d7b4910f8733c04bc9dd98ec05da7247bdceSumir Kataria } 198b0a0d7b4910f8733c04bc9dd98ec05da7247bdceSumir Kataria 1993557457daf57a3248c72320243263a0387687085Xyan Bhatnagar private void notifyIncorrectStatus() { 200dcbf20db18e3e93a13e9fa75fa4b723255b87c54Sumir Kataria State status = mWorkSpecDao.getState(mWorkSpecId); 2014ee69ffea5f5636674c7aa8a19366dd950c9b770Sumir Kataria if (status == RUNNING) { 202697d6a4a3797bc71d0dd8685937a318e9934066bRahul Ravikumar Log.d(TAG, String.format("Status for %s is RUNNING;" 203697d6a4a3797bc71d0dd8685937a318e9934066bRahul Ravikumar + "not doing any work and rescheduling for later execution", mWorkSpecId)); 204fb351fb5fe9af0af6c37aa282ce3a3325d311425Rahul Ravikumar notifyListener(false, true); 2053557457daf57a3248c72320243263a0387687085Xyan Bhatnagar } else { 206697d6a4a3797bc71d0dd8685937a318e9934066bRahul Ravikumar Log.e(TAG, 207697d6a4a3797bc71d0dd8685937a318e9934066bRahul Ravikumar String.format("Status for %s is %s; not doing any work", mWorkSpecId, status)); 208fb351fb5fe9af0af6c37aa282ce3a3325d311425Rahul Ravikumar notifyListener(false, false); 209d7b783ea8f3a1e7fe1318681573a59bdf341b9dbXyan Bhatnagar } 210d7b783ea8f3a1e7fe1318681573a59bdf341b9dbXyan Bhatnagar } 211d7b783ea8f3a1e7fe1318681573a59bdf341b9dbXyan Bhatnagar 212b0a0d7b4910f8733c04bc9dd98ec05da7247bdceSumir Kataria private boolean tryCheckForInterruptionAndNotify() { 213b0a0d7b4910f8733c04bc9dd98ec05da7247bdceSumir Kataria if (mInterrupted) { 214b0a0d7b4910f8733c04bc9dd98ec05da7247bdceSumir Kataria Log.d(TAG, String.format("Work interrupted for %s", mWorkSpecId)); 215b0a0d7b4910f8733c04bc9dd98ec05da7247bdceSumir Kataria State currentState = mWorkSpecDao.getState(mWorkSpecId); 216d874811ee5f3275e6022115a03aa6001dc1830a9Sumir Kataria if (currentState == null) { 217d874811ee5f3275e6022115a03aa6001dc1830a9Sumir Kataria // This can happen because of a beginUniqueWork(..., REPLACE, ...). Notify the 218d874811ee5f3275e6022115a03aa6001dc1830a9Sumir Kataria // listeners so we can clean up any wake locks, etc. 219d874811ee5f3275e6022115a03aa6001dc1830a9Sumir Kataria notifyListener(false, false); 220d874811ee5f3275e6022115a03aa6001dc1830a9Sumir Kataria } else { 221d874811ee5f3275e6022115a03aa6001dc1830a9Sumir Kataria notifyListener(currentState == SUCCEEDED, !currentState.isFinished()); 222d874811ee5f3275e6022115a03aa6001dc1830a9Sumir Kataria } 223b0a0d7b4910f8733c04bc9dd98ec05da7247bdceSumir Kataria return true; 224d7b783ea8f3a1e7fe1318681573a59bdf341b9dbXyan Bhatnagar } 225b0a0d7b4910f8733c04bc9dd98ec05da7247bdceSumir Kataria return false; 226b8909f2c9c62261181e8270be8de44a69ac2b75fXyan Bhatnagar } 227dc31aa85682ec4cb14784d393b4b70ff4da5d43dXyan Bhatnagar 228fb351fb5fe9af0af6c37aa282ce3a3325d311425Rahul Ravikumar private void notifyListener(final boolean isSuccessful, final boolean needsReschedule) { 229969025c012f4a8bd7bccda7216d76fc4636590feXyan Bhatnagar if (mListener == null) { 230969025c012f4a8bd7bccda7216d76fc4636590feXyan Bhatnagar return; 231969025c012f4a8bd7bccda7216d76fc4636590feXyan Bhatnagar } 232687da3388ece2fefd80c710c382dff908b615a3fXyan Bhatnagar WorkManagerTaskExecutor.getInstance().postToMainThread(new Runnable() { 233dc31aa85682ec4cb14784d393b4b70ff4da5d43dXyan Bhatnagar @Override 234dc31aa85682ec4cb14784d393b4b70ff4da5d43dXyan Bhatnagar public void run() { 235fb351fb5fe9af0af6c37aa282ce3a3325d311425Rahul Ravikumar mListener.onExecuted(mWorkSpecId, isSuccessful, needsReschedule); 236dc31aa85682ec4cb14784d393b4b70ff4da5d43dXyan Bhatnagar } 237dc31aa85682ec4cb14784d393b4b70ff4da5d43dXyan Bhatnagar }); 238dc31aa85682ec4cb14784d393b4b70ff4da5d43dXyan Bhatnagar } 2396463bebf1255dabbe9b5efd1c3be20e7dfd74551Xyan Bhatnagar 24011a7c26af63674a21787696e509e9a43d0bd7acfSumir Kataria private void handleResult(Worker.Result result) { 241fdd887fead7d32e5e69e94d6b2ebe9770b2ec5bbXyan Bhatnagar switch (result) { 242d7c332544c4dc6e06b4a876fd10c25b0469e81bcSumir Kataria case SUCCESS: { 243697d6a4a3797bc71d0dd8685937a318e9934066bRahul Ravikumar Log.d(TAG, String.format("Worker result SUCCESS for %s", mWorkSpecId)); 244fdd887fead7d32e5e69e94d6b2ebe9770b2ec5bbXyan Bhatnagar if (mWorkSpec.isPeriodic()) { 245fb351fb5fe9af0af6c37aa282ce3a3325d311425Rahul Ravikumar resetPeriodicAndNotify(true); 246fdd887fead7d32e5e69e94d6b2ebe9770b2ec5bbXyan Bhatnagar } else { 2473557457daf57a3248c72320243263a0387687085Xyan Bhatnagar setSucceededAndNotify(); 248fdd887fead7d32e5e69e94d6b2ebe9770b2ec5bbXyan Bhatnagar } 249fdd887fead7d32e5e69e94d6b2ebe9770b2ec5bbXyan Bhatnagar break; 250fdd887fead7d32e5e69e94d6b2ebe9770b2ec5bbXyan Bhatnagar } 251fdd887fead7d32e5e69e94d6b2ebe9770b2ec5bbXyan Bhatnagar 252d7c332544c4dc6e06b4a876fd10c25b0469e81bcSumir Kataria case RETRY: { 253697d6a4a3797bc71d0dd8685937a318e9934066bRahul Ravikumar Log.d(TAG, String.format("Worker result RETRY for %s", mWorkSpecId)); 254b0a0d7b4910f8733c04bc9dd98ec05da7247bdceSumir Kataria rescheduleAndNotify(); 255fdd887fead7d32e5e69e94d6b2ebe9770b2ec5bbXyan Bhatnagar break; 256fdd887fead7d32e5e69e94d6b2ebe9770b2ec5bbXyan Bhatnagar } 257fdd887fead7d32e5e69e94d6b2ebe9770b2ec5bbXyan Bhatnagar 258d7c332544c4dc6e06b4a876fd10c25b0469e81bcSumir Kataria case FAILURE: 259fdd887fead7d32e5e69e94d6b2ebe9770b2ec5bbXyan Bhatnagar default: { 260697d6a4a3797bc71d0dd8685937a318e9934066bRahul Ravikumar Log.d(TAG, String.format("Worker result FAILURE for %s", mWorkSpecId)); 261fdd887fead7d32e5e69e94d6b2ebe9770b2ec5bbXyan Bhatnagar if (mWorkSpec.isPeriodic()) { 262fb351fb5fe9af0af6c37aa282ce3a3325d311425Rahul Ravikumar resetPeriodicAndNotify(false); 263fdd887fead7d32e5e69e94d6b2ebe9770b2ec5bbXyan Bhatnagar } else { 2643557457daf57a3248c72320243263a0387687085Xyan Bhatnagar setFailedAndNotify(); 265fdd887fead7d32e5e69e94d6b2ebe9770b2ec5bbXyan Bhatnagar } 266fdd887fead7d32e5e69e94d6b2ebe9770b2ec5bbXyan Bhatnagar } 267fdd887fead7d32e5e69e94d6b2ebe9770b2ec5bbXyan Bhatnagar } 268fdd887fead7d32e5e69e94d6b2ebe9770b2ec5bbXyan Bhatnagar } 269fdd887fead7d32e5e69e94d6b2ebe9770b2ec5bbXyan Bhatnagar 270dcbf20db18e3e93a13e9fa75fa4b723255b87c54Sumir Kataria private boolean trySetRunning() { 271dcbf20db18e3e93a13e9fa75fa4b723255b87c54Sumir Kataria boolean setToRunning = false; 2723557457daf57a3248c72320243263a0387687085Xyan Bhatnagar mWorkDatabase.beginTransaction(); 2733557457daf57a3248c72320243263a0387687085Xyan Bhatnagar try { 274dcbf20db18e3e93a13e9fa75fa4b723255b87c54Sumir Kataria State currentState = mWorkSpecDao.getState(mWorkSpecId); 275dcbf20db18e3e93a13e9fa75fa4b723255b87c54Sumir Kataria if (currentState == ENQUEUED) { 276dcbf20db18e3e93a13e9fa75fa4b723255b87c54Sumir Kataria mWorkSpecDao.setState(RUNNING, mWorkSpecId); 277dcbf20db18e3e93a13e9fa75fa4b723255b87c54Sumir Kataria mWorkSpecDao.incrementWorkSpecRunAttemptCount(mWorkSpecId); 278dcbf20db18e3e93a13e9fa75fa4b723255b87c54Sumir Kataria mWorkDatabase.setTransactionSuccessful(); 279dcbf20db18e3e93a13e9fa75fa4b723255b87c54Sumir Kataria setToRunning = true; 280dcbf20db18e3e93a13e9fa75fa4b723255b87c54Sumir Kataria } 2813557457daf57a3248c72320243263a0387687085Xyan Bhatnagar } finally { 2823557457daf57a3248c72320243263a0387687085Xyan Bhatnagar mWorkDatabase.endTransaction(); 2833557457daf57a3248c72320243263a0387687085Xyan Bhatnagar } 284dcbf20db18e3e93a13e9fa75fa4b723255b87c54Sumir Kataria return setToRunning; 2853557457daf57a3248c72320243263a0387687085Xyan Bhatnagar } 2863557457daf57a3248c72320243263a0387687085Xyan Bhatnagar 2873557457daf57a3248c72320243263a0387687085Xyan Bhatnagar private void setFailedAndNotify() { 28886666efc34520f0ac97e0fbde5229ba560caac46Sumir Kataria mWorkDatabase.beginTransaction(); 28986666efc34520f0ac97e0fbde5229ba560caac46Sumir Kataria try { 290c1ba633e4668bbf02097a76261ebcee8f3b59e06Sumir Kataria recursivelyFailWorkAndDependents(mWorkSpecId); 291c1ba633e4668bbf02097a76261ebcee8f3b59e06Sumir Kataria 292c1ba633e4668bbf02097a76261ebcee8f3b59e06Sumir Kataria // Try to set the output for the failed work but check if the worker exists; this could 293c1ba633e4668bbf02097a76261ebcee8f3b59e06Sumir Kataria // be a permanent error where we couldn't find or create the worker class. 29486666efc34520f0ac97e0fbde5229ba560caac46Sumir Kataria if (mWorker != null) { 29564e6bd86c786f1cb1b0c3dbc2b5307cca5c0d1f6Sumir Kataria // Update Data as necessary. 29664e6bd86c786f1cb1b0c3dbc2b5307cca5c0d1f6Sumir Kataria Data output = mWorker.getOutputData(); 297b9701e2752b53221501cfaeb247256f1ae12baecSumir Kataria mWorkSpecDao.setOutput(mWorkSpecId, output); 29886666efc34520f0ac97e0fbde5229ba560caac46Sumir Kataria } 299c1ba633e4668bbf02097a76261ebcee8f3b59e06Sumir Kataria 30086666efc34520f0ac97e0fbde5229ba560caac46Sumir Kataria mWorkDatabase.setTransactionSuccessful(); 30186666efc34520f0ac97e0fbde5229ba560caac46Sumir Kataria } finally { 30286666efc34520f0ac97e0fbde5229ba560caac46Sumir Kataria mWorkDatabase.endTransaction(); 30386666efc34520f0ac97e0fbde5229ba560caac46Sumir Kataria notifyListener(false, false); 30486666efc34520f0ac97e0fbde5229ba560caac46Sumir Kataria } 3059f91ee8c71606f36a51177cd0b5c3005834be1ffRahul Ravikumar 306e326592ec414dfe4c002e2840d9fc4aef0ee8747Rahul Ravikumar Schedulers.schedule(mConfiguration, mWorkDatabase, mSchedulers); 3073557457daf57a3248c72320243263a0387687085Xyan Bhatnagar } 3083557457daf57a3248c72320243263a0387687085Xyan Bhatnagar 309c1ba633e4668bbf02097a76261ebcee8f3b59e06Sumir Kataria private void recursivelyFailWorkAndDependents(String workSpecId) { 310c1ba633e4668bbf02097a76261ebcee8f3b59e06Sumir Kataria List<String> dependentIds = mDependencyDao.getDependentWorkIds(workSpecId); 311c1ba633e4668bbf02097a76261ebcee8f3b59e06Sumir Kataria for (String id : dependentIds) { 312c1ba633e4668bbf02097a76261ebcee8f3b59e06Sumir Kataria recursivelyFailWorkAndDependents(id); 313c1ba633e4668bbf02097a76261ebcee8f3b59e06Sumir Kataria } 314c1ba633e4668bbf02097a76261ebcee8f3b59e06Sumir Kataria 315c1ba633e4668bbf02097a76261ebcee8f3b59e06Sumir Kataria // Don't fail already cancelled work. 3165b84f5ce59c65703ce6d5cdb1133185cd93e1862Sumir Kataria if (mWorkSpecDao.getState(workSpecId) != CANCELLED) { 317c1ba633e4668bbf02097a76261ebcee8f3b59e06Sumir Kataria mWorkSpecDao.setState(FAILED, workSpecId); 318c1ba633e4668bbf02097a76261ebcee8f3b59e06Sumir Kataria } 319c1ba633e4668bbf02097a76261ebcee8f3b59e06Sumir Kataria } 320c1ba633e4668bbf02097a76261ebcee8f3b59e06Sumir Kataria 321b0a0d7b4910f8733c04bc9dd98ec05da7247bdceSumir Kataria private void rescheduleAndNotify() { 3221c78bb2b576a34e69875808aa675e1ca5d5068b4Xyan Bhatnagar mWorkDatabase.beginTransaction(); 3231c78bb2b576a34e69875808aa675e1ca5d5068b4Xyan Bhatnagar try { 3249cf4f3d3aa83bc64db574955805c67ac9ea84008Sumir Kataria mWorkSpecDao.setState(ENQUEUED, mWorkSpecId); 3251c78bb2b576a34e69875808aa675e1ca5d5068b4Xyan Bhatnagar // TODO(xbhatnag): Period Start Time is confusing for non-periodic work. Rename. 3261c78bb2b576a34e69875808aa675e1ca5d5068b4Xyan Bhatnagar mWorkSpecDao.setPeriodStartTime(mWorkSpecId, System.currentTimeMillis()); 3271c78bb2b576a34e69875808aa675e1ca5d5068b4Xyan Bhatnagar mWorkDatabase.setTransactionSuccessful(); 3281c78bb2b576a34e69875808aa675e1ca5d5068b4Xyan Bhatnagar } finally { 3291c78bb2b576a34e69875808aa675e1ca5d5068b4Xyan Bhatnagar mWorkDatabase.endTransaction(); 330b0a0d7b4910f8733c04bc9dd98ec05da7247bdceSumir Kataria notifyListener(false, true); 3311c78bb2b576a34e69875808aa675e1ca5d5068b4Xyan Bhatnagar } 3321c78bb2b576a34e69875808aa675e1ca5d5068b4Xyan Bhatnagar } 3331c78bb2b576a34e69875808aa675e1ca5d5068b4Xyan Bhatnagar 334fb351fb5fe9af0af6c37aa282ce3a3325d311425Rahul Ravikumar private void resetPeriodicAndNotify(boolean isSuccessful) { 335fdd887fead7d32e5e69e94d6b2ebe9770b2ec5bbXyan Bhatnagar mWorkDatabase.beginTransaction(); 336fdd887fead7d32e5e69e94d6b2ebe9770b2ec5bbXyan Bhatnagar try { 337b5728f4e1a4b3f4f1fabf033b1363ca6b1cffdefSumir Kataria long currentPeriodStartTime = mWorkSpec.periodStartTime; 338b5728f4e1a4b3f4f1fabf033b1363ca6b1cffdefSumir Kataria long nextPeriodStartTime = currentPeriodStartTime + mWorkSpec.intervalDuration; 3390deb5e280d72959e89e7c4433e15c77f6523b693Jan Clarin mWorkSpecDao.setPeriodStartTime(mWorkSpecId, nextPeriodStartTime); 3409cf4f3d3aa83bc64db574955805c67ac9ea84008Sumir Kataria mWorkSpecDao.setState(ENQUEUED, mWorkSpecId); 341fdd887fead7d32e5e69e94d6b2ebe9770b2ec5bbXyan Bhatnagar mWorkSpecDao.resetWorkSpecRunAttemptCount(mWorkSpecId); 342fdd887fead7d32e5e69e94d6b2ebe9770b2ec5bbXyan Bhatnagar mWorkDatabase.setTransactionSuccessful(); 343fdd887fead7d32e5e69e94d6b2ebe9770b2ec5bbXyan Bhatnagar } finally { 344fdd887fead7d32e5e69e94d6b2ebe9770b2ec5bbXyan Bhatnagar mWorkDatabase.endTransaction(); 345fb351fb5fe9af0af6c37aa282ce3a3325d311425Rahul Ravikumar notifyListener(isSuccessful, false); 346fdd887fead7d32e5e69e94d6b2ebe9770b2ec5bbXyan Bhatnagar } 347fdd887fead7d32e5e69e94d6b2ebe9770b2ec5bbXyan Bhatnagar } 3485643e2e608bf406eaf6a8bc990b9bad7a7deb97dSumir Kataria 3493557457daf57a3248c72320243263a0387687085Xyan Bhatnagar private void setSucceededAndNotify() { 3506463bebf1255dabbe9b5efd1c3be20e7dfd74551Xyan Bhatnagar mWorkDatabase.beginTransaction(); 3516463bebf1255dabbe9b5efd1c3be20e7dfd74551Xyan Bhatnagar try { 3529cf4f3d3aa83bc64db574955805c67ac9ea84008Sumir Kataria mWorkSpecDao.setState(SUCCEEDED, mWorkSpecId); 3536ae802c24782090d816f3950869a446344206e55Sumir Kataria 35464e6bd86c786f1cb1b0c3dbc2b5307cca5c0d1f6Sumir Kataria // Update Data as necessary. 35564e6bd86c786f1cb1b0c3dbc2b5307cca5c0d1f6Sumir Kataria Data output = mWorker.getOutputData(); 356b9701e2752b53221501cfaeb247256f1ae12baecSumir Kataria mWorkSpecDao.setOutput(mWorkSpecId, output); 3576ae802c24782090d816f3950869a446344206e55Sumir Kataria 3583557457daf57a3248c72320243263a0387687085Xyan Bhatnagar // Unblock Dependencies and set Period Start Time 3590deb5e280d72959e89e7c4433e15c77f6523b693Jan Clarin long currentTimeMillis = System.currentTimeMillis(); 3609244d377b9c9216a474b12d1a5f6aaa787941af4Sumir Kataria List<String> dependentWorkIds = mDependencyDao.getDependentWorkIds(mWorkSpecId); 3619244d377b9c9216a474b12d1a5f6aaa787941af4Sumir Kataria for (String dependentWorkId : dependentWorkIds) { 3629244d377b9c9216a474b12d1a5f6aaa787941af4Sumir Kataria if (mDependencyDao.hasCompletedAllPrerequisites(dependentWorkId)) { 363697d6a4a3797bc71d0dd8685937a318e9934066bRahul Ravikumar Log.d(TAG, String.format("Setting status to enqueued for %s", dependentWorkId)); 3649cf4f3d3aa83bc64db574955805c67ac9ea84008Sumir Kataria mWorkSpecDao.setState(ENQUEUED, dependentWorkId); 3650deb5e280d72959e89e7c4433e15c77f6523b693Jan Clarin mWorkSpecDao.setPeriodStartTime(dependentWorkId, currentTimeMillis); 3669244d377b9c9216a474b12d1a5f6aaa787941af4Sumir Kataria } 3679244d377b9c9216a474b12d1a5f6aaa787941af4Sumir Kataria } 3686ae802c24782090d816f3950869a446344206e55Sumir Kataria 3695611e083e6e2713f155fbdea091c1fa13c479b5cSumir Kataria mWorkDatabase.setTransactionSuccessful(); 3705611e083e6e2713f155fbdea091c1fa13c479b5cSumir Kataria } finally { 3715611e083e6e2713f155fbdea091c1fa13c479b5cSumir Kataria mWorkDatabase.endTransaction(); 3725611e083e6e2713f155fbdea091c1fa13c479b5cSumir Kataria notifyListener(true, false); 3735611e083e6e2713f155fbdea091c1fa13c479b5cSumir Kataria } 3745611e083e6e2713f155fbdea091c1fa13c479b5cSumir Kataria 3759f91ee8c71606f36a51177cd0b5c3005834be1ffRahul Ravikumar // This takes of scheduling the dependent workers as they have been marked ENQUEUED. 376e326592ec414dfe4c002e2840d9fc4aef0ee8747Rahul Ravikumar Schedulers.schedule(mConfiguration, mWorkDatabase, mSchedulers); 3776463bebf1255dabbe9b5efd1c3be20e7dfd74551Xyan Bhatnagar } 378969025c012f4a8bd7bccda7216d76fc4636590feXyan Bhatnagar 379da315bf9331a3ead74483bd0d38fd331f4a96088Sumir Kataria static Worker workerFromWorkSpec(@NonNull Context context, 380da315bf9331a3ead74483bd0d38fd331f4a96088Sumir Kataria @NonNull WorkSpec workSpec, 3817b5c560e4098585f73564951621060de708e441fSumir Kataria @NonNull Extras extras) { 382b5728f4e1a4b3f4f1fabf033b1363ca6b1cffdefSumir Kataria String workerClassName = workSpec.workerClassName; 383dd5f33cd6b98eba208ac7c69d3d6314d3115e2d2Sumir Kataria UUID workSpecId = UUID.fromString(workSpec.id); 384681a8d809fe41189c9d590d33b986b98170e4963Sumir Kataria return workerFromClassName( 385681a8d809fe41189c9d590d33b986b98170e4963Sumir Kataria context, 386681a8d809fe41189c9d590d33b986b98170e4963Sumir Kataria workerClassName, 387681a8d809fe41189c9d590d33b986b98170e4963Sumir Kataria workSpecId, 3887b5c560e4098585f73564951621060de708e441fSumir Kataria extras); 389d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar } 390d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar 391d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar /** 392d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar * Creates a {@link Worker} reflectively & initializes the worker. 393d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar * 394d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar * @param context The application {@link Context} 395d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar * @param workerClassName The fully qualified class name for the {@link Worker} 396d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar * @param workSpecId The {@link WorkSpec} identifier 3977b5c560e4098585f73564951621060de708e441fSumir Kataria * @param extras The {@link Extras} for the worker 398d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar * @return The instance of {@link Worker} 399d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar * 400d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar * @hide 401d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar */ 402d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) 403d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar @SuppressWarnings("ClassNewInstance") 404d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar public static Worker workerFromClassName( 405d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar @NonNull Context context, 406d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar @NonNull String workerClassName, 407dd5f33cd6b98eba208ac7c69d3d6314d3115e2d2Sumir Kataria @NonNull UUID workSpecId, 4087b5c560e4098585f73564951621060de708e441fSumir Kataria @NonNull Extras extras) { 409d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar Context appContext = context.getApplicationContext(); 410da315bf9331a3ead74483bd0d38fd331f4a96088Sumir Kataria try { 411da315bf9331a3ead74483bd0d38fd331f4a96088Sumir Kataria Class<?> clazz = Class.forName(workerClassName); 412da315bf9331a3ead74483bd0d38fd331f4a96088Sumir Kataria Worker worker = (Worker) clazz.newInstance(); 413da315bf9331a3ead74483bd0d38fd331f4a96088Sumir Kataria Method internalInitMethod = Worker.class.getDeclaredMethod( 414681a8d809fe41189c9d590d33b986b98170e4963Sumir Kataria "internalInit", 415681a8d809fe41189c9d590d33b986b98170e4963Sumir Kataria Context.class, 416dd5f33cd6b98eba208ac7c69d3d6314d3115e2d2Sumir Kataria UUID.class, 4177b5c560e4098585f73564951621060de708e441fSumir Kataria Extras.class); 418da315bf9331a3ead74483bd0d38fd331f4a96088Sumir Kataria internalInitMethod.setAccessible(true); 419681a8d809fe41189c9d590d33b986b98170e4963Sumir Kataria internalInitMethod.invoke( 420681a8d809fe41189c9d590d33b986b98170e4963Sumir Kataria worker, 421681a8d809fe41189c9d590d33b986b98170e4963Sumir Kataria appContext, 422681a8d809fe41189c9d590d33b986b98170e4963Sumir Kataria workSpecId, 4237b5c560e4098585f73564951621060de708e441fSumir Kataria extras); 424da315bf9331a3ead74483bd0d38fd331f4a96088Sumir Kataria return worker; 425da315bf9331a3ead74483bd0d38fd331f4a96088Sumir Kataria } catch (Exception e) { 426da315bf9331a3ead74483bd0d38fd331f4a96088Sumir Kataria Log.e(TAG, "Trouble instantiating " + workerClassName, e); 427da315bf9331a3ead74483bd0d38fd331f4a96088Sumir Kataria } 428da315bf9331a3ead74483bd0d38fd331f4a96088Sumir Kataria return null; 429da315bf9331a3ead74483bd0d38fd331f4a96088Sumir Kataria } 430da315bf9331a3ead74483bd0d38fd331f4a96088Sumir Kataria 431969025c012f4a8bd7bccda7216d76fc4636590feXyan Bhatnagar /** 432969025c012f4a8bd7bccda7216d76fc4636590feXyan Bhatnagar * Builder class for {@link WorkerWrapper} 433d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar * @hide 434969025c012f4a8bd7bccda7216d76fc4636590feXyan Bhatnagar */ 435d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) 436d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar public static class Builder { 437969025c012f4a8bd7bccda7216d76fc4636590feXyan Bhatnagar private Context mAppContext; 438d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar @Nullable 439d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar private Worker mWorker; 440e326592ec414dfe4c002e2840d9fc4aef0ee8747Rahul Ravikumar private Configuration mConfiguration; 441969025c012f4a8bd7bccda7216d76fc4636590feXyan Bhatnagar private WorkDatabase mWorkDatabase; 442969025c012f4a8bd7bccda7216d76fc4636590feXyan Bhatnagar private String mWorkSpecId; 443969025c012f4a8bd7bccda7216d76fc4636590feXyan Bhatnagar private ExecutionListener mListener; 444137c84c9c8212a44ee81c238a1a2271637ffa24bSumir Kataria private List<Scheduler> mSchedulers; 4457b5c560e4098585f73564951621060de708e441fSumir Kataria private Extras.RuntimeExtras mRuntimeExtras; 446969025c012f4a8bd7bccda7216d76fc4636590feXyan Bhatnagar 447d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar public Builder(@NonNull Context context, 448e326592ec414dfe4c002e2840d9fc4aef0ee8747Rahul Ravikumar @NonNull Configuration configuration, 449969025c012f4a8bd7bccda7216d76fc4636590feXyan Bhatnagar @NonNull WorkDatabase database, 450969025c012f4a8bd7bccda7216d76fc4636590feXyan Bhatnagar @NonNull String workSpecId) { 451969025c012f4a8bd7bccda7216d76fc4636590feXyan Bhatnagar mAppContext = context.getApplicationContext(); 452e326592ec414dfe4c002e2840d9fc4aef0ee8747Rahul Ravikumar mConfiguration = configuration; 453969025c012f4a8bd7bccda7216d76fc4636590feXyan Bhatnagar mWorkDatabase = database; 454969025c012f4a8bd7bccda7216d76fc4636590feXyan Bhatnagar mWorkSpecId = workSpecId; 455969025c012f4a8bd7bccda7216d76fc4636590feXyan Bhatnagar } 456969025c012f4a8bd7bccda7216d76fc4636590feXyan Bhatnagar 457d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar /** 458d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar * @param listener The {@link ExecutionListener} which gets notified on completion of the 459d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar * {@link Worker} with the given {@code workSpecId}. 460d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar * @return The instance of {@link Builder} for chaining. 461d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar */ 462d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar public Builder withListener(ExecutionListener listener) { 463969025c012f4a8bd7bccda7216d76fc4636590feXyan Bhatnagar mListener = listener; 464969025c012f4a8bd7bccda7216d76fc4636590feXyan Bhatnagar return this; 465969025c012f4a8bd7bccda7216d76fc4636590feXyan Bhatnagar } 466969025c012f4a8bd7bccda7216d76fc4636590feXyan Bhatnagar 467d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar /** 468681a8d809fe41189c9d590d33b986b98170e4963Sumir Kataria * @param schedulers The list of {@link Scheduler}s used for scheduling {@link Worker}s. 469d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar * @return The instance of {@link Builder} for chaining. 470d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar */ 471d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar public Builder withSchedulers(List<Scheduler> schedulers) { 472137c84c9c8212a44ee81c238a1a2271637ffa24bSumir Kataria mSchedulers = schedulers; 473b7a9f83e8ec6365bfd9057e30bfa5f73270ed12dSumir Kataria return this; 474b7a9f83e8ec6365bfd9057e30bfa5f73270ed12dSumir Kataria } 475b7a9f83e8ec6365bfd9057e30bfa5f73270ed12dSumir Kataria 476d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar /** 4777b5c560e4098585f73564951621060de708e441fSumir Kataria * @param runtimeExtras The {@link Extras.RuntimeExtras} for the {@link Worker}. 478681a8d809fe41189c9d590d33b986b98170e4963Sumir Kataria * @return The instance of {@link Builder} for chaining. 479681a8d809fe41189c9d590d33b986b98170e4963Sumir Kataria */ 4807b5c560e4098585f73564951621060de708e441fSumir Kataria public Builder withRuntimeExtras(Extras.RuntimeExtras runtimeExtras) { 481681a8d809fe41189c9d590d33b986b98170e4963Sumir Kataria mRuntimeExtras = runtimeExtras; 482681a8d809fe41189c9d590d33b986b98170e4963Sumir Kataria return this; 483681a8d809fe41189c9d590d33b986b98170e4963Sumir Kataria } 484681a8d809fe41189c9d590d33b986b98170e4963Sumir Kataria 485681a8d809fe41189c9d590d33b986b98170e4963Sumir Kataria /** 486d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar * @param worker The instance of {@link Worker} to be executed by {@link WorkerWrapper}. 487d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar * Useful in the context of testing. 488d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar * @return The instance of {@link Builder} for chaining. 489d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar */ 490d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar @VisibleForTesting 491d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar public Builder withWorker(Worker worker) { 492d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar mWorker = worker; 493d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar return this; 494d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar } 495d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar 496d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar /** 497d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar * @return The instance of {@link WorkerWrapper}. 498d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar */ 499d64a1a65bd138cfeeb9ae6a595120b85e77a57f6Rahul Ravikumar public WorkerWrapper build() { 500969025c012f4a8bd7bccda7216d76fc4636590feXyan Bhatnagar return new WorkerWrapper(this); 501969025c012f4a8bd7bccda7216d76fc4636590feXyan Bhatnagar } 502969025c012f4a8bd7bccda7216d76fc4636590feXyan Bhatnagar } 503b8909f2c9c62261181e8270be8de44a69ac2b75fXyan Bhatnagar} 504