1+ /*
2+ * Copyright 2020 Google LLC
3+ *
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
6+ * You may obtain a copy of the License at
7+ *
8+ * https://www.apache.org/licenses/LICENSE-2.0
9+ *
10+ * Unless required by applicable law or agreed to in writing, software
11+ * distributed under the License is distributed on an "AS IS" BASIS,
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ * See the License for the specific language governing permissions and
14+ * limitations under the License.
15+ *
16+ */
17+
18+ package org .pathcheck .covidsafepaths .exposurenotifications .nearby ;
19+
20+ import android .content .Context ;
21+ import android .content .Intent ;
22+ import android .util .Log ;
23+ import androidx .annotation .NonNull ;
24+ import androidx .work .ListenableWorker ;
25+ import androidx .work .OneTimeWorkRequest ;
26+ import androidx .work .WorkManager ;
27+ import androidx .work .WorkerParameters ;
28+ import com .facebook .react .bridge .ReactContext ;
29+ import com .google .common .util .concurrent .FluentFuture ;
30+ import com .google .common .util .concurrent .ListenableFuture ;
31+ import org .pathcheck .covidsafepaths .MainApplication ;
32+ import org .pathcheck .covidsafepaths .bridge .EventSender ;
33+ import org .pathcheck .covidsafepaths .exposurenotifications .ExposureNotificationClientWrapper ;
34+ import org .pathcheck .covidsafepaths .exposurenotifications .common .AppExecutors ;
35+ import org .pathcheck .covidsafepaths .exposurenotifications .common .NotificationHelper ;
36+ import org .pathcheck .covidsafepaths .exposurenotifications .storage .RealmSecureStorageBte ;
37+
38+
39+ /**
40+ * Performs work for
41+ * {@value com.google.android.gms.nearby.exposurenotification.ExposureNotificationClient#ACTION_EXPOSURE_STATE_UPDATED}
42+ * broadcast from exposure notification API.
43+ */
44+ public class StateUpdatedWorker extends ListenableWorker {
45+ private static final String TAG = "StateUpdatedWorker" ;
46+
47+ private final Context context ;
48+
49+ public StateUpdatedWorker (@ NonNull Context context , @ NonNull WorkerParameters workerParams ) {
50+ super (context , workerParams );
51+ this .context = context ;
52+ }
53+
54+ @ NonNull
55+ @ Override
56+ public ListenableFuture <Result > startWork () {
57+ Log .d (TAG , "Starting worker to get exposure windows, "
58+ + "compare them with the exposures stored in the local database "
59+ + "and show a notification if there is a new one" );
60+ return FluentFuture .from (ExposureNotificationClientWrapper .get (context ).getDailySummaries ())
61+ .transform (RealmSecureStorageBte .INSTANCE ::refreshWithDailySummaries , AppExecutors .getBackgroundExecutor ())
62+ .transform (exposureResult -> {
63+
64+ if (exposureResult .getNewExposureAdded ()) {
65+ Log .d (TAG , "New exposures found, showing a notification" );
66+ NotificationHelper .showPossibleExposureNotification (context );
67+
68+ MainApplication app = (MainApplication ) getApplicationContext ();
69+ ReactContext reactContext = app .getReactNativeHost ()
70+ .getReactInstanceManager ()
71+ .getCurrentReactContext ();
72+
73+ if (reactContext != null ) {
74+ EventSender .INSTANCE .sendExposureRecordUpdatedChangedEvent (reactContext , exposureResult .getExposures ());
75+ }
76+
77+ } else {
78+ Log .d (TAG , "No new exposures found" );
79+ }
80+ return Result .success ();
81+ }, AppExecutors .getLightweightExecutor ())
82+ .catching (Exception .class , exception -> {
83+ Log .e (TAG , "Failure to update app state (tokens, etc) from exposure summary." , exception );
84+ return Result .failure ();
85+ },
86+ AppExecutors .getLightweightExecutor ()
87+ );
88+ }
89+
90+ static void runOnce (Context context , Intent intent ) {
91+ WorkManager .getInstance (context ).enqueue (
92+ new OneTimeWorkRequest .Builder (StateUpdatedWorker .class )
93+ .build ());
94+ }
95+ }
0 commit comments