1 /*
2  * Copyright (C) 2019 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.systemui.car;
18 
19 import android.app.ActivityManager;
20 import android.car.settings.CarSettings;
21 import android.content.ContentResolver;
22 import android.content.Context;
23 import android.database.ContentObserver;
24 import android.net.Uri;
25 import android.provider.Settings;
26 
27 import com.android.systemui.Dependency;
28 
29 import java.util.ArrayList;
30 
31 /**
32  * A controller that monitors the status of SUW progress for each user.
33  */
34 public class SUWProgressController {
35     private static final Uri USER_SETUP_IN_PROGRESS_URI = Settings.Secure.getUriFor(
36             CarSettings.Secure.KEY_SETUP_WIZARD_IN_PROGRESS);
37     private final ArrayList<SUWProgressListener> mListeners = new ArrayList<>();
38     private final ContentObserver mCarSettingsObserver = new ContentObserver(
39             Dependency.get(Dependency.MAIN_HANDLER)) {
40         @Override
41         public void onChange(boolean selfChange, Uri uri, int userId) {
42             if (USER_SETUP_IN_PROGRESS_URI.equals(uri)) {
43                 notifyUserSetupInProgressChanged();
44             }
45         }
46     };
47     private final ContentResolver mContentResolver;
48 
SUWProgressController(Context context)49     public SUWProgressController(Context context) {
50         mContentResolver = context.getContentResolver();
51     }
52 
53     /**
54      * Returns {@code true} then SUW is in progress for the given user.
55      */
isUserSetupInProgress(int user)56     public boolean isUserSetupInProgress(int user) {
57         return Settings.Secure.getIntForUser(mContentResolver,
58                 CarSettings.Secure.KEY_SETUP_WIZARD_IN_PROGRESS, /* def= */ 0, user) != 0;
59     }
60 
61     /**
62      * Returns {@code true} then SUW is in progress for the current user.
63      */
isCurrentUserSetupInProgress()64     public boolean isCurrentUserSetupInProgress() {
65         return isUserSetupInProgress(ActivityManager.getCurrentUser());
66     }
67 
68     /**
69      * Adds a {@link SUWProgressListener} callback.
70      */
addCallback(SUWProgressListener listener)71     public void addCallback(SUWProgressListener listener) {
72         mListeners.add(listener);
73         if (mListeners.size() == 1) {
74             startListening(ActivityManager.getCurrentUser());
75         }
76         listener.onUserSetupInProgressChanged();
77     }
78 
79     /**
80      * Removes a {@link SUWProgressListener} callback.
81      */
removeCallback(SUWProgressListener listener)82     public void removeCallback(SUWProgressListener listener) {
83         mListeners.remove(listener);
84         if (mListeners.size() == 0) {
85             stopListening();
86         }
87     }
88 
startListening(int user)89     private void startListening(int user) {
90         mContentResolver.registerContentObserver(
91                 USER_SETUP_IN_PROGRESS_URI, /* notifyForDescendants= */ true, mCarSettingsObserver,
92                 user);
93     }
94 
stopListening()95     private void stopListening() {
96         mContentResolver.unregisterContentObserver(mCarSettingsObserver);
97     }
98 
99     /**
100      * Allows SUWProgressController to switch its listeners to observe SUW progress for new user.
101      */
onUserSwitched()102     public void onUserSwitched() {
103         if (mListeners.size() == 0) {
104             return;
105         }
106 
107         mContentResolver.unregisterContentObserver(mCarSettingsObserver);
108         mContentResolver.registerContentObserver(
109                 USER_SETUP_IN_PROGRESS_URI, /* notifyForDescendants= */ true, mCarSettingsObserver,
110                 ActivityManager.getCurrentUser());
111     }
112 
notifyUserSetupInProgressChanged()113     private void notifyUserSetupInProgressChanged() {
114         for (int i = mListeners.size() - 1; i >= 0; --i) {
115             mListeners.get(i).onUserSetupInProgressChanged();
116         }
117     }
118 
119     /**
120      * A listener that listens for changes in SUW progress for a user.
121      */
122     public interface SUWProgressListener {
123         /**
124          * A callback for when a change occurs in SUW progress for a user.
125          */
onUserSetupInProgressChanged()126         default void onUserSetupInProgressChanged() {
127         }
128     }
129 }
130