1 /* 2 * Copyright (C) 2020 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.picker.theme; 17 18 import static android.app.Activity.RESULT_OK; 19 20 import static com.android.wallpaper.widget.BottomActionBar.BottomAction.APPLY; 21 import static com.android.wallpaper.widget.BottomActionBar.BottomAction.INFORMATION; 22 23 import android.app.Activity; 24 import android.content.Context; 25 import android.content.Intent; 26 import android.os.Bundle; 27 import android.util.Log; 28 import android.view.LayoutInflater; 29 import android.view.View; 30 import android.view.ViewGroup; 31 import android.widget.ImageView; 32 33 import androidx.annotation.NonNull; 34 import androidx.annotation.Nullable; 35 36 import com.android.customization.model.theme.DefaultThemeProvider; 37 import com.android.customization.model.theme.ThemeBundle; 38 import com.android.customization.model.theme.ThemeBundleProvider; 39 import com.android.customization.module.CustomizationInjector; 40 import com.android.customization.picker.WallpaperPreviewer; 41 import com.android.wallpaper.R; 42 import com.android.wallpaper.model.WallpaperInfo; 43 import com.android.wallpaper.module.InjectorProvider; 44 import com.android.wallpaper.picker.AppbarFragment; 45 import com.android.wallpaper.widget.BottomActionBar; 46 import com.android.wallpaper.widget.BottomActionBar.BottomSheetContent; 47 48 import com.bumptech.glide.Glide; 49 50 import org.json.JSONException; 51 52 /** A Fragment for theme full preview page. */ 53 public class ThemeFullPreviewFragment extends AppbarFragment { 54 private static final String TAG = "ThemeFullPreviewFragment"; 55 56 public static final String EXTRA_THEME_OPTION_TITLE = "theme_option_title"; 57 protected static final String EXTRA_THEME_OPTION = "theme_option"; 58 protected static final String EXTRA_WALLPAPER_INFO = "wallpaper_info"; 59 protected static final String EXTRA_CAN_APPLY_FROM_FULL_PREVIEW = "can_apply"; 60 61 private WallpaperInfo mWallpaper; 62 private ThemeBundle mThemeBundle; 63 private boolean mCanApplyFromFullPreview; 64 65 /** 66 * Returns a new {@link ThemeFullPreviewFragment} with the provided title and bundle arguments 67 * set. 68 */ newInstance(CharSequence title, Bundle intentBundle)69 public static ThemeFullPreviewFragment newInstance(CharSequence title, Bundle intentBundle) { 70 ThemeFullPreviewFragment fragment = new ThemeFullPreviewFragment(); 71 Bundle bundle = new Bundle(); 72 bundle.putAll(AppbarFragment.createArguments(title)); 73 bundle.putAll(intentBundle); 74 fragment.setArguments(bundle); 75 return fragment; 76 } 77 78 @Override onCreate(@ullable Bundle savedInstanceState)79 public void onCreate(@Nullable Bundle savedInstanceState) { 80 super.onCreate(savedInstanceState); 81 mWallpaper = getArguments().getParcelable(EXTRA_WALLPAPER_INFO); 82 mCanApplyFromFullPreview = getArguments().getBoolean(EXTRA_CAN_APPLY_FROM_FULL_PREVIEW); 83 CustomizationInjector injector = (CustomizationInjector) InjectorProvider.getInjector(); 84 ThemeBundleProvider themeProvider = new DefaultThemeProvider( 85 getContext(), injector.getCustomizationPreferences(getContext())); 86 try { 87 ThemeBundle.Builder builder = themeProvider.parseThemeBundle( 88 getArguments().getString(EXTRA_THEME_OPTION)); 89 if (builder != null) { 90 builder.setTitle(getArguments().getString(EXTRA_THEME_OPTION_TITLE)); 91 mThemeBundle = builder.build(getContext()); 92 } 93 } catch (JSONException e) { 94 Log.w(TAG, "Couldn't parse provided custom theme, will override it"); 95 // TODO(chihhangchuang): Handle the error case. 96 } 97 } 98 99 @Nullable 100 @Override onCreateView(@onNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)101 public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, 102 @Nullable Bundle savedInstanceState) { 103 View view = inflater.inflate( 104 R.layout.fragment_theme_full_preview, container, /* attachToRoot */ false); 105 setUpToolbar(view); 106 Glide.get(getContext()).clearMemory(); 107 108 // Set theme option. 109 final ThemeOptionPreviewer themeOptionPreviewer = new ThemeOptionPreviewer( 110 getLifecycle(), 111 getContext(), 112 view.findViewById(R.id.theme_preview_container)); 113 themeOptionPreviewer.setPreviewInfo(mThemeBundle.getPreviewInfo()); 114 115 // Set wallpaper background. 116 ImageView wallpaperImageView = view.findViewById(R.id.wallpaper_preview_image); 117 final WallpaperPreviewer wallpaperPreviewer = new WallpaperPreviewer( 118 getLifecycle(), 119 getActivity(), 120 wallpaperImageView, 121 view.findViewById(R.id.wallpaper_preview_surface)); 122 wallpaperPreviewer.setWallpaper(mWallpaper, 123 themeOptionPreviewer::updateColorForLauncherWidgets); 124 return view; 125 } 126 127 @Override onBottomActionBarReady(BottomActionBar bottomActionBar)128 protected void onBottomActionBarReady(BottomActionBar bottomActionBar) { 129 super.onBottomActionBarReady(bottomActionBar); 130 if (mCanApplyFromFullPreview) { 131 bottomActionBar.showActionsOnly(INFORMATION, APPLY); 132 bottomActionBar.setActionClickListener(APPLY, v -> finishActivityWithResultOk()); 133 } else { 134 bottomActionBar.showActionsOnly(INFORMATION); 135 } 136 bottomActionBar.bindBottomSheetContentWithAction( 137 new ThemeInfoContent(getContext()), INFORMATION); 138 bottomActionBar.show(); 139 } 140 finishActivityWithResultOk()141 private void finishActivityWithResultOk() { 142 Activity activity = requireActivity(); 143 activity.overridePendingTransition(R.anim.fade_in, R.anim.fade_out); 144 Intent intent = new Intent(); 145 activity.setResult(RESULT_OK, intent); 146 activity.finish(); 147 } 148 149 private final class ThemeInfoContent extends BottomSheetContent<ThemeInfoView> { 150 ThemeInfoContent(Context context)151 private ThemeInfoContent(Context context) { 152 super(context); 153 } 154 155 @Override getViewId()156 public int getViewId() { 157 return R.layout.theme_info_view; 158 } 159 160 @Override onViewCreated(ThemeInfoView view)161 public void onViewCreated(ThemeInfoView view) { 162 view.populateThemeInfo(mThemeBundle); 163 } 164 } 165 } 166