1 /*
2  * Copyright (C) 2023 The Android Open Source Project
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  *      http://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 package com.android.devicelockcontroller.provision.worker;
18 
19 import android.content.Context;
20 import android.telephony.TelephonyManager;
21 
22 import androidx.annotation.NonNull;
23 import androidx.annotation.VisibleForTesting;
24 import androidx.work.Data;
25 import androidx.work.WorkerParameters;
26 
27 import com.android.devicelockcontroller.provision.grpc.DeviceCheckInClient;
28 import com.android.devicelockcontroller.provision.grpc.IsDeviceInApprovedCountryGrpcResponse;
29 import com.android.devicelockcontroller.stats.StatsLoggerProvider;
30 import com.android.devicelockcontroller.util.LogUtil;
31 
32 import com.google.common.util.concurrent.Futures;
33 import com.google.common.util.concurrent.ListenableFuture;
34 import com.google.common.util.concurrent.ListeningExecutorService;
35 
36 import java.util.Objects;
37 
38 /**
39  * A worker class dedicated to check whether device is in approved country.
40  * Note that this worker always returns {@link androidx.work.ListenableWorker.Result.Success}
41  * regardless of the success of the underlying rpc.
42  * This worker only returns a successful result if it gets the country eligibility information from
43  * the server.
44  */
45 public final class IsDeviceInApprovedCountryWorker extends AbstractCheckInWorker {
46 
47     public static final String KEY_IS_IN_APPROVED_COUNTRY = "is-in-approved-country";
48 
IsDeviceInApprovedCountryWorker(@onNull Context context, @NonNull WorkerParameters workerParams, ListeningExecutorService executorService)49     public IsDeviceInApprovedCountryWorker(@NonNull Context context,
50             @NonNull WorkerParameters workerParams, ListeningExecutorService executorService) {
51         super(context, workerParams, null, executorService);
52     }
53 
54     @VisibleForTesting
IsDeviceInApprovedCountryWorker(@onNull Context context, @NonNull WorkerParameters workerParameters, DeviceCheckInClient client, ListeningExecutorService executorService)55     IsDeviceInApprovedCountryWorker(@NonNull Context context,
56             @NonNull WorkerParameters workerParameters,
57             DeviceCheckInClient client, ListeningExecutorService executorService) {
58         super(context, workerParameters, client, executorService);
59     }
60 
61     @NonNull
62     @Override
startWork()63     public ListenableFuture<Result> startWork() {
64         return Futures.transform(mClient, client -> {
65             String carrierInfo = Objects.requireNonNull(
66                     mContext.getSystemService(TelephonyManager.class)).getSimOperator();
67             IsDeviceInApprovedCountryGrpcResponse response =
68                     client.isDeviceInApprovedCountry(carrierInfo);
69             ((StatsLoggerProvider) mContext.getApplicationContext()).getStatsLogger()
70                     .logIsDeviceInApprovedCountry();
71             if (response.hasRecoverableError()) {
72                 LogUtil.w(TAG, "Is in approve country failed w/ recoverable error " + response
73                         + "\nRetrying...");
74                 return Result.retry();
75             }
76             Data.Builder builder = new Data.Builder();
77             if (response.isSuccessful()) {
78                 return Result.success(builder.putBoolean(KEY_IS_IN_APPROVED_COUNTRY,
79                         response.isDeviceInApprovedCountry()).build());
80             }
81             return Result.failure();
82         }, mExecutorService);
83     }
84 }
85