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.test.uibench.leanback; 17 18 import android.app.Activity; 19 import android.content.Context; 20 import android.graphics.Bitmap; 21 import android.graphics.Canvas; 22 import androidx.leanback.app.BackgroundManager; 23 import androidx.leanback.widget.ArrayObjectAdapter; 24 import androidx.leanback.widget.HeaderItem; 25 import androidx.leanback.widget.ListRow; 26 import androidx.leanback.widget.ListRowPresenter; 27 import androidx.leanback.widget.ObjectAdapter; 28 import androidx.leanback.widget.Presenter; 29 import android.util.DisplayMetrics; 30 import android.util.TypedValue; 31 32 public class TestHelper { 33 34 public static final String EXTRA_BACKGROUND = "extra_bg"; 35 public static final String EXTRA_ROWS = "extra_rows"; 36 public static final String EXTRA_CARDS_PER_ROW = "extra_cards_per_row"; 37 public static final String EXTRA_CARD_HEIGHT_DP = "extra_card_height"; 38 public static final String EXTRA_CARD_WIDTH_DP = "extra_card_width"; 39 public static final String EXTRA_CARD_SHADOW = "extra_card_shadow"; 40 public static final String EXTRA_CARD_ROUND_RECT = "extra_card_round_rect"; 41 public static final String EXTRA_ENTRANCE_TRANSITION = "extra_entrance_transition"; 42 public static final String EXTRA_BITMAP_UPLOAD = "extra_bitmap_upload"; 43 public static final String EXTRA_SHOW_FAST_LANE = "extra_show_fast_lane"; 44 45 /** 46 * Dont change the default values, they gave baseline for measuring the performance 47 */ 48 static final int DEFAULT_CARD_HEIGHT_DP = 180; 49 static final int DEFAULT_CARD_WIDTH_DP = 125; 50 static final int DEFAULT_CARDS_PER_ROW = 20; 51 static final int DEFAULT_ROWS = 10; 52 static final boolean DEFAULT_ENTRANCE_TRANSITION = false; 53 static final boolean DEFAULT_BACKGROUND = true; 54 static final boolean DEFAULT_CARD_SHADOW = true; 55 static final boolean DEFAULT_CARD_ROUND_RECT = true; 56 static final boolean DEFAULT_BITMAP_UPLOAD = true; 57 static final boolean DEFAULT_SHOW_FAST_LANE = true; 58 59 static long sCardIdSeed = 0; 60 static long sRowIdSeed = 0; 61 62 public static class ListRowPresenterBuilder { 63 64 boolean mShadow = DEFAULT_CARD_SHADOW; 65 boolean mRoundedCorner = DEFAULT_CARD_ROUND_RECT; 66 ListRowPresenterBuilder(Context context)67 ListRowPresenterBuilder(Context context) { 68 } 69 configShadow(boolean shadow)70 public ListRowPresenterBuilder configShadow(boolean shadow) { 71 mShadow = shadow; 72 return this; 73 } 74 configRoundedCorner(boolean roundedCorner)75 public ListRowPresenterBuilder configRoundedCorner(boolean roundedCorner) { 76 mRoundedCorner = roundedCorner; 77 return this; 78 } 79 build()80 public ListRowPresenter build() { 81 ListRowPresenter listRowPresenter = new ListRowPresenter(); 82 listRowPresenter.setShadowEnabled(mShadow); 83 listRowPresenter.enableChildRoundedCorners(mRoundedCorner); 84 return listRowPresenter; 85 } 86 } 87 88 public static class CardPresenterBuilder { 89 Context mContext; 90 int mWidthDP = DEFAULT_CARD_WIDTH_DP; 91 int mHeightDP = DEFAULT_CARD_HEIGHT_DP; 92 CardPresenterBuilder(Context context)93 CardPresenterBuilder(Context context) { 94 mContext = context; 95 } 96 configWidthDP(int widthDP)97 public CardPresenterBuilder configWidthDP(int widthDP) { 98 mWidthDP = widthDP; 99 return this; 100 } 101 configHeightDP(int hightDP)102 public CardPresenterBuilder configHeightDP(int hightDP) { 103 mHeightDP = hightDP; 104 return this; 105 } 106 build()107 public Presenter build() { 108 DisplayMetrics dm = mContext.getResources().getDisplayMetrics(); 109 return new CardPresenter( 110 (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mWidthDP, dm), 111 (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mHeightDP, dm)); 112 } 113 } 114 115 public static class RowsAdapterBuilder { 116 117 Context mContext; 118 int mCardsPerRow = DEFAULT_CARDS_PER_ROW; 119 int mRows = DEFAULT_ROWS; 120 CardPresenterBuilder mCardPresenterBuilder; 121 ListRowPresenterBuilder mListRowPresenterBuilder; 122 Presenter mCardPresenter; 123 boolean mBitmapUpload = DEFAULT_BITMAP_UPLOAD; 124 125 static final String[] sSampleStrings = new String[] { 126 "Hello world", "This is a test", "Android TV", "UI Jank Test", 127 "Scroll Up", "Scroll Down", "Load Bitmaps" 128 }; 129 130 /** 131 * Create a RowsAdapterBuilder with default settings 132 */ RowsAdapterBuilder(Context context)133 public RowsAdapterBuilder(Context context) { 134 mContext = context; 135 mCardPresenterBuilder = new CardPresenterBuilder(context); 136 mListRowPresenterBuilder = new ListRowPresenterBuilder(context); 137 } 138 getListRowPresenterBuilder()139 public ListRowPresenterBuilder getListRowPresenterBuilder() { 140 return mListRowPresenterBuilder; 141 } 142 getCardPresenterBuilder()143 public CardPresenterBuilder getCardPresenterBuilder() { 144 return mCardPresenterBuilder; 145 } 146 configRows(int rows)147 public RowsAdapterBuilder configRows(int rows) { 148 mRows = rows; 149 return this; 150 } 151 configCardsPerRow(int cardsPerRow)152 public RowsAdapterBuilder configCardsPerRow(int cardsPerRow) { 153 mCardsPerRow = cardsPerRow; 154 return this; 155 } 156 configBitmapUpLoad(boolean bitmapUpload)157 public RowsAdapterBuilder configBitmapUpLoad(boolean bitmapUpload) { 158 mBitmapUpload = bitmapUpload; 159 return this; 160 } 161 buildListRow()162 public ListRow buildListRow() { 163 ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(mCardPresenter); 164 ListRow listRow = new ListRow(new HeaderItem(sRowIdSeed++, "Row"), listRowAdapter); 165 int indexSample = 0; 166 for (int i = 0; i < mCardsPerRow; i++) { 167 // when doing bitmap upload, use different id so each card has different bitmap 168 // otherwise all cards share the same bitmap 169 listRowAdapter.add(new PhotoItem(sSampleStrings[indexSample], 170 (mBitmapUpload ? sCardIdSeed++ : 0))); 171 indexSample++; 172 if (indexSample >= sSampleStrings.length) { 173 indexSample = 0; 174 } 175 } 176 return listRow; 177 } 178 build()179 public ObjectAdapter build() { 180 try { 181 mCardPresenter = mCardPresenterBuilder.build(); 182 ArrayObjectAdapter adapter = new ArrayObjectAdapter( 183 mListRowPresenterBuilder.build()); 184 for (int i = 0; i < mRows; i++) { 185 adapter.add(buildListRow()); 186 } 187 return adapter; 188 } finally { 189 mCardPresenter = null; 190 } 191 } 192 } 193 runEntranceTransition(Activity activity)194 public static boolean runEntranceTransition(Activity activity) { 195 return activity.getIntent().getBooleanExtra(EXTRA_ENTRANCE_TRANSITION, 196 DEFAULT_ENTRANCE_TRANSITION); 197 } 198 initRowsAdapterBuilder(Activity activity)199 public static RowsAdapterBuilder initRowsAdapterBuilder(Activity activity) { 200 RowsAdapterBuilder builder = new RowsAdapterBuilder(activity); 201 boolean shadow = activity.getIntent().getBooleanExtra(EXTRA_CARD_SHADOW, 202 DEFAULT_CARD_SHADOW); 203 boolean roundRect = activity.getIntent().getBooleanExtra(EXTRA_CARD_ROUND_RECT, 204 DEFAULT_CARD_ROUND_RECT); 205 int widthDp = activity.getIntent().getIntExtra(EXTRA_CARD_WIDTH_DP, 206 DEFAULT_CARD_WIDTH_DP); 207 int heightDp = activity.getIntent().getIntExtra(EXTRA_CARD_HEIGHT_DP, 208 DEFAULT_CARD_HEIGHT_DP); 209 int rows = activity.getIntent().getIntExtra(EXTRA_ROWS, DEFAULT_ROWS); 210 int cardsPerRow = activity.getIntent().getIntExtra(EXTRA_CARDS_PER_ROW, 211 DEFAULT_CARDS_PER_ROW); 212 boolean bitmapUpload = activity.getIntent().getBooleanExtra(EXTRA_BITMAP_UPLOAD, 213 DEFAULT_BITMAP_UPLOAD); 214 builder.configRows(rows) 215 .configCardsPerRow(cardsPerRow) 216 .configBitmapUpLoad(bitmapUpload); 217 builder.getListRowPresenterBuilder() 218 .configRoundedCorner(roundRect) 219 .configShadow(shadow); 220 builder.getCardPresenterBuilder() 221 .configWidthDP(widthDp) 222 .configHeightDP(heightDp); 223 return builder; 224 } 225 initBackground(Activity activity)226 public static void initBackground(Activity activity) { 227 if (activity.getIntent().getBooleanExtra(EXTRA_BACKGROUND, DEFAULT_BACKGROUND)) { 228 BackgroundManager manager = BackgroundManager.getInstance(activity); 229 manager.attach(activity.getWindow()); 230 DisplayMetrics metrics = activity.getResources().getDisplayMetrics(); 231 int width = metrics.widthPixels; 232 int height = metrics.heightPixels; 233 Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 234 Canvas canvas = new Canvas(bitmap); 235 canvas.drawARGB(255, 128, 128, 128); 236 canvas.setBitmap(null); 237 manager.setBitmap(bitmap); 238 } 239 } 240 initHeaderState(BrowseFragment fragment)241 public static void initHeaderState(BrowseFragment fragment) { 242 if (!fragment.getActivity().getIntent() 243 .getBooleanExtra(EXTRA_SHOW_FAST_LANE, DEFAULT_SHOW_FAST_LANE)) { 244 fragment.setHeadersState(BrowseFragment.HEADERS_HIDDEN); 245 } 246 } 247 } 248