1 /*
2  * Copyright (C) 2022 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 package com.android.adservices.ui.settings.viewmodels;
17 
18 import android.app.Application;
19 import android.os.Build;
20 import android.util.Pair;
21 
22 import androidx.annotation.NonNull;
23 import androidx.annotation.RequiresApi;
24 import androidx.lifecycle.AndroidViewModel;
25 import androidx.lifecycle.LiveData;
26 import androidx.lifecycle.MutableLiveData;
27 
28 import com.android.adservices.service.consent.App;
29 import com.android.adservices.service.consent.ConsentManager;
30 import com.android.adservices.ui.settings.fragments.AdServicesSettingsAppsFragment;
31 import com.android.adservices.ui.settings.fragments.AdServicesSettingsBlockedAppsFragment;
32 import com.android.internal.annotations.VisibleForTesting;
33 
34 import com.google.common.collect.ImmutableList;
35 
36 import java.io.IOException;
37 
38 /**
39  * View model for the apps view and blocked apps view of the AdServices Settings App. This view
40  * model is responsible for serving apps to the apps view and blocked apps view, and interacting
41  * with the {@link ConsentManager} that persists and changes the apps data in a storage.
42  */
43 @RequiresApi(Build.VERSION_CODES.S)
44 public class BlockedAppsViewModel extends AndroidViewModel {
45 
46     private final MutableLiveData<Pair<BlockedAppsViewModelUiEvent, App>> mEventTrigger =
47             new MutableLiveData<>();
48     private final MutableLiveData<ImmutableList<App>> mBlockedApps;
49     private final ConsentManager mConsentManager;
50 
51     /** UI event triggered by view model */
52     public enum BlockedAppsViewModelUiEvent {
53         RESTORE_APP,
54     }
55 
BlockedAppsViewModel(@onNull Application application)56     public BlockedAppsViewModel(@NonNull Application application) {
57         super(application);
58 
59         mConsentManager = ConsentManager.getInstance();
60         mBlockedApps = new MutableLiveData<>(getBlockedAppsFromConsentManager());
61     }
62 
63     @VisibleForTesting
BlockedAppsViewModel(@onNull Application application, ConsentManager consentManager)64     public BlockedAppsViewModel(@NonNull Application application, ConsentManager consentManager) {
65         super(application);
66 
67         mConsentManager = consentManager;
68         mBlockedApps = new MutableLiveData<>(getBlockedAppsFromConsentManager());
69     }
70 
71     /**
72      * Provides the blocked apps displayed in {@link AdServicesSettingsBlockedAppsFragment}.
73      *
74      * @return a list of apps that represents the user's blocked interests.
75      */
getBlockedApps()76     public LiveData<ImmutableList<App>> getBlockedApps() {
77         return mBlockedApps;
78     }
79 
80     /**
81      * Restore the consent for the specified app (i.e. unblock the app).
82      *
83      * @param app the app to be restored.
84      */
restoreAppConsent(App app)85     public void restoreAppConsent(App app) throws IOException {
86         mConsentManager.restoreConsentForApp(app);
87         refresh();
88     }
89 
90     /**
91      * Reads all the data from {@link ConsentManager}.
92      *
93      * <p>TODO(b/238387560): To be moved to private when is fixed.
94      */
refresh()95     public void refresh() {
96         mBlockedApps.postValue(getBlockedAppsFromConsentManager());
97     }
98 
99     /** Returns an observable but immutable event enum representing a view action on UI. */
getUiEvents()100     public LiveData<Pair<BlockedAppsViewModelUiEvent, App>> getUiEvents() {
101         return mEventTrigger;
102     }
103 
104     /**
105      * Sets the UI Event as handled so the action will not be handled again if activity is
106      * recreated.
107      */
uiEventHandled()108     public void uiEventHandled() {
109         mEventTrigger.postValue(new Pair<>(null, null));
110     }
111 
112     /**
113      * Triggers the block of the specified app in the list of apps in {@link
114      * AdServicesSettingsAppsFragment}.
115      *
116      * @param app the app to be blocked.
117      */
restoreAppConsentButtonClickHandler(App app)118     public void restoreAppConsentButtonClickHandler(App app) {
119         mEventTrigger.postValue(new Pair<>(BlockedAppsViewModelUiEvent.RESTORE_APP, app));
120     }
121 
getBlockedAppsFromConsentManager()122     private ImmutableList<App> getBlockedAppsFromConsentManager() {
123         return mConsentManager.getAppsWithRevokedConsent();
124     }
125 }
126