1/* 2 * Copyright (C) 2016 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 17package com.google.android.leanbackjank.ui; 18 19import android.content.Intent; 20import android.content.res.Resources; 21import android.net.Uri; 22import android.os.Bundle; 23 24import androidx.core.content.res.ResourcesCompat; 25import androidx.leanback.app.BackgroundManager; 26import androidx.leanback.app.BrowseFragment; 27import androidx.leanback.widget.ArrayObjectAdapter; 28import androidx.leanback.widget.HeaderItem; 29import androidx.leanback.widget.ListRow; 30import androidx.leanback.widget.ListRowPresenter; 31import androidx.leanback.widget.Presenter; 32import androidx.leanback.widget.PresenterSelector; 33import androidx.leanback.widget.ShadowOverlayHelper; 34 35import com.google.android.leanbackjank.IntentDefaults; 36import com.google.android.leanbackjank.IntentKeys; 37import com.google.android.leanbackjank.R; 38import com.google.android.leanbackjank.data.VideoProvider; 39import com.google.android.leanbackjank.model.VideoInfo; 40import com.google.android.leanbackjank.presenter.CardPresenter; 41import com.google.android.leanbackjank.presenter.GridItemPresenter; 42import com.google.android.leanbackjank.presenter.HeaderItemPresenter; 43 44import java.util.HashMap; 45import java.util.List; 46import java.util.Map; 47 48/** 49 * Main class to show BrowseFragment with header and rows of videos 50 */ 51public class MainFragment extends BrowseFragment { 52 53 private BackgroundManager mBackgroundManager; 54 private ArrayObjectAdapter mRowsAdapter; 55 56 @Override 57 public void onActivityCreated(Bundle savedInstanceState) { 58 super.onActivityCreated(savedInstanceState); 59 60 // Define defaults. 61 int categoryCount = IntentDefaults.CATEGORY_COUNT; 62 int entriesPerCat = IntentDefaults.ENTRIES_PER_CATEGORY; 63 boolean disableShadows = IntentDefaults.DISABLE_SHADOWS; 64 int cardWidth = IntentDefaults.CARD_WIDTH; 65 int cardHeight = IntentDefaults.CARD_HEIGHT; 66 int whichVideo = IntentDefaults.WHICH_VIDEO; 67 boolean useSingleBitmap = IntentDefaults.USE_SINGLE_BITMAP; 68 69 Intent intent = getActivity().getIntent(); 70 if (intent.getExtras() != null) { 71 categoryCount = intent.getIntExtra(IntentKeys.CATEGORY_COUNT, categoryCount); 72 entriesPerCat = intent.getIntExtra(IntentKeys.ENTRIES_PER_CATEGORY, entriesPerCat); 73 disableShadows = intent.getBooleanExtra(IntentKeys.DISABLE_SHADOWS, disableShadows); 74 cardWidth = intent.getIntExtra(IntentKeys.CARD_WIDTH, cardWidth); 75 cardHeight = intent.getIntExtra(IntentKeys.CARD_HEIGHT, cardHeight); 76 whichVideo = intent.getIntExtra(IntentKeys.WHICH_VIDEO, whichVideo); 77 useSingleBitmap = intent.getBooleanExtra(IntentKeys.USE_SINGLE_BITMAP, useSingleBitmap); 78 } 79 80 loadVideoData(categoryCount, entriesPerCat, disableShadows, useSingleBitmap, cardWidth, 81 cardHeight); 82 setBackground(); 83 setupUIElements(); 84 85 if (whichVideo != IntentKeys.NO_VIDEO) { 86 int resource = 0; 87 /* For info on how to generate videos see: 88 * https://docs.google.com/document/d/1HV8O-Nm4rc2DwVwiZmT4Wa9pf8XttWndg9saGncTRGw 89 */ 90 if (whichVideo == IntentKeys.VIDEO_2160P_60FPS) { 91 resource = R.raw.bbb_sunflower_2160p_60fps; 92 } else if (whichVideo == IntentKeys.VIDEO_1080P_60FPS) { 93 resource = R.raw.testvideo_1080p_60fps; 94 } else if (whichVideo == IntentKeys.VIDEO_480P_60FPS) { 95 resource = R.raw.bbb_480p; 96 } else if (whichVideo == IntentKeys.VIDEO_360P_60FPS) { 97 resource = R.raw.bbb_360p; 98 } 99 Uri uri = Uri.parse("android.resource://" + getActivity().getPackageName() + "/" 100 + resource); 101 Intent videoIntent = new Intent(Intent.ACTION_VIEW, uri, getActivity(), 102 VideoActivity.class); 103 startActivity(videoIntent); 104 } 105 } 106 107 private void setBackground() { 108 mBackgroundManager = BackgroundManager.getInstance(getActivity()); 109 mBackgroundManager.attach(getActivity().getWindow()); 110 mBackgroundManager.setDrawable( 111 ResourcesCompat.getDrawable(getResources(), R.drawable.default_background, null)); 112 } 113 114 private void setupUIElements() { 115 setBadgeDrawable(ResourcesCompat.getDrawable( 116 getActivity().getResources(), R.drawable.app_banner, null)); 117 // Badge, when set, takes precedent over title 118 setTitle(getString(R.string.browse_title)); 119 setHeadersState(HEADERS_ENABLED); 120 setHeadersTransitionOnBackEnabled(true); 121 // set headers background color 122 setBrandColor(ResourcesCompat.getColor(getResources(), R.color.jank_yellow, null)); 123 // set search icon color 124 setSearchAffordanceColor( 125 ResourcesCompat.getColor(getResources(), R.color.search_opaque, null)); 126 127 setHeaderPresenterSelector(new PresenterSelector() { 128 @Override 129 public Presenter getPresenter(Object o) { 130 return new HeaderItemPresenter(); 131 } 132 }); 133 } 134 135 private void loadVideoData(int categoryCount, int entriesPerCat, boolean disableShadows, 136 boolean useSingleBitmap, int cardWidth, int cardHeight) { 137 ListRowPresenter listRowPresenter = new ListRowPresenter() { 138 @Override 139 protected ShadowOverlayHelper.Options createShadowOverlayOptions() { 140 Resources res = getResources(); 141 ShadowOverlayHelper.Options options = new ShadowOverlayHelper.Options(); 142 options.dynamicShadowZ(res.getDimension(R.dimen.shadow_unfocused_z), 143 res.getDimension(R.dimen.shadow_focused_z)); 144 return options; 145 } 146 }; 147 listRowPresenter.setShadowEnabled(!disableShadows); 148 // see b/64451726, leanback bug causes child rounded corner is incorrectly disabled when 149 // shadow is disabled. To make the test data consistent and comparable, by default treat 150 // the rounded corner option same as shadow option. 151 boolean disableRoundedCorner = disableShadows; 152 listRowPresenter.enableChildRoundedCorners(!disableRoundedCorner); 153 mRowsAdapter = new ArrayObjectAdapter(listRowPresenter); 154 HashMap<String, List<VideoInfo>> data = VideoProvider.buildMedia(categoryCount, 155 entriesPerCat, cardWidth, cardHeight, getActivity(), useSingleBitmap); 156 CardPresenter cardPresenter = new CardPresenter(cardWidth, cardHeight); 157 158 int i = 0; 159 for (Map.Entry<String, List<VideoInfo>> entry : data.entrySet()) { 160 ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(cardPresenter); 161 for (VideoInfo videoInfo : entry.getValue()) { 162 listRowAdapter.add(videoInfo); 163 } 164 HeaderItem header = new HeaderItem(i++, entry.getKey()); 165 mRowsAdapter.add(new ListRow(header, listRowAdapter)); 166 } 167 168 ArrayObjectAdapter settingsListAdapter = new ArrayObjectAdapter(new GridItemPresenter()); 169 for (int j = 0; j < entriesPerCat; j++) { 170 settingsListAdapter.add("Settings " + j); 171 } 172 HeaderItem settingsHeader = new HeaderItem(i++, "Settings"); 173 mRowsAdapter.add(new ListRow(settingsHeader, settingsListAdapter)); 174 175 setAdapter(mRowsAdapter); 176 } 177} 178