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