1 // CHECKSTYLE:OFF Generated code
2 /* This file is auto-generated from NewDetailsFragment.java.  DO NOT MODIFY. */
3 
4 /*
5  * Copyright (C) 2014 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
8  * in compliance with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software distributed under the License
13  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
14  * or implied. See the License for the specific language governing permissions and limitations under
15  * the License.
16  */
17 package com.example.android.leanback;
18 
19 import android.content.Context;
20 import android.content.Intent;
21 import android.graphics.Bitmap;
22 import android.graphics.drawable.Drawable;
23 import android.net.Uri;
24 import android.os.Bundle;
25 import android.os.Handler;
26 import android.util.Log;
27 import android.view.LayoutInflater;
28 import android.view.View;
29 import android.view.ViewGroup;
30 
31 import androidx.core.app.ActivityOptionsCompat;
32 import androidx.core.content.res.ResourcesCompat;
33 import androidx.leanback.app.DetailsSupportFragmentBackgroundController;
34 import androidx.leanback.media.MediaPlayerAdapter;
35 import androidx.leanback.media.MediaPlayerGlue;
36 import androidx.leanback.media.PlaybackGlue;
37 import androidx.leanback.media.PlaybackTransportControlGlue;
38 import androidx.leanback.widget.Action;
39 import androidx.leanback.widget.ArrayObjectAdapter;
40 import androidx.leanback.widget.ClassPresenterSelector;
41 import androidx.leanback.widget.DetailsOverviewRow;
42 import androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter;
43 import androidx.leanback.widget.FullWidthDetailsOverviewSharedElementHelper;
44 import androidx.leanback.widget.HeaderItem;
45 import androidx.leanback.widget.ImageCardView;
46 import androidx.leanback.widget.ListRow;
47 import androidx.leanback.widget.ListRowPresenter;
48 import androidx.leanback.widget.OnActionClickedListener;
49 import androidx.leanback.widget.OnItemViewClickedListener;
50 import androidx.leanback.widget.OnItemViewSelectedListener;
51 import androidx.leanback.widget.Presenter;
52 import androidx.leanback.widget.Row;
53 import androidx.leanback.widget.RowPresenter;
54 import androidx.leanback.widget.SparseArrayObjectAdapter;
55 
56 import org.jspecify.annotations.NonNull;
57 
58 public class NewDetailsSupportFragment extends androidx.leanback.app.DetailsSupportFragment {
59 
60     private static final String TAG = "leanback.DetailsSupportFragment";
61 
62     private static final int NUM_ROWS = 3;
63     private ArrayObjectAdapter mRowsAdapter;
64     private PhotoItem mPhotoItem;
65     final CardPresenter cardPresenter = new CardPresenter();
66 
67     private static final int ACTION_PLAY = 1;
68     private static final int ACTION_RENT = 2;
69     private static final int ACTION_BUY = 3;
70 
71     private boolean TEST_SHARED_ELEMENT_TRANSITION = true;
72     private boolean TEST_BACKGROUND_PLAYER;
73 
74     private static final long TIME_TO_LOAD_OVERVIEW_ROW_MS = 1000;
75     private static final long TIME_TO_LOAD_RELATED_ROWS_MS = 2000;
76 
77     private Action mActionPlay;
78     private Action mActionRent;
79     private Action mActionBuy;
80 
81     private FullWidthDetailsOverviewSharedElementHelper mHelper;
82     private BackgroundHelper mBackgroundHelper; // used to download bitmap async.
83     private final DetailsSupportFragmentBackgroundController mDetailsBackground =
84             new DetailsSupportFragmentBackgroundController(this);
85 
setupTrailerVideo()86     void setupTrailerVideo() {
87         MediaPlayerGlue mediaPlayerGlue = new MediaPlayerGlue(getActivity());
88         mDetailsBackground.setupVideoPlayback(mediaPlayerGlue);
89         mediaPlayerGlue.setMode(MediaPlayerGlue.REPEAT_ONE);
90         mediaPlayerGlue.setArtist("A Googler");
91         mediaPlayerGlue.setTitle("Diving with Sharks Trailer");
92         mediaPlayerGlue.setMediaSource(Uri.parse("android.resource://com.example.android.leanback/"
93                 + "raw/browse"));
94     }
95 
setupMainVideo()96     void setupMainVideo() {
97         Context context = getActivity();
98         MediaPlayerAdapter adapter = new MediaPlayerAdapter(context);
99         PlaybackTransportControlGlue<MediaPlayerAdapter> mediaPlayerGlue =
100                 new PlaybackTransportControlGlue(context, adapter);
101         mDetailsBackground.setupVideoPlayback(mediaPlayerGlue);
102         mediaPlayerGlue.setSubtitle("A Googler");
103         mediaPlayerGlue.setTitle("Diving with Sharks");
104         mediaPlayerGlue.getPlayerAdapter().setDataSource(Uri.parse(
105                 "https://storage.googleapis.com/android-tv/Sample videos/April Fool's "
106                         + "2013/Explore Treasure Mode with Google Maps.mp4"));
107         mediaPlayerGlue.addPlayerCallback(new PlaybackGlue.PlayerCallback() {
108             @Override
109             public void onPreparedStateChanged(@NonNull PlaybackGlue glue) {
110                 super.onPreparedStateChanged(glue);
111                 PlaybackTransportControlGlue controlGlue = (PlaybackTransportControlGlue) glue;
112                 controlGlue.setSeekProvider(new PlaybackSeekDiskDataProvider(
113                         controlGlue.getDuration(), 1000,
114                         "/sdcard/seek/frame_%04d.jpg"));
115             }
116         });
117     }
118 
119     @Override
onCreate(Bundle savedInstanceState)120     public void onCreate(Bundle savedInstanceState) {
121         Log.i(TAG, "onCreate");
122         super.onCreate(savedInstanceState);
123 
124         mBackgroundHelper = new BackgroundHelper(getActivity());
125         mDetailsBackground.enableParallax();
126         if (TEST_BACKGROUND_PLAYER) {
127             if (MovieData.sStatus == MovieData.STATUS_INIT) {
128                 // not own/rented, play trailer
129                 setupTrailerVideo();
130             } else {
131                 // bought or rented, play the main content
132                 setupMainVideo();
133                 // hide details main ui
134                 mDetailsBackground.switchToVideo();
135             }
136         }
137 
138         final Context context = getActivity();
139         setBadgeDrawable(ResourcesCompat.getDrawable(context.getResources(), R.drawable.ic_title,
140                 context.getTheme()));
141         setTitle("Leanback Sample App");
142         if (!TEST_BACKGROUND_PLAYER) {
143             setOnSearchClickedListener(new View.OnClickListener() {
144                 @Override
145                 public void onClick(View view) {
146                     Intent intent = new Intent(getActivity(), SearchSupportActivity.class);
147                     startActivity(intent);
148                 }
149             });
150         }
151 
152         mActionPlay = new Action(ACTION_PLAY, "Play");
153         mActionRent = new Action(ACTION_RENT, "Rent", "$3.99", ResourcesCompat.getDrawable(
154                 context.getResources(), R.drawable.ic_action_a, context.getTheme()));
155         mActionBuy = new Action(ACTION_BUY, "Buy $9.99");
156 
157         ClassPresenterSelector ps = new ClassPresenterSelector();
158         FullWidthDetailsOverviewRowPresenter dorPresenter =
159                 new FullWidthDetailsOverviewRowPresenter(new DetailsDescriptionPresenter());
160         dorPresenter.setOnActionClickedListener(new OnActionClickedListener() {
161             @Override
162             public void onActionClicked(Action action) {
163                 final Context context = getActivity();
164                 DetailsOverviewRow dor = (DetailsOverviewRow) mRowsAdapter.get(0);
165                 if (action.getId() == ACTION_BUY) {
166                     // on the UI thread, we can modify actions adapter directly
167                     SparseArrayObjectAdapter actions = (SparseArrayObjectAdapter)
168                             dor.getActionsAdapter();
169                     actions.set(ACTION_PLAY, mActionPlay);
170                     actions.clear(ACTION_RENT);
171                     actions.clear(ACTION_BUY);
172                     boolean previousRented = MovieData.sStatus == MovieData.STATUS_RENTED;
173                     MovieData.sStatus = MovieData.STATUS_OWN;
174                     dor.setItem(getDisplayTitle(mPhotoItem.getTitle()));
175                     dor.setImageDrawable(ResourcesCompat.getDrawable(context.getResources(),
176                             R.drawable.details_img_16x9, context.getTheme()));
177                     if (TEST_BACKGROUND_PLAYER) {
178                         if (!previousRented) {
179                             setupMainVideo();
180                             mDetailsBackground.switchToVideo();
181                         }
182                     } else {
183                         Intent intent = new Intent(context, PlaybackActivity.class);
184                         getActivity().startActivity(intent);
185                     }
186                 } else if (action.getId() == ACTION_RENT) {
187                     // on the UI thread, we can modify actions adapter directly
188                     SparseArrayObjectAdapter actions = (SparseArrayObjectAdapter)
189                             dor.getActionsAdapter();
190                     actions.set(ACTION_PLAY, mActionPlay);
191                     actions.clear(ACTION_RENT);
192                     MovieData.sStatus = MovieData.STATUS_RENTED;
193                     dor.setItem(getDisplayTitle(mPhotoItem.getTitle()));
194                     if (TEST_BACKGROUND_PLAYER) {
195                         setupMainVideo();
196                         mDetailsBackground.switchToVideo();
197                     } else {
198                         Intent intent = new Intent(context, PlaybackActivity.class);
199                         getActivity().startActivity(intent);
200                     }
201                 } else if (action.getId() == ACTION_PLAY) {
202                     if (TEST_BACKGROUND_PLAYER) {
203                         mDetailsBackground.switchToVideo();
204                     } else {
205                         Intent intent = new Intent(context, PlaybackActivity.class);
206                         getActivity().startActivity(intent);
207                     }
208                 }
209             }
210         });
211 
212         ps.addClassPresenter(DetailsOverviewRow.class, dorPresenter);
213         ps.addClassPresenter(ListRow.class, new ListRowPresenter());
214 
215         mRowsAdapter = new ArrayObjectAdapter(ps);
216         updateAdapter();
217 
218         setOnItemViewClickedListener(new OnItemViewClickedListener() {
219             @Override
220             public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item,
221                     RowPresenter.ViewHolder rowViewHolder, Row row) {
222                 Log.i(TAG, "onItemClicked: " + item + " row " + row);
223                 if (item instanceof PhotoItem) {
224                     Intent intent = new Intent(getActivity(), DetailsSupportActivity.class);
225                     intent.putExtra(DetailsSupportActivity.EXTRA_ITEM, (PhotoItem) item);
226 
227                     Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(
228                             getActivity(),
229                             ((ImageCardView) itemViewHolder.view).getMainImageView(),
230                             DetailsSupportActivity.SHARED_ELEMENT_NAME).toBundle();
231                     getActivity().startActivity(intent, bundle);
232                 }
233             }
234         });
235         setOnItemViewSelectedListener(new OnItemViewSelectedListener() {
236             @Override
237             public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item,
238                     RowPresenter.ViewHolder rowViewHolder, Row row) {
239                 Log.i(TAG, "onItemSelected: " + item + " row " + row);
240             }
241         });
242 
243         if (TEST_SHARED_ELEMENT_TRANSITION) {
244             mHelper = new FullWidthDetailsOverviewSharedElementHelper();
245             mHelper.setSharedElementEnterTransition(getActivity(),
246                     DetailsSupportActivity.SHARED_ELEMENT_NAME);
247             dorPresenter.setListener(mHelper);
248             dorPresenter.setParticipatingEntranceTransition(false);
249         } else {
250             dorPresenter.setParticipatingEntranceTransition(true);
251         }
252     }
253 
254     @Override
onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)255     public View onCreateView(LayoutInflater inflater, ViewGroup container,
256             Bundle savedInstanceState) {
257         View view = super.onCreateView(inflater, container, savedInstanceState);
258         return view;
259     }
260 
setBackgroundVideo(boolean backgroundVideo)261     public void setBackgroundVideo(boolean backgroundVideo) {
262         TEST_BACKGROUND_PLAYER = backgroundVideo;
263     }
264 
setItem(PhotoItem photoItem)265     public void setItem(PhotoItem photoItem) {
266         mPhotoItem = photoItem;
267         updateAdapter();
268     }
269 
getDisplayTitle(String title)270     static String getDisplayTitle(String title) {
271         switch (MovieData.sStatus) {
272             case MovieData.STATUS_OWN:
273                 title = title + "(Owned)";
274                 break;
275             case MovieData.STATUS_RENTED:
276                 title = title + "(Rented)";
277                 break;
278             case MovieData.STATUS_INIT:
279             default:
280         }
281         return title;
282     }
283 
updateAdapter()284     void updateAdapter() {
285         if (mRowsAdapter == null) {
286             return;
287         }
288         mRowsAdapter.clear();
289         new Handler().postDelayed(new Runnable() {
290             @Override
291             public void run() {
292                 final Context context = getActivity();
293                 if (context == null) {
294                     return;
295                 }
296 
297                 DetailsOverviewRow dor = new DetailsOverviewRow(
298                         getDisplayTitle(mPhotoItem.getTitle()));
299                 dor.setImageDrawable(ResourcesCompat.getDrawable(context.getResources(),
300                         mPhotoItem.getImageResourceId(), context.getTheme()));
301                 SparseArrayObjectAdapter adapter = new SparseArrayObjectAdapter();
302                 switch (MovieData.sStatus) {
303                     case MovieData.STATUS_INIT:
304                         adapter.set(ACTION_RENT, mActionRent);
305                         adapter.set(ACTION_BUY, mActionBuy);
306                         break;
307                     case MovieData.STATUS_OWN:
308                         adapter.set(ACTION_PLAY, mActionPlay);
309                         break;
310                     case MovieData.STATUS_RENTED:
311                         adapter.set(ACTION_PLAY, mActionPlay);
312                         adapter.set(ACTION_BUY, mActionBuy);
313                         break;
314                 }
315                 // one line text with icon
316                 Drawable d = ResourcesCompat.getDrawable(context.getResources(),
317                         R.drawable.ic_action_a, context.getTheme());
318                 adapter.set(202, new Action(202, "Top", null, d));
319                 dor.setActionsAdapter(adapter);
320                 mRowsAdapter.add(0, dor);
321                 setSelectedPosition(0, true);
322                 if (TEST_SHARED_ELEMENT_TRANSITION) {
323                     if (mHelper != null && !mHelper.getAutoStartSharedElementTransition()) {
324                         mHelper.startPostponedEnterTransition();
325                     }
326                 }
327             }
328         }, TIME_TO_LOAD_OVERVIEW_ROW_MS);
329 
330         new Handler().postDelayed(new Runnable() {
331             @Override
332             public void run() {
333                 if (getActivity() == null) {
334                     return;
335                 }
336                 for (int i = 0; i < NUM_ROWS; ++i) {
337                     ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(cardPresenter);
338                     listRowAdapter.add(new PhotoItem("Hello world", R.drawable.gallery_photo_1));
339                     listRowAdapter.add(new PhotoItem("This is a test", R.drawable.gallery_photo_2));
340                     listRowAdapter.add(new PhotoItem("Android TV", R.drawable.gallery_photo_3));
341                     listRowAdapter.add(new PhotoItem("Leanback", R.drawable.gallery_photo_4));
342                     HeaderItem header = new HeaderItem(i, "Row " + i);
343                     mRowsAdapter.add(new ListRow(header, listRowAdapter));
344                 }
345             }
346         }, TIME_TO_LOAD_RELATED_ROWS_MS);
347         setAdapter(mRowsAdapter);
348     }
349 
350     @Override
onStart()351     public void onStart() {
352         super.onStart();
353 
354         // Restore background drawable in onStart():
355         mBackgroundHelper.loadBitmap(R.drawable.spiderman,
356                 new BackgroundHelper.BitmapLoadCallback() {
357                     @Override
358                     public void onBitmapLoaded(Bitmap bitmap) {
359                         mDetailsBackground.setCoverBitmap(bitmap);
360                     }
361                 });
362     }
363 
364     @Override
onStop()365     public void onStop() {
366         mDetailsBackground.setCoverBitmap(null);
367         super.onStop();
368     }
369 }
370