summaryrefslogtreecommitdiff
path: root/src/com/android/customization
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/customization')
-rw-r--r--src/com/android/customization/model/grid/GridOption.java11
-rw-r--r--src/com/android/customization/model/grid/GridOptionViewModel.java53
-rw-r--r--src/com/android/customization/model/grid/GridSectionController.java4
-rw-r--r--src/com/android/customization/model/mode/DarkModeSectionController.java6
-rw-r--r--src/com/android/customization/module/DefaultCustomizationInjector.java4
-rw-r--r--src/com/android/customization/picker/grid/GridFragment.java98
-rw-r--r--src/com/android/customization/widget/OptionSelectorController.java73
7 files changed, 161 insertions, 88 deletions
diff --git a/src/com/android/customization/model/grid/GridOption.java b/src/com/android/customization/model/grid/GridOption.java
index 16a5eb01..19c5d4f1 100644
--- a/src/com/android/customization/model/grid/GridOption.java
+++ b/src/com/android/customization/model/grid/GridOption.java
@@ -93,11 +93,18 @@ public class GridOption implements CustomizationOption<GridOption>, Parcelable {
Context context = view.getContext();
int colorFilter = ResourceUtils.getColorAttr(context,
- view.isActivated() ? android.R.attr.textColorPrimary :
- android.R.attr.textColorTertiary);
+ view.isActivated()
+ ? (mIsCurrent
+ ? android.R.attr.textColorPrimary
+ : android.R.attr.textColorPrimaryInverse)
+ : android.R.attr.textColorTertiary);
mTileDrawable.setColorFilter(colorFilter, Mode.SRC_ATOP);
((ImageView) view.findViewById(R.id.grid_option_thumbnail))
.setImageDrawable(mTileDrawable);
+
+ int backgroundResource = view.isActivated() && !mIsCurrent
+ ? R.drawable.option_border_new_selection : R.drawable.option_border;
+ view.findViewById(R.id.option_tile).setBackgroundResource(backgroundResource);
}
@Override
diff --git a/src/com/android/customization/model/grid/GridOptionViewModel.java b/src/com/android/customization/model/grid/GridOptionViewModel.java
new file mode 100644
index 00000000..33fa8e179
--- /dev/null
+++ b/src/com/android/customization/model/grid/GridOptionViewModel.java
@@ -0,0 +1,53 @@
+/*
+ * 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);
+ }
+}
diff --git a/src/com/android/customization/model/grid/GridSectionController.java b/src/com/android/customization/model/grid/GridSectionController.java
index 5470d77d..64a6cce1 100644
--- a/src/com/android/customization/model/grid/GridSectionController.java
+++ b/src/com/android/customization/model/grid/GridSectionController.java
@@ -74,8 +74,8 @@ public class GridSectionController implements CustomizationSectionController<Gri
}
}, /* reload= */ true);
- gridSectionView.setOnClickListener(v -> mSectionNavigationController.navigateTo(
- GridFragment.newInstance(context.getString(R.string.grid_title))));
+ gridSectionView.setOnClickListener(
+ v -> mSectionNavigationController.navigateTo(new GridFragment()));
return gridSectionView;
}
diff --git a/src/com/android/customization/model/mode/DarkModeSectionController.java b/src/com/android/customization/model/mode/DarkModeSectionController.java
index 382162ea..f56b7092 100644
--- a/src/com/android/customization/model/mode/DarkModeSectionController.java
+++ b/src/com/android/customization/model/mode/DarkModeSectionController.java
@@ -128,7 +128,11 @@ public class DarkModeSectionController implements
UiModeManager uiModeManager = context.getSystemService(UiModeManager.class);
int shortDelay = context.getResources().getInteger(android.R.integer.config_shortAnimTime);
new Handler(Looper.getMainLooper()).postDelayed(
- () -> uiModeManager.setNightModeActivated(viewActivated),
+ () -> {
+ mDarkModeSectionView.announceForAccessibility(
+ context.getString(R.string.mode_changed));
+ uiModeManager.setNightModeActivated(viewActivated);
+ },
/* delayMillis= */ shortDelay);
}
diff --git a/src/com/android/customization/module/DefaultCustomizationInjector.java b/src/com/android/customization/module/DefaultCustomizationInjector.java
index db899a3d..c9062812 100644
--- a/src/com/android/customization/module/DefaultCustomizationInjector.java
+++ b/src/com/android/customization/module/DefaultCustomizationInjector.java
@@ -95,8 +95,10 @@ public class DefaultCustomizationInjector extends BaseWallpaperInjector
WallpaperInfo wallpaperInfo,
int mode,
boolean viewAsHome,
+ boolean viewFullScreen,
boolean testingModeEnabled) {
- return PreviewFragment.newInstance(wallpaperInfo, mode, viewAsHome, testingModeEnabled);
+ return PreviewFragment.newInstance(wallpaperInfo, mode, viewAsHome, viewFullScreen,
+ testingModeEnabled);
}
@Override
diff --git a/src/com/android/customization/picker/grid/GridFragment.java b/src/com/android/customization/picker/grid/GridFragment.java
index bb29d55a..cb04fc39 100644
--- a/src/com/android/customization/picker/grid/GridFragment.java
+++ b/src/com/android/customization/picker/grid/GridFragment.java
@@ -17,23 +17,27 @@ package com.android.customization.picker.grid;
import static com.android.wallpaper.widget.BottomActionBar.BottomAction.APPLY_TEXT;
+import android.content.Context;
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.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;
@@ -57,27 +61,18 @@ import java.util.List;
public class GridFragment extends AppbarFragment {
private static final String TAG = "GridFragment";
- private static final String KEY_STATE_SELECTED_OPTION = "GridFragment.selectedOption";
- private static final String KEY_STATE_BOTTOM_ACTION_BAR_VISIBLE =
- "GridFragment.bottomActionBarVisible";
-
- public static GridFragment newInstance(CharSequence title) {
- GridFragment fragment = new GridFragment();
- fragment.setArguments(AppbarFragment.createArguments(title));
- return fragment;
- }
private WallpaperInfo mHomeWallpaper;
private RecyclerView mOptionsContainer;
private OptionSelectorController<GridOption> mOptionsController;
private GridOptionsManager mGridManager;
- private GridOption mSelectedOption;
private ContentLoadingProgressBar mLoading;
private View mContent;
private View mError;
private BottomActionBar mBottomActionBar;
private ThemesUserEventLogger mEventLogger;
private GridOptionPreviewer mGridOptionPreviewer;
+ private GridOptionViewModel mGridOptionViewModel;
private final Callback mApplyGridCallback = new Callback() {
@Override
@@ -95,10 +90,18 @@ public class GridFragment extends AppbarFragment {
// 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,
@@ -108,6 +111,12 @@ public class GridFragment extends AppbarFragment {
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);
+ }
mLoading = view.findViewById(R.id.loading_indicator);
mError = view.findViewById(R.id.error_section);
@@ -127,7 +136,7 @@ public class GridFragment extends AppbarFragment {
mGridManager = GridOptionsManager.getInstance(getContext());
mEventLogger = (ThemesUserEventLogger) InjectorProvider.getInjector()
.getUserEventLogger(getContext());
- setUpOptions(savedInstanceState);
+ setUpOptions();
SurfaceView wallpaperSurface = view.findViewById(R.id.wallpaper_preview_surface);
WallpaperPreviewer wallpaperPreviewer = new WallpaperPreviewer(getLifecycle(),
@@ -147,6 +156,13 @@ public class GridFragment extends AppbarFragment {
}
@Override
+ public boolean onBackPressed() {
+ mGridOptionViewModel.setSelectedOption(null);
+ mGridOptionViewModel.setBottomActionBarVisible(false);
+ return super.onBackPressed();
+ }
+
+ @Override
public void onDestroy() {
super.onDestroy();
if (mGridOptionPreviewer != null) {
@@ -155,14 +171,8 @@ public class GridFragment extends AppbarFragment {
}
@Override
- public void onSaveInstanceState(@NonNull Bundle outState) {
- super.onSaveInstanceState(outState);
- if (mSelectedOption != null) {
- outState.putParcelable(KEY_STATE_SELECTED_OPTION, mSelectedOption);
- }
- if (mBottomActionBar != null) {
- outState.putBoolean(KEY_STATE_BOTTOM_ACTION_BAR_VISIBLE, mBottomActionBar.isVisible());
- }
+ public CharSequence getDefaultTitle() {
+ return getString(R.string.grid_title);
}
@Override
@@ -170,7 +180,8 @@ public class GridFragment extends AppbarFragment {
super.onBottomActionBarReady(bottomActionBar);
mBottomActionBar = bottomActionBar;
mBottomActionBar.showActionsOnly(APPLY_TEXT);
- mBottomActionBar.setActionClickListener(APPLY_TEXT, v -> applyGridOption(mSelectedOption));
+ mBottomActionBar.setActionClickListener(APPLY_TEXT,
+ v -> applyGridOption(mGridOptionViewModel.getSelectedOption()));
}
private void applyGridOption(GridOption gridOption) {
@@ -178,7 +189,7 @@ public class GridFragment extends AppbarFragment {
mGridManager.apply(gridOption, mApplyGridCallback);
}
- private void setUpOptions(@Nullable Bundle savedInstanceState) {
+ private void setUpOptions() {
hideError();
mLoading.show();
mGridManager.fetchOptions(new OptionsFetchedListener<GridOption>() {
@@ -186,26 +197,31 @@ public class GridFragment extends AppbarFragment {
public void onOptionsLoaded(List<GridOption> options) {
mLoading.hide();
mOptionsController = new OptionSelectorController<>(
- mOptionsContainer, options, /* useGrid= */ false, CheckmarkStyle.CENTER);
+ 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));
- // Find the selected Grid option.
- GridOption previouslySelectedOption = null;
- if (savedInstanceState != null) {
- previouslySelectedOption = findEquivalent(
- options, savedInstanceState.getParcelable(KEY_STATE_SELECTED_OPTION));
- }
- mSelectedOption = previouslySelectedOption != null
- ? previouslySelectedOption
- : getActiveOption(options);
-
- mOptionsController.setSelectedOption(mSelectedOption);
- onOptionSelected(mSelectedOption);
- restoreBottomActionBarVisibility(savedInstanceState);
+ 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);
});
}
@@ -247,15 +263,13 @@ public class GridFragment extends AppbarFragment {
}
private void onOptionSelected(CustomizationOption selectedOption) {
- mSelectedOption = (GridOption) selectedOption;
- mEventLogger.logGridSelected(mSelectedOption);
- mGridOptionPreviewer.setGridOption(mSelectedOption);
+ mGridOptionViewModel.setSelectedOption((GridOption) selectedOption);
+ mEventLogger.logGridSelected(mGridOptionViewModel.getSelectedOption());
+ mGridOptionPreviewer.setGridOption(mGridOptionViewModel.getSelectedOption());
}
- private void restoreBottomActionBarVisibility(@Nullable Bundle savedInstanceState) {
- boolean isBottomActionBarVisible = savedInstanceState != null
- && savedInstanceState.getBoolean(KEY_STATE_BOTTOM_ACTION_BAR_VISIBLE);
- if (isBottomActionBarVisible) {
+ private void restoreBottomActionBarVisibility() {
+ if (mGridOptionViewModel.getBottomActionBarVisible()) {
mBottomActionBar.show();
} else {
mBottomActionBar.hide();
diff --git a/src/com/android/customization/widget/OptionSelectorController.java b/src/com/android/customization/widget/OptionSelectorController.java
index 8e85c013..952bc555 100644
--- a/src/com/android/customization/widget/OptionSelectorController.java
+++ b/src/com/android/customization/widget/OptionSelectorController.java
@@ -68,11 +68,13 @@ public class OptionSelectorController<T extends CustomizationOption<T>> {
void onOptionSelected(CustomizationOption selected);
}
- @IntDef({CheckmarkStyle.NONE, CheckmarkStyle.CORNER, CheckmarkStyle.CENTER})
+ @IntDef({CheckmarkStyle.NONE, CheckmarkStyle.CORNER, CheckmarkStyle.CENTER,
+ CheckmarkStyle.CENTER_CHANGE_COLOR_WHEN_NOT_SELECTED})
public @interface CheckmarkStyle {
int NONE = 0;
int CORNER = 1;
int CENTER = 2;
+ int CENTER_CHANGE_COLOR_WHEN_NOT_SELECTED = 3;
}
private static final float LINEAR_LAYOUT_HORIZONTAL_DISPLAY_OPTIONS_MAX = 4.35f;
@@ -114,8 +116,6 @@ public class OptionSelectorController<T extends CustomizationOption<T>> {
if (!mOptions.contains(option)) {
throw new IllegalArgumentException("Invalid option");
}
- updateActivatedStatus(mSelectedOption, false);
- updateActivatedStatus(option, true);
T lastSelectedOption = mSelectedOption;
mSelectedOption = option;
mAdapter.notifyItemChanged(mOptions.indexOf(option));
@@ -149,38 +149,6 @@ public class OptionSelectorController<T extends CustomizationOption<T>> {
}
}
- private void updateActivatedStatus(T option, boolean isActivated) {
- int index = mOptions.indexOf(option);
- if (index < 0) {
- return;
- }
- RecyclerView.ViewHolder holder = mContainer.findViewHolderForAdapterPosition(index);
- if (holder != null && holder.itemView != null) {
- holder.itemView.setActivated(isActivated);
-
- if (holder instanceof TileViewHolder) {
- TileViewHolder tileHolder = (TileViewHolder) holder;
- if (isActivated) {
- if (option == mAppliedOption && mCheckmarkStyle != CheckmarkStyle.NONE) {
- tileHolder.setContentDescription(mContainer.getContext(), option,
- R.string.option_applied_previewed_description);
- } else {
- tileHolder.setContentDescription(mContainer.getContext(), option,
- R.string.option_previewed_description);
- }
- } else if (option == mAppliedOption && mCheckmarkStyle != CheckmarkStyle.NONE) {
- tileHolder.setContentDescription(mContainer.getContext(), option,
- R.string.option_applied_description);
- } else {
- tileHolder.resetContentDescription();
- }
- }
- } else {
- // Item is not visible, make sure the item is re-bound when it becomes visible
- mAdapter.notifyItemChanged(index);
- }
- }
-
/**
* Notify that a given option has changed.
* @param option the option that changed
@@ -235,19 +203,39 @@ public class OptionSelectorController<T extends CustomizationOption<T>> {
mContainer.getContext().getTheme()),
Gravity.BOTTOM | Gravity.RIGHT,
res.getDimensionPixelSize(R.dimen.check_size),
- res.getDimensionPixelOffset(R.dimen.check_offset));
+ res.getDimensionPixelOffset(R.dimen.check_offset), true);
} else if (mCheckmarkStyle == CheckmarkStyle.CENTER
&& option.equals(mAppliedOption)) {
drawCheckmark(option, holder,
res.getDrawable(R.drawable.check_circle_grey_large,
mContainer.getContext().getTheme()),
Gravity.CENTER, res.getDimensionPixelSize(R.dimen.center_check_size),
- 0);
+ 0, true);
+ } else if (mCheckmarkStyle == CheckmarkStyle.CENTER_CHANGE_COLOR_WHEN_NOT_SELECTED
+ && option.equals(mAppliedOption)) {
+ int drawableRes = option.equals(mSelectedOption)
+ ? R.drawable.check_circle_grey_large
+ : R.drawable.check_circle_grey_large_not_select;
+ drawCheckmark(option, holder,
+ res.getDrawable(drawableRes,
+ mContainer.getContext().getTheme()),
+ Gravity.CENTER, res.getDimensionPixelSize(R.dimen.center_check_size),
+ 0, option.equals(mSelectedOption));
} else if (option.equals(mAppliedOption)) {
// Initialize with "previewed" description if we don't show checkmark
holder.setContentDescription(mContainer.getContext(), option,
R.string.option_previewed_description);
} else if (mCheckmarkStyle != CheckmarkStyle.NONE) {
+ if (mCheckmarkStyle == CheckmarkStyle.CENTER_CHANGE_COLOR_WHEN_NOT_SELECTED) {
+ if (option.equals(mSelectedOption)) {
+ holder.setContentDescription(mContainer.getContext(), option,
+ R.string.option_previewed_description);
+ } else {
+ holder.setContentDescription(mContainer.getContext(), option,
+ R.string.option_change_applied_previewed_description);
+ }
+ }
+
holder.tileView.setForeground(null);
}
}
@@ -259,7 +247,7 @@ public class OptionSelectorController<T extends CustomizationOption<T>> {
private void drawCheckmark(CustomizationOption<?> option, TileViewHolder holder,
Drawable checkmark, int gravity, @Dimension int checkSize,
- @Dimension int checkOffset) {
+ @Dimension int checkOffset, boolean currentlyPreviewed) {
Drawable frame = holder.tileView.getForeground();
Drawable[] layers = {frame, checkmark};
if (frame == null) {
@@ -277,8 +265,13 @@ public class OptionSelectorController<T extends CustomizationOption<T>> {
holder.tileView.setForeground(checkedFrame);
// Initialize the currently applied option
- holder.setContentDescription(mContainer.getContext(), option,
- R.string.option_applied_previewed_description);
+ if (currentlyPreviewed) {
+ holder.setContentDescription(mContainer.getContext(), option,
+ R.string.option_applied_previewed_description);
+ } else {
+ holder.setContentDescription(mContainer.getContext(), option,
+ R.string.option_applied_description);
+ }
}
};