1 /* 2 * Copyright (C) 2017 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.wallpaper.picker.individual; 17 18 import android.app.Activity; 19 import android.content.Context; 20 import android.content.Intent; 21 import android.content.res.Resources.NotFoundException; 22 import android.graphics.Insets; 23 import android.os.Bundle; 24 import android.util.Log; 25 import android.view.MenuItem; 26 import android.view.View; 27 import android.view.WindowInsets; 28 import android.widget.Toast; 29 30 import androidx.appcompat.widget.Toolbar; 31 import androidx.fragment.app.Fragment; 32 import androidx.fragment.app.FragmentManager; 33 34 import com.android.wallpaper.R; 35 import com.android.wallpaper.compat.BuildCompat; 36 import com.android.wallpaper.model.Category; 37 import com.android.wallpaper.model.CategoryProvider; 38 import com.android.wallpaper.model.CategoryReceiver; 39 import com.android.wallpaper.model.InlinePreviewIntentFactory; 40 import com.android.wallpaper.model.LiveWallpaperInfo; 41 import com.android.wallpaper.model.PickerIntentFactory; 42 import com.android.wallpaper.model.WallpaperInfo; 43 import com.android.wallpaper.module.Injector; 44 import com.android.wallpaper.module.InjectorProvider; 45 import com.android.wallpaper.module.WallpaperPersister; 46 import com.android.wallpaper.picker.BaseActivity; 47 import com.android.wallpaper.picker.PreviewActivity.PreviewActivityIntentFactory; 48 import com.android.wallpaper.util.DiskBasedLogger; 49 50 /** 51 * Activity that can be launched from the Android wallpaper picker and allows users to pick from 52 * various wallpapers and enter a preview mode for specific ones. 53 */ 54 public class IndividualPickerActivity extends BaseActivity { 55 private static final String TAG = "IndividualPickerAct"; 56 private static final String EXTRA_CATEGORY_COLLECTION_ID = 57 "com.android.wallpaper.category_collection_id"; 58 private static final int PREVIEW_WALLPAPER_REQUEST_CODE = 0; 59 private static final int PREVIEW_LIVEWALLPAPER_REQUEST_CODE = 2; 60 private static final String KEY_CATEGORY_COLLECTION_ID = "key_category_collection_id"; 61 62 private InlinePreviewIntentFactory mPreviewIntentFactory; 63 private WallpaperPersister mWallpaperPersister; 64 private Category mCategory; 65 private String mCategoryCollectionId; 66 67 @Override onCreate(Bundle savedInstanceState)68 protected void onCreate(Bundle savedInstanceState) { 69 super.onCreate(savedInstanceState); 70 setContentView(R.layout.activity_single_fragment_with_toolbar); 71 72 // Set toolbar as the action bar. 73 Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 74 setSupportActionBar(toolbar); 75 76 mPreviewIntentFactory = new PreviewActivityIntentFactory(); 77 Injector injector = InjectorProvider.getInjector(); 78 mWallpaperPersister = injector.getWallpaperPersister(this); 79 80 FragmentManager fm = getSupportFragmentManager(); 81 Fragment fragment = fm.findFragmentById(R.id.fragment_container); 82 83 mCategoryCollectionId = (savedInstanceState == null) 84 ? getIntent().getStringExtra(EXTRA_CATEGORY_COLLECTION_ID) 85 : savedInstanceState.getString(KEY_CATEGORY_COLLECTION_ID); 86 CategoryProvider categoryProvider = injector.getCategoryProvider(this); 87 categoryProvider.fetchCategories(new CategoryReceiver() { 88 @Override 89 public void onCategoryReceived(Category category) { 90 // Do nothing. 91 } 92 93 @Override 94 public void doneFetchingCategories() { 95 mCategory = categoryProvider.getCategory(mCategoryCollectionId); 96 if (mCategory == null) { 97 DiskBasedLogger.e(TAG, "Failed to find the category: " + mCategoryCollectionId, 98 IndividualPickerActivity.this); 99 // We either were called with an invalid collection Id, or we're restarting with 100 // no saved state, or with a collection id that doesn't exist anymore. 101 // In those cases, we cannot continue, so let's just go back. 102 finish(); 103 return; 104 } 105 onCategoryLoaded(); 106 } 107 }, false); 108 109 getSupportActionBar().setDisplayHomeAsUpEnabled(true); 110 111 toolbar.getNavigationIcon().setTint(getColor(R.color.toolbar_icon_color)); 112 toolbar.getNavigationIcon().setAutoMirrored(true); 113 114 getWindow().getDecorView().setSystemUiVisibility( 115 getWindow().getDecorView().getSystemUiVisibility() 116 | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION 117 | View.SYSTEM_UI_FLAG_LAYOUT_STABLE); 118 ((View) findViewById(R.id.fragment_container).getParent()) 119 .setOnApplyWindowInsetsListener((view, windowInsets) -> { 120 view.setPadding(view.getPaddingLeft(), windowInsets.getSystemWindowInsetTop(), 121 view.getPaddingRight(), view.getBottom()); 122 // Consume only the top inset (status bar), to let other content in the Activity consume 123 // the nav bar (ie, by using "fitSystemWindows") 124 if (BuildCompat.isAtLeastQ()) { 125 WindowInsets.Builder builder = new WindowInsets.Builder(windowInsets); 126 builder.setSystemWindowInsets(Insets.of(windowInsets.getSystemWindowInsetLeft(), 127 0, windowInsets.getStableInsetRight(), 128 windowInsets.getSystemWindowInsetBottom())); 129 return builder.build(); 130 } else { 131 return windowInsets.replaceSystemWindowInsets( 132 windowInsets.getSystemWindowInsetLeft(), 133 0, windowInsets.getStableInsetRight(), 134 windowInsets.getSystemWindowInsetBottom()); 135 } 136 }); 137 138 if (fragment == null) { 139 fragment = injector.getIndividualPickerFragment(mCategoryCollectionId); 140 fm.beginTransaction() 141 .add(R.id.fragment_container, fragment) 142 .commit(); 143 } 144 } 145 onCategoryLoaded()146 private void onCategoryLoaded() { 147 setTitle(mCategory.getTitle()); 148 getSupportActionBar().setTitle(mCategory.getTitle()); 149 } 150 151 @Override onOptionsItemSelected(MenuItem item)152 public boolean onOptionsItemSelected(MenuItem item) { 153 int id = item.getItemId(); 154 if (id == android.R.id.home) { 155 // Handle Up as a Global back since the only entry point to IndividualPickerActivity is 156 // from TopLevelPickerActivity. 157 onBackPressed(); 158 return true; 159 } 160 return false; 161 } 162 163 @Override onActivityResult(int requestCode, int resultCode, Intent data)164 public void onActivityResult(int requestCode, int resultCode, Intent data) { 165 super.onActivityResult(requestCode, resultCode, data); 166 167 boolean shouldShowMessage = false; 168 switch (requestCode) { 169 case PREVIEW_LIVEWALLPAPER_REQUEST_CODE: 170 shouldShowMessage = true; 171 case PREVIEW_WALLPAPER_REQUEST_CODE: 172 if (resultCode == Activity.RESULT_OK) { 173 mWallpaperPersister.onLiveWallpaperSet(); 174 175 // The wallpaper was set, so finish this activity with result OK. 176 finishWithResultOk(shouldShowMessage); 177 } 178 break; 179 default: 180 Log.e(TAG, "Invalid request code: " + requestCode); 181 } 182 } 183 184 /** 185 * Shows the preview activity for the given wallpaper. 186 */ showPreview(WallpaperInfo wallpaperInfo)187 public void showPreview(WallpaperInfo wallpaperInfo) { 188 mWallpaperPersister.setWallpaperInfoInPreview(wallpaperInfo); 189 wallpaperInfo.showPreview(this, mPreviewIntentFactory, 190 wallpaperInfo instanceof LiveWallpaperInfo ? PREVIEW_LIVEWALLPAPER_REQUEST_CODE 191 : PREVIEW_WALLPAPER_REQUEST_CODE); 192 } 193 finishWithResultOk(boolean shouldShowMessage)194 private void finishWithResultOk(boolean shouldShowMessage) { 195 if (shouldShowMessage) { 196 try { 197 Toast.makeText(this, R.string.wallpaper_set_successfully_message, 198 Toast.LENGTH_SHORT).show(); 199 } catch (NotFoundException e) { 200 Log.e(TAG, "Could not show toast " + e); 201 } 202 } 203 overridePendingTransition(R.anim.fade_in, R.anim.fade_out); 204 setResult(Activity.RESULT_OK); 205 finish(); 206 } 207 208 @Override onSaveInstanceState(Bundle bundle)209 protected void onSaveInstanceState(Bundle bundle) { 210 super.onSaveInstanceState(bundle); 211 212 bundle.putString(KEY_CATEGORY_COLLECTION_ID, mCategoryCollectionId); 213 } 214 215 /** 216 * Default implementation of intent factory that provides an intent to start an 217 * IndividualPickerActivity. 218 */ 219 public static class IndividualPickerActivityIntentFactory implements PickerIntentFactory { 220 @Override newIntent(Context ctx, String collectionId)221 public Intent newIntent(Context ctx, String collectionId) { 222 return new Intent(ctx, IndividualPickerActivity.class).putExtra( 223 EXTRA_CATEGORY_COLLECTION_ID, collectionId); 224 } 225 } 226 } 227