1 /*
2  * Copyright (C) 2018 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 
17 package com.android.car.radio;
18 
19 import static com.android.car.ui.core.CarUi.requireInsets;
20 
21 import android.content.Context;
22 import android.os.Bundle;
23 import android.view.LayoutInflater;
24 import android.view.View;
25 import android.view.ViewGroup;
26 
27 import androidx.fragment.app.Fragment;
28 import androidx.recyclerview.widget.LinearLayoutManager;
29 
30 import com.android.car.broadcastradio.support.Program;
31 import com.android.car.radio.storage.RadioStorage;
32 import com.android.car.radio.util.Log;
33 import com.android.car.ui.baselayout.Insets;
34 import com.android.car.ui.baselayout.InsetsChangedListener;
35 import com.android.car.ui.recyclerview.CarUiRecyclerView;
36 
37 /**
38  * Fragment that shows all browseable radio stations from background scan
39  */
40 public class BrowseFragment extends Fragment implements InsetsChangedListener {
41     private static final String TAG = "BcRadioApp.BrwFrg";
42 
43     private RadioController mRadioController;
44     private BrowseAdapter mBrowseAdapter;
45     private RadioStorage mRadioStorage;
46     private View mRootView;
47     private CarUiRecyclerView mBrowseList;
48 
49     @Override
onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)50     public View onCreateView(LayoutInflater inflater, ViewGroup container,
51             Bundle savedInstanceState) {
52         mRootView = inflater.inflate(R.layout.browse_fragment, container, false);
53         return mRootView;
54     }
55 
56     @Override
onViewCreated(View view, Bundle savedInstanceState)57     public void onViewCreated(View view, Bundle savedInstanceState) {
58         Context context = getContext();
59 
60         mRadioStorage = RadioStorage.getInstance(context);
61         mBrowseAdapter = new BrowseAdapter(this, mRadioController.getCurrentProgram(),
62                 mRadioStorage.getFavorites());
63 
64         mBrowseAdapter.setOnItemClickListener(mRadioController::tune);
65         mBrowseAdapter.setOnItemFavoriteListener(this::handlePresetItemFavoriteChanged);
66 
67         mBrowseList = view.findViewById(R.id.browse_list);
68         mBrowseList.setLayoutManager(new LinearLayoutManager(context));
69         mBrowseList.setAdapter(mBrowseAdapter);
70         mBrowseList.setVerticalFadingEdgeEnabled(true);
71         mBrowseList.setFadingEdgeLength(getResources()
72                 .getDimensionPixelSize(R.dimen.browse_list_fading_edge_length));
73 
74         mRadioController.getProgramList().observe(this, mBrowseAdapter::setProgramList);
75     }
76 
77     @Override
setUserVisibleHint(boolean isVisibleToUser)78     public void setUserVisibleHint(boolean isVisibleToUser) {
79         super.setUserVisibleHint(isVisibleToUser);
80 
81         if (!isVisibleToUser) return;
82 
83         try {
84             mRadioController.setSkipMode(SkipMode.BROWSE);
85         } catch (IllegalStateException e) {
86             Log.e(TAG, "Can't set skip mode", e);
87         }
88     }
89 
90     @Override
onCarUiInsetsChanged(Insets insets)91     public void onCarUiInsetsChanged(Insets insets) {
92         View view = requireView();
93         View recyclerView = view.findViewById(R.id.browse_list);
94         recyclerView.setPadding(insets.getLeft(),
95                 insets.getTop(),
96                 insets.getRight(),
97                 insets.getBottom());
98     }
99 
100     @Override
onStart()101     public void onStart() {
102         super.onStart();
103 
104         // This is needed to apply the inset changes that happened before this fragment was visible
105         onCarUiInsetsChanged(requireInsets(getActivity()));
106     }
107 
handlePresetItemFavoriteChanged(Program program, boolean saveAsFavorite)108     private void handlePresetItemFavoriteChanged(Program program, boolean saveAsFavorite) {
109         if (saveAsFavorite) {
110             mRadioStorage.addFavorite(program);
111         } else {
112             mRadioStorage.removeFavorite(program.getSelector());
113         }
114     }
115 
newInstance(RadioController radioController)116     static BrowseFragment newInstance(RadioController radioController) {
117         BrowseFragment fragment = new BrowseFragment();
118         fragment.mRadioController = radioController;
119         return fragment;
120     }
121 }
122