Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a4264fef authored by Catherine Liang's avatar Catherine Liang
Browse files

Pre-revamped UI grid cleanup

As part of the revamped UI flag removal process, clean up grid picker
related files that are no longer used.

Bug: 262780002
Test: manually verified functionalities still work throughout the
wallpaper picker app

Change-Id: I9d5b87a3a22bd1e0d4692ede47c08bcdaa6eebc8
parent fd6c1edb
Loading
Loading
Loading
Loading
+0 −53
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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 androidx.lifecycle.SavedStateHandle;
import androidx.lifecycle.ViewModel;

/** The class to store status of the grid fragment view. */
public class GridOptionViewModel extends ViewModel {
    private static final String SELECTED_OPTION_KEY = "selected_option";
    private static final String BOTTOM_ACTION_BAR_VISIBLE_KEY = "bottom_action_bar_visible";

    private SavedStateHandle mState;

    public GridOptionViewModel(SavedStateHandle savedStateHandle) {
        mState = savedStateHandle;
    }

    /** Gets selected {@link GridOption} from {@link SavedStateHandle} */
    public GridOption getSelectedOption() {
        return mState.get(SELECTED_OPTION_KEY);
    }

    /** Sets selected {@link GridOption} to {@link SavedStateHandle} */
    public void setSelectedOption(GridOption selectedOption) {
        mState.set(SELECTED_OPTION_KEY, selectedOption);
    }

    /** Gets bottom action bar visible from {@link SavedStateHandle} */
    public boolean getBottomActionBarVisible() {
        return mState.contains(BOTTOM_ACTION_BAR_VISIBLE_KEY)
                ? mState.get(BOTTOM_ACTION_BAR_VISIBLE_KEY)
                : false;
    }

    /** Sets bottom action bar visible to {@link SavedStateHandle} */
    public void setBottomActionBarVisible(boolean bottomActionBarVisible) {
        mState.set(BOTTOM_ACTION_BAR_VISIBLE_KEY, bottomActionBarVisible);
    }
}
+5 −15
Original line number Diff line number Diff line
@@ -28,7 +28,6 @@ import androidx.lifecycle.Observer;

import com.android.customization.model.CustomizationManager.OptionsFetchedListener;
import com.android.customization.model.grid.ui.fragment.GridFragment2;
import com.android.customization.picker.grid.GridFragment;
import com.android.customization.picker.grid.GridSectionView;
import com.android.wallpaper.R;
import com.android.wallpaper.model.CustomizationSectionController;
@@ -42,7 +41,6 @@ public class GridSectionController implements CustomizationSectionController<Gri

    private final GridOptionsManager mGridOptionsManager;
    private final CustomizationSectionNavigationController mSectionNavigationController;
    private final boolean mIsRevampedUiEnabled;
    private final Observer<Object> mOptionChangeObserver;
    private final LifecycleOwner mLifecycleOwner;
    private TextView mSectionDescription;
@@ -55,7 +53,6 @@ public class GridSectionController implements CustomizationSectionController<Gri
            boolean isRevampedUiEnabled) {
        mGridOptionsManager = gridOptionsManager;
        mSectionNavigationController = sectionNavigationController;
        mIsRevampedUiEnabled = isRevampedUiEnabled;
        mLifecycleOwner = lifecycleOwner;
        mOptionChangeObserver = o -> updateUi(/* reload= */ true);
    }
@@ -74,20 +71,13 @@ public class GridSectionController implements CustomizationSectionController<Gri

        // Fetch grid options to show currently set grid.
        updateUi(/* The result is getting when calling isAvailable(), so reload= */ false);
        if (mIsRevampedUiEnabled) {
        mGridOptionsManager.getOptionChangeObservable(/* handler= */ null).observe(
                mLifecycleOwner,
                mOptionChangeObserver);
        }

        gridSectionView.setOnClickListener(
                v -> {
                    final Fragment gridFragment;
                    if (mIsRevampedUiEnabled) {
                        gridFragment = new GridFragment2();
                    } else {
                        gridFragment = new GridFragment();
                    }
                    final Fragment gridFragment = new GridFragment2();
                    mSectionNavigationController.navigateTo(gridFragment);
                });

@@ -96,7 +86,7 @@ public class GridSectionController implements CustomizationSectionController<Gri

    @Override
    public void release() {
        if (mIsRevampedUiEnabled && mGridOptionsManager.isAvailable()) {
        if (mGridOptionsManager.isAvailable()) {
            mGridOptionsManager.getOptionChangeObservable(/* handler= */ null).removeObserver(
                    mOptionChangeObserver
            );
+0 −299
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 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.picker.grid;

import static com.android.wallpaper.widget.BottomActionBar.BottomAction.APPLY_TEXT;

import android.content.Context;
import android.graphics.Point;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityManager;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.constraintlayout.widget.ConstraintSet;
import androidx.core.widget.ContentLoadingProgressBar;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.RecyclerView;

import com.android.customization.model.CustomizationManager.Callback;
import com.android.customization.model.CustomizationManager.OptionsFetchedListener;
import com.android.customization.model.CustomizationOption;
import com.android.customization.model.grid.GridOption;
import com.android.customization.model.grid.GridOptionViewModel;
import com.android.customization.model.grid.GridOptionsManager;
import com.android.customization.module.ThemesUserEventLogger;
import com.android.customization.picker.WallpaperPreviewer;
import com.android.customization.widget.OptionSelectorController;
import com.android.customization.widget.OptionSelectorController.CheckmarkStyle;
import com.android.wallpaper.R;
import com.android.wallpaper.model.WallpaperInfo;
import com.android.wallpaper.module.CurrentWallpaperInfoFactory;
import com.android.wallpaper.module.InjectorProvider;
import com.android.wallpaper.picker.AppbarFragment;
import com.android.wallpaper.util.LaunchUtils;
import com.android.wallpaper.util.ScreenSizeCalculator;
import com.android.wallpaper.widget.BottomActionBar;

import com.bumptech.glide.Glide;

import java.util.List;
import java.util.Locale;

/**
 * Fragment that contains the UI for selecting and applying a GridOption.
 */
public class GridFragment extends AppbarFragment {

    private static final String TAG = "GridFragment";

    private WallpaperInfo mHomeWallpaper;
    private RecyclerView mOptionsContainer;
    private OptionSelectorController<GridOption> mOptionsController;
    private GridOptionsManager mGridManager;
    private ContentLoadingProgressBar mLoading;
    private ConstraintLayout mContent;
    private View mError;
    private BottomActionBar mBottomActionBar;
    private ThemesUserEventLogger mEventLogger;
    private GridOptionPreviewer mGridOptionPreviewer;
    private GridOptionViewModel mGridOptionViewModel;

    private final Callback mApplyGridCallback = new Callback() {
        @Override
        public void onSuccess() {
            mGridManager.fetchOptions(unused -> {}, true);
            Toast.makeText(getContext(), R.string.applied_grid_msg, Toast.LENGTH_SHORT).show();
            getActivity().overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
            getActivity().finish();

            // Go back to launcher home
            LaunchUtils.launchHome(getContext());
        }

        @Override
        public void onError(@Nullable Throwable throwable) {
            // Since we disabled it when clicked apply button.
            mBottomActionBar.enableActions();
            mBottomActionBar.hide();
            mGridOptionViewModel.setBottomActionBarVisible(false);
            //TODO(chihhangchuang): handle
        }
    };

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mGridOptionViewModel = new ViewModelProvider(requireActivity()).get(
                GridOptionViewModel.class);
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
            @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(
                R.layout.fragment_grid_picker, container, /* attachToRoot */ false);
        setUpToolbar(view);
        mContent = view.findViewById(R.id.content_section);
        mOptionsContainer = view.findViewById(R.id.options_container);
        AccessibilityManager accessibilityManager =
                (AccessibilityManager) getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
        if (accessibilityManager.isEnabled()) {
            // Make Talkback focus won't reset when notifyDataSetChange
            mOptionsContainer.setItemAnimator(null);
        }

        // Set aspect ratio on the preview card dynamically.
        Point mScreenSize;
        ScreenSizeCalculator screenSizeCalculator = ScreenSizeCalculator.getInstance();
        mScreenSize = screenSizeCalculator.getScreenSize(
                requireActivity().getWindowManager().getDefaultDisplay());
        ConstraintSet set = new ConstraintSet();
        set.clone(mContent);
        String ratio = String.format(Locale.US, "%d:%d", mScreenSize.x, mScreenSize.y);
        set.setDimensionRatio(R.id.preview_card_container, ratio);
        set.applyTo(mContent);

        mLoading = view.findViewById(R.id.loading_indicator);
        mError = view.findViewById(R.id.error_section);

        // For nav bar edge-to-edge effect.
        view.setOnApplyWindowInsetsListener((v, windowInsets) -> {
            v.setPadding(
                    v.getPaddingLeft(),
                    windowInsets.getSystemWindowInsetTop(),
                    v.getPaddingRight(),
                    windowInsets.getSystemWindowInsetBottom());
            return windowInsets.consumeSystemWindowInsets();
        });

        // Clear memory cache whenever grid fragment view is being loaded.
        Glide.get(getContext()).clearMemory();

        mGridManager = GridOptionsManager.getInstance(getContext());
        mEventLogger = (ThemesUserEventLogger) InjectorProvider.getInjector()
                .getUserEventLogger(getContext());
        setUpOptions();

        SurfaceView wallpaperSurface = view.findViewById(R.id.wallpaper_preview_surface);
        WallpaperPreviewer wallpaperPreviewer = new WallpaperPreviewer(getLifecycle(),
                getActivity(), view.findViewById(R.id.wallpaper_preview_image), wallpaperSurface,
                view.findViewById(R.id.grid_fadein_scrim));
        // Loads current Wallpaper.
        CurrentWallpaperInfoFactory factory = InjectorProvider.getInjector()
                .getCurrentWallpaperInfoFactory(getContext().getApplicationContext());
        factory.createCurrentWallpaperInfos((homeWallpaper, lockWallpaper, presentationMode) -> {
            mHomeWallpaper = homeWallpaper;
            wallpaperPreviewer.setWallpaper(mHomeWallpaper, /* listener= */ null);
        }, false);

        mGridOptionPreviewer = new GridOptionPreviewer(mGridManager,
                view.findViewById(R.id.grid_preview_container));

        return view;
    }

    @Override
    public boolean onBackPressed() {
        mGridOptionViewModel.setSelectedOption(null);
        mGridOptionViewModel.setBottomActionBarVisible(false);
        return super.onBackPressed();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mGridOptionPreviewer != null) {
            mGridOptionPreviewer.release();
        }
    }

    @Override
    public CharSequence getDefaultTitle() {
        return getString(R.string.grid_title);
    }

    @Override
    protected void onBottomActionBarReady(BottomActionBar bottomActionBar) {
        super.onBottomActionBarReady(bottomActionBar);
        mBottomActionBar = bottomActionBar;
        mBottomActionBar.showActionsOnly(APPLY_TEXT);
        mBottomActionBar.setActionClickListener(APPLY_TEXT,
                v -> applyGridOption(mGridOptionViewModel.getSelectedOption()));
        mBottomActionBar.setActionAccessibilityTraversalAfter(APPLY_TEXT,
                mOptionsContainer.getId());
    }

    private void applyGridOption(GridOption gridOption) {
        mBottomActionBar.disableActions();
        mGridManager.apply(gridOption, mApplyGridCallback);
    }

    private void setUpOptions() {
        hideError();
        mLoading.show();
        mGridManager.fetchOptions(new OptionsFetchedListener<GridOption>() {
            @Override
            public void onOptionsLoaded(List<GridOption> options) {
                mLoading.hide();
                mOptionsController = new OptionSelectorController<>(
                        mOptionsContainer, options, /* useGrid= */ false,
                        CheckmarkStyle.CENTER_CHANGE_COLOR_WHEN_NOT_SELECTED);
                mOptionsController.initOptions(mGridManager);
                GridOption previouslySelectedOption = findEquivalent(options,
                        mGridOptionViewModel.getSelectedOption());
                mGridOptionViewModel.setSelectedOption(
                        previouslySelectedOption != null
                                ? previouslySelectedOption
                                : getActiveOption(options));

                mOptionsController.setSelectedOption(mGridOptionViewModel.getSelectedOption());
                onOptionSelected(mGridOptionViewModel.getSelectedOption());
                restoreBottomActionBarVisibility();

                mOptionsController.addListener(selectedOption -> {
                    String title = selectedOption.getTitle();
                    int stringId = R.string.option_previewed_description;
                    if (selectedOption.isActive(mGridManager)) {
                        stringId = R.string.option_applied_previewed_description;
                    }
                    CharSequence cd = getContext().getString(stringId, title);
                    mOptionsContainer.announceForAccessibility(cd);
                    onOptionSelected(selectedOption);
                    mBottomActionBar.show();
                    mGridOptionViewModel.setBottomActionBarVisible(true);
                });
            }

            @Override
            public void onError(@Nullable Throwable throwable) {
                if (throwable != null) {
                    Log.e(TAG, "Error loading grid options", throwable);
                }
                showError();
            }
        }, /*reload= */ true);
    }

    private GridOption getActiveOption(List<GridOption> options) {
        return options.stream()
                .filter(option -> option.isActive(mGridManager))
                .findAny()
                // For development only, as there should always be a grid set.
                .orElse(options.get(0));
    }

    @Nullable
    private GridOption findEquivalent(List<GridOption> options, GridOption target) {
        return options.stream()
                .filter(option -> option.equals(target))
                .findAny()
                .orElse(null);
    }

    private void hideError() {
        mContent.setVisibility(View.VISIBLE);
        mError.setVisibility(View.GONE);
    }

    private void showError() {
        mLoading.hide();
        mContent.setVisibility(View.GONE);
        mError.setVisibility(View.VISIBLE);
    }

    private void onOptionSelected(CustomizationOption selectedOption) {
        mGridOptionViewModel.setSelectedOption((GridOption) selectedOption);
        mEventLogger.logGridSelected(mGridOptionViewModel.getSelectedOption());
        mGridOptionPreviewer.setGridOption(mGridOptionViewModel.getSelectedOption());
    }

    private void restoreBottomActionBarVisibility() {
        if (mGridOptionViewModel.getBottomActionBarVisible()) {
            mBottomActionBar.show();
        } else {
            mBottomActionBar.hide();
        }
    }
}
+0 −105
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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.picker.grid;

import android.content.Context;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.ViewGroup;

import com.android.customization.model.grid.GridOption;
import com.android.customization.model.grid.GridOptionsManager;
import com.android.wallpaper.R;
import com.android.wallpaper.picker.WorkspaceSurfaceHolderCallback;
import com.android.wallpaper.util.PreviewUtils;
import com.android.wallpaper.util.SurfaceViewUtils;

/** A class to load the {@link GridOption} preview to the view. */
class GridOptionPreviewer {

    private final GridOptionsManager mGridManager;
    private final ViewGroup mPreviewContainer;

    private SurfaceView mGridOptionSurface;
    private GridOption mGridOption;
    private GridOptionSurfaceHolderCallback mSurfaceCallback;

    GridOptionPreviewer(GridOptionsManager gridManager, ViewGroup previewContainer) {
        mGridManager = gridManager;
        mPreviewContainer = previewContainer;
    }

    /** Loads the Grid option into the container view. */
    public void setGridOption(GridOption gridOption) {
        mGridOption = gridOption;
        if (mGridOption != null) {
            updateWorkspacePreview();
        }
    }

    /** Releases the view resource. */
    public void release() {
        if (mGridOptionSurface != null) {
            mSurfaceCallback.cleanUp();
            mGridOptionSurface = null;
        }
        mPreviewContainer.removeAllViews();
    }

    private void updateWorkspacePreview() {
        // Reattach SurfaceView to trigger #surfaceCreated to update preview for different option.
        mPreviewContainer.removeAllViews();
        if (mSurfaceCallback != null) {
            mSurfaceCallback.cleanUp();
            mSurfaceCallback.resetLastSurface();
            if (mGridOptionSurface != null) {
                mGridOptionSurface.getHolder().removeCallback(mSurfaceCallback);
            }
        }
        mGridOptionSurface = new SurfaceView(mPreviewContainer.getContext());
        mGridOptionSurface.setLayoutParams(new ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        mGridOptionSurface.setZOrderMediaOverlay(true);
        mSurfaceCallback = new GridOptionSurfaceHolderCallback(mGridOptionSurface,
                mGridOptionSurface.getContext());
        mGridOptionSurface.getHolder().addCallback(mSurfaceCallback);
        mPreviewContainer.addView(mGridOptionSurface);
    }

    private class GridOptionSurfaceHolderCallback extends WorkspaceSurfaceHolderCallback {
        private GridOptionSurfaceHolderCallback(SurfaceView workspaceSurface, Context context) {
            super(
                    workspaceSurface,
                    new PreviewUtils(
                            context, context.getString(R.string.grid_control_metadata_name)));
        }

        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            if (mGridOption != null) {
                super.surfaceCreated(holder);
            }
        }

        @Override
        protected void requestPreview(SurfaceView workspaceSurface,
                PreviewUtils.WorkspacePreviewCallback callback) {
            mGridManager.renderPreview(
                    SurfaceViewUtils.createSurfaceViewRequest(workspaceSurface),
                    mGridOption.name, callback);
        }
    }
}