• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 package com.android.customization.model.grid;
17 
18 import android.content.Context;
19 import android.os.Handler;
20 import android.os.Looper;
21 import android.util.Log;
22 
23 import androidx.annotation.Nullable;
24 import androidx.annotation.VisibleForTesting;
25 import androidx.lifecycle.LiveData;
26 
27 import com.android.customization.model.CustomizationManager;
28 import com.android.customization.module.CustomizationInjector;
29 import com.android.customization.module.logging.ThemesUserEventLogger;
30 import com.android.wallpaper.R;
31 import com.android.wallpaper.module.InjectorProvider;
32 
33 import java.util.List;
34 import java.util.concurrent.ExecutionException;
35 import java.util.concurrent.ExecutorService;
36 import java.util.concurrent.Executors;
37 
38 /**
39  * {@link CustomizationManager} for interfacing with the launcher to handle {@link GridOption}s.
40  */
41 public class GridOptionsManager implements CustomizationManager<GridOption> {
42 
43     private static final ExecutorService sExecutorService = Executors.newSingleThreadExecutor();
44     private static final String TAG = "GridOptionsManager";
45 
46     private static GridOptionsManager sGridOptionsManager;
47 
48     private final LauncherGridOptionsProvider mProvider;
49     private final ThemesUserEventLogger mEventLogger;
50     private int mGridOptionSize = -1;
51 
52     /** Returns the {@link GridOptionsManager} instance. */
getInstance(Context context)53     public static GridOptionsManager getInstance(Context context) {
54         if (sGridOptionsManager == null) {
55             Context appContext = context.getApplicationContext();
56             CustomizationInjector injector = (CustomizationInjector) InjectorProvider.getInjector();
57             ThemesUserEventLogger eventLogger =
58                     (ThemesUserEventLogger) injector.getUserEventLogger();
59             sGridOptionsManager = new GridOptionsManager(
60                     new LauncherGridOptionsProvider(appContext,
61                             appContext.getString(R.string.grid_control_metadata_name)),
62                     eventLogger);
63         }
64         return sGridOptionsManager;
65     }
66 
67     @VisibleForTesting
GridOptionsManager(LauncherGridOptionsProvider provider, ThemesUserEventLogger logger)68     GridOptionsManager(LauncherGridOptionsProvider provider, ThemesUserEventLogger logger) {
69         mProvider = provider;
70         mEventLogger = logger;
71     }
72 
73     @Override
isAvailable()74     public boolean isAvailable() {
75         if (mGridOptionSize < 0) {
76             try {
77                 mGridOptionSize = sExecutorService.submit(() -> {
78                     List<GridOption> gridOptions = mProvider.fetch(/* reload= */true);
79                     return gridOptions == null ? 0 : gridOptions.size();
80                 }).get();
81             } catch (InterruptedException | ExecutionException e) {
82                 Log.w(TAG, "could not get gridOptionSize", e);
83             }
84         }
85         return mGridOptionSize > 1 && mProvider.areGridsAvailable();
86     }
87 
88     @Override
apply(GridOption option, Callback callback)89     public void apply(GridOption option, Callback callback) {
90         int updated = mProvider.applyGrid(option.name);
91         if (updated == 1) {
92             mEventLogger.logGridApplied(option);
93             callback.onSuccess();
94         } else {
95             callback.onError(null);
96         }
97     }
98 
99     @Override
preview(GridOption option)100     public void preview(GridOption option) {
101         mProvider.updateView();
102     }
103 
104     @Override
fetchOptions(OptionsFetchedListener<GridOption> callback, boolean reload)105     public void fetchOptions(OptionsFetchedListener<GridOption> callback, boolean reload) {
106         sExecutorService.submit(() -> {
107             List<GridOption> gridOptions = mProvider.fetch(reload);
108             new Handler(Looper.getMainLooper()).post(() -> {
109                 if (callback != null) {
110                     if (gridOptions != null && !gridOptions.isEmpty()) {
111                         callback.onOptionsLoaded(gridOptions);
112                     } else {
113                         callback.onError(null);
114                     }
115                 }
116             });
117         });
118     }
119 
120     /**
121      * Returns an observable that receives a new value each time that the grid options are changed.
122      */
getOptionChangeObservable(@ullable Handler handler)123     public LiveData<Object> getOptionChangeObservable(@Nullable Handler handler) {
124         return mProvider.getOptionChangeObservable(handler);
125     }
126 }
127