• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package com.android.settings.dream;
18 
19 import android.app.settings.SettingsEnums;
20 import android.content.Context;
21 import android.graphics.drawable.Drawable;
22 
23 import androidx.annotation.Nullable;
24 import androidx.preference.Preference;
25 import androidx.preference.PreferenceScreen;
26 import androidx.recyclerview.widget.RecyclerView;
27 
28 import com.android.settings.R;
29 import com.android.settings.core.BasePreferenceController;
30 import com.android.settings.overlay.FeatureFactory;
31 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
32 import com.android.settingslib.dream.DreamBackend;
33 import com.android.settingslib.dream.DreamBackend.DreamInfo;
34 import com.android.settingslib.widget.LayoutPreference;
35 
36 import java.util.HashSet;
37 import java.util.List;
38 import java.util.stream.Collectors;
39 
40 /**
41  * Controller for the dream picker where the user can select a screensaver.
42  */
43 public class DreamPickerController extends BasePreferenceController {
44     public static final String PREF_KEY = "dream_picker";
45 
46     private final DreamBackend mBackend;
47     private final MetricsFeatureProvider mMetricsFeatureProvider;
48     private final List<DreamInfo> mDreamInfos;
49     @Nullable
50     private DreamInfo mActiveDream;
51     private DreamAdapter mAdapter;
52 
53     private final HashSet<Callback> mCallbacks = new HashSet<>();
54 
DreamPickerController(Context context)55     public DreamPickerController(Context context) {
56         this(context, DreamBackend.getInstance(context));
57     }
58 
DreamPickerController(Context context, DreamBackend backend)59     public DreamPickerController(Context context, DreamBackend backend) {
60         super(context, PREF_KEY);
61         mBackend = backend;
62         mDreamInfos = mBackend.getDreamInfos();
63         mActiveDream = getActiveDreamInfo(mDreamInfos);
64         mMetricsFeatureProvider = FeatureFactory.getFeatureFactory().getMetricsFeatureProvider();
65     }
66 
67     @Override
getAvailabilityStatus()68     public int getAvailabilityStatus() {
69         return mDreamInfos.size() > 0 ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
70     }
71 
72     @Override
displayPreference(PreferenceScreen screen)73     public void displayPreference(PreferenceScreen screen) {
74         super.displayPreference(screen);
75 
76         mAdapter = new DreamAdapter(R.layout.dream_preference_layout,
77                 mDreamInfos.stream()
78                         .map(DreamItem::new)
79                         .collect(Collectors.toList()));
80 
81         mAdapter.setEnabled(mBackend.isEnabled());
82 
83         final LayoutPreference pref = screen.findPreference(getPreferenceKey());
84         if (pref == null) {
85             return;
86         }
87         final RecyclerView recyclerView = pref.findViewById(R.id.dream_list);
88         recyclerView.setLayoutManager(new AutoFitGridLayoutManager(mContext));
89         recyclerView.addItemDecoration(
90                 new GridSpacingItemDecoration(mContext, R.dimen.dream_preference_card_padding));
91         recyclerView.setHasFixedSize(true);
92         recyclerView.setAdapter(mAdapter);
93     }
94 
95     @Override
updateState(Preference preference)96     public void updateState(Preference preference) {
97         super.updateState(preference);
98         if (mAdapter != null) {
99             mAdapter.setEnabled(preference.isEnabled());
100         }
101     }
102 
103     @Nullable
getActiveDreamInfo()104     public DreamInfo getActiveDreamInfo() {
105         return mActiveDream;
106     }
107 
108     @Nullable
getActiveDreamInfo(List<DreamInfo> dreamInfos)109     private static DreamInfo getActiveDreamInfo(List<DreamInfo> dreamInfos) {
110         return dreamInfos
111                 .stream()
112                 .filter(d -> d.isActive)
113                 .findFirst()
114                 .orElse(null);
115     }
116 
addCallback(Callback callback)117     void addCallback(Callback callback) {
118         mCallbacks.add(callback);
119     }
120 
removeCallback(Callback callback)121     void removeCallback(Callback callback) {
122         mCallbacks.remove(callback);
123     }
124 
125     interface Callback {
126         // Triggered when the selected dream changes.
onActiveDreamChanged()127         void onActiveDreamChanged();
128     }
129 
130     private class DreamItem implements IDreamItem {
131         DreamInfo mDreamInfo;
132 
DreamItem(DreamInfo dreamInfo)133         DreamItem(DreamInfo dreamInfo) {
134             mDreamInfo = dreamInfo;
135         }
136 
137         @Override
getTitle()138         public CharSequence getTitle() {
139             return mDreamInfo.caption;
140         }
141 
142         @Override
getSummary()143         public CharSequence getSummary() {
144             return mDreamInfo.description;
145         }
146 
147         @Override
getIcon()148         public Drawable getIcon() {
149             return mDreamInfo.icon;
150         }
151 
152         @Override
onItemClicked()153         public void onItemClicked() {
154             mActiveDream = mDreamInfo;
155             mBackend.setActiveDream(mDreamInfo.componentName);
156             mCallbacks.forEach(Callback::onActiveDreamChanged);
157             mMetricsFeatureProvider.action(SettingsEnums.PAGE_UNKNOWN,
158                     SettingsEnums.ACTION_DREAM_SELECT_TYPE, SettingsEnums.DREAM,
159                     mDreamInfo.componentName.flattenToString(), 1);
160         }
161 
162         @Override
onCustomizeClicked()163         public void onCustomizeClicked() {
164             mBackend.launchSettings(mContext, mDreamInfo);
165         }
166 
167         @Override
getPreviewImage()168         public Drawable getPreviewImage() {
169             return mDreamInfo.previewImage;
170         }
171 
172         @Override
isActive()173         public boolean isActive() {
174             if (!mAdapter.getEnabled() || mActiveDream == null) {
175                 return false;
176             }
177             return mDreamInfo.componentName.equals(mActiveDream.componentName);
178         }
179 
180         @Override
allowCustomization()181         public boolean allowCustomization() {
182             return isActive() && mDreamInfo.settingsComponentName != null;
183         }
184     }
185 }
186