/* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.customization.model.grid; import android.content.Context; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.util.Log; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import androidx.lifecycle.LiveData; import com.android.customization.model.CustomizationManager; import com.android.customization.module.CustomizationInjector; import com.android.customization.module.ThemesUserEventLogger; import com.android.wallpaper.R; import com.android.wallpaper.module.InjectorProvider; import com.android.wallpaper.util.PreviewUtils; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * {@link CustomizationManager} for interfacing with the launcher to handle {@link GridOption}s. */ public class GridOptionsManager implements CustomizationManager { private static final ExecutorService sExecutorService = Executors.newSingleThreadExecutor(); private static final String TAG = "GridOptionsManager"; private static GridOptionsManager sGridOptionsManager; private final LauncherGridOptionsProvider mProvider; private final ThemesUserEventLogger mEventLogger; private int mGridOptionSize = -1; /** Returns the {@link GridOptionsManager} instance. */ public static GridOptionsManager getInstance(Context context) { if (sGridOptionsManager == null) { Context appContext = context.getApplicationContext(); CustomizationInjector injector = (CustomizationInjector) InjectorProvider.getInjector(); ThemesUserEventLogger eventLogger = (ThemesUserEventLogger) injector.getUserEventLogger( appContext); sGridOptionsManager = new GridOptionsManager( new LauncherGridOptionsProvider(appContext, appContext.getString(R.string.grid_control_metadata_name)), eventLogger); } return sGridOptionsManager; } @VisibleForTesting GridOptionsManager(LauncherGridOptionsProvider provider, ThemesUserEventLogger logger) { mProvider = provider; mEventLogger = logger; } @Override public boolean isAvailable() { if (mGridOptionSize < 0) { try { mGridOptionSize = sExecutorService.submit(() -> { List gridOptions = mProvider.fetch(/* reload= */true); return gridOptions == null ? 0 : gridOptions.size(); }).get(); } catch (InterruptedException | ExecutionException e) { Log.w(TAG, "could not get gridOptionSize", e); } } return mGridOptionSize > 1 && mProvider.areGridsAvailable(); } @Override public void apply(GridOption option, Callback callback) { int updated = mProvider.applyGrid(option.name); if (updated == 1) { mEventLogger.logGridApplied(option); callback.onSuccess(); } else { callback.onError(null); } } @Override public void fetchOptions(OptionsFetchedListener callback, boolean reload) { sExecutorService.submit(() -> { List gridOptions = mProvider.fetch(reload); new Handler(Looper.getMainLooper()).post(() -> { if (callback != null) { if (gridOptions != null && !gridOptions.isEmpty()) { callback.onOptionsLoaded(gridOptions); } else { callback.onError(null); } } }); }); } /** * Returns an observable that receives a new value each time that the grid options are changed. */ public LiveData getOptionChangeObservable(@Nullable Handler handler) { return mProvider.getOptionChangeObservable(handler); } /** Call through content provider API to render preview */ public void renderPreview(Bundle bundle, String gridName, PreviewUtils.WorkspacePreviewCallback callback) { mProvider.renderPreview(gridName, bundle, callback); } }