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.activities; 18 19 import android.text.TextUtils; 20 import android.util.Pair; 21 22 import androidx.lifecycle.MediatorLiveData; 23 import androidx.lifecycle.MutableLiveData; 24 import androidx.lifecycle.ViewModel; 25 26 import com.android.devicelockcontroller.storage.GlobalParametersClient; 27 import com.android.devicelockcontroller.storage.SetupParametersClient; 28 import com.android.devicelockcontroller.util.LogUtil; 29 30 import com.google.common.util.concurrent.FutureCallback; 31 import com.google.common.util.concurrent.Futures; 32 import com.google.common.util.concurrent.MoreExecutors; 33 34 import java.util.List; 35 36 /** 37 * This class provides the resources and {@link ProvisionInfo} to render the 38 * {@link ProvisionInfoFragment} and/or {@link ProvisionNotRequiredFragment}. 39 */ 40 public abstract class ProvisionInfoViewModel extends ViewModel { 41 42 public static final String TAG = "ProvisionInfoViewModel"; 43 public static final String PROVIDER_NAME_PLACEHOLDER = ""; 44 public static final int TEXT_ID_PLACEHOLDER = -1; 45 final MutableLiveData<Integer> mHeaderDrawableIdLiveData; 46 final MutableLiveData<Integer> mHeaderTextIdLiveData; 47 final MutableLiveData<Integer> mSubheaderTextIdLiveData; 48 final MutableLiveData<List<ProvisionInfo>> mProvisionInfoListLiveData; 49 final MutableLiveData<String> mProviderNameLiveData; 50 final MutableLiveData<String> mTermsAndConditionsUrlLiveData; 51 final MutableLiveData<Boolean> mIsProvisionForcedLiveData; 52 final MediatorLiveData<Pair<Integer, String>> mHeaderTextLiveData; 53 final MediatorLiveData<Pair<Integer, String>> mSubHeaderTextLiveData; 54 ProvisionInfoViewModel()55 public ProvisionInfoViewModel() { 56 mProvisionInfoListLiveData = new MutableLiveData<>(); 57 mHeaderDrawableIdLiveData = new MutableLiveData<>(); 58 mHeaderTextIdLiveData = new MutableLiveData<>(); 59 mSubheaderTextIdLiveData = new MutableLiveData<>(); 60 mProviderNameLiveData = new MutableLiveData<>(); 61 mTermsAndConditionsUrlLiveData = new MutableLiveData<>(); 62 mIsProvisionForcedLiveData = new MutableLiveData<>(); 63 mHeaderTextLiveData = new MediatorLiveData<>(); 64 mHeaderTextLiveData.addSource(mHeaderTextIdLiveData, 65 id -> { 66 Pair<Integer, String> oldValue = mHeaderTextLiveData.getValue(); 67 mHeaderTextLiveData.setValue(oldValue == null 68 ? new Pair<>(id, PROVIDER_NAME_PLACEHOLDER) 69 : new Pair<>(id, oldValue.second)); 70 }); 71 mHeaderTextLiveData.addSource(mProviderNameLiveData, 72 providerName -> { 73 Pair<Integer, String> oldValue = mHeaderTextLiveData.getValue(); 74 mHeaderTextLiveData.setValue(oldValue == null 75 ? new Pair<>(TEXT_ID_PLACEHOLDER, providerName) 76 : new Pair<>(oldValue.first, providerName)); 77 }); 78 mSubHeaderTextLiveData = new MediatorLiveData<>(); 79 mSubHeaderTextLiveData.addSource(mSubheaderTextIdLiveData, 80 id -> { 81 Pair<Integer, String> oldValue = mSubHeaderTextLiveData.getValue(); 82 mSubHeaderTextLiveData.setValue(oldValue == null 83 ? new Pair<>(id, PROVIDER_NAME_PLACEHOLDER) 84 : new Pair<>(id, oldValue.second)); 85 }); 86 mSubHeaderTextLiveData.addSource(mProviderNameLiveData, 87 providerName -> { 88 Pair<Integer, String> oldValue = mSubHeaderTextLiveData.getValue(); 89 mSubHeaderTextLiveData.setValue(oldValue == null 90 ? new Pair<>(TEXT_ID_PLACEHOLDER, providerName) 91 : new Pair<>(oldValue.first, providerName)); 92 }); 93 94 Futures.addCallback( 95 SetupParametersClient.getInstance().getKioskAppProviderName(), 96 new FutureCallback<>() { 97 @Override 98 public void onSuccess(String providerName) { 99 if (TextUtils.isEmpty(providerName)) { 100 LogUtil.e(TAG, "Device provider name is empty, should not reach here."); 101 return; 102 } 103 mProviderNameLiveData.postValue(providerName); 104 } 105 106 @Override 107 public void onFailure(Throwable t) { 108 LogUtil.e(TAG, "Failed to get Kiosk app provider name", t); 109 } 110 }, MoreExecutors.directExecutor()); 111 112 Futures.addCallback( 113 SetupParametersClient.getInstance().getTermsAndConditionsUrl(), 114 new FutureCallback<>() { 115 @Override 116 public void onSuccess(String termsAndConditionsUrl) { 117 if (TextUtils.isEmpty(termsAndConditionsUrl)) { 118 LogUtil.e(TAG, 119 "Terms and Conditions URL is empty, should not reach here."); 120 return; 121 } 122 mTermsAndConditionsUrlLiveData.postValue(termsAndConditionsUrl); 123 } 124 125 @Override 126 public void onFailure(Throwable t) { 127 LogUtil.e(TAG, "Failed to get Terms and Conditions URL", t); 128 } 129 }, MoreExecutors.directExecutor()); 130 131 Futures.addCallback(GlobalParametersClient.getInstance().isProvisionForced(), 132 new FutureCallback<>() { 133 @Override 134 public void onSuccess(Boolean isProvisionForced) { 135 mIsProvisionForcedLiveData.postValue(isProvisionForced); 136 } 137 138 @Override 139 public void onFailure(Throwable t) { 140 LogUtil.e(TAG, "Failed to get if provision should be forced", t); 141 } 142 }, MoreExecutors.directExecutor()); 143 } 144 } 145