blob: fa2e45163b25802c8ed035da562d3a00803646d4 [file] [log] [blame]
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.tv.search;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.os.AsyncTask;
import android.os.Bundle;
import androidx.leanback.app.SearchFragment;
import androidx.leanback.widget.ArrayObjectAdapter;
import androidx.leanback.widget.HeaderItem;
import androidx.leanback.widget.ImageCardView;
import androidx.leanback.widget.ListRow;
import androidx.leanback.widget.ListRowPresenter;
import androidx.leanback.widget.ObjectAdapter;
import androidx.leanback.widget.OnItemViewClickedListener;
import androidx.leanback.widget.Presenter;
import androidx.leanback.widget.Row;
import androidx.leanback.widget.RowPresenter;
import androidx.leanback.widget.SearchBar;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.android.tv.MainActivity;
import com.android.tv.R;
import com.android.tv.common.util.PermissionUtils;
import com.android.tv.util.images.ImageLoader;
import java.util.List;
public class ProgramGuideSearchFragment extends SearchFragment {
private static final String TAG = "ProgramGuideSearch";
private static final boolean DEBUG = false;
private static final int SEARCH_RESULT_MAX = 10;
private final Presenter mPresenter =
new Presenter() {
@Override
public Presenter.ViewHolder onCreateViewHolder(ViewGroup viewGroup) {
if (DEBUG) Log.d(TAG, "onCreateViewHolder");
ImageCardView cardView = new ImageCardView(mMainActivity);
cardView.setFocusable(true);
cardView.setFocusableInTouchMode(true);
cardView.setMainImageAdjustViewBounds(false);
Resources res = mMainActivity.getResources();
cardView.setMainImageDimensions(
res.getDimensionPixelSize(R.dimen.card_image_layout_width),
res.getDimensionPixelSize(R.dimen.card_image_layout_height));
return new Presenter.ViewHolder(cardView);
}
@Override
public void onBindViewHolder(ViewHolder viewHolder, Object o) {
ImageCardView cardView = (ImageCardView) viewHolder.view;
LocalSearchProvider.SearchResult result = (LocalSearchProvider.SearchResult) o;
if (DEBUG) Log.d(TAG, "onBindViewHolder result:" + result);
cardView.setTitleText(result.getTitle());
if (!TextUtils.isEmpty(result.getImageUri())) {
ImageLoader.loadBitmap(
mMainActivity,
result.getImageUri(),
mMainCardWidth,
mMainCardHeight,
createImageLoaderCallback(cardView));
} else {
cardView.setMainImage(
mMainActivity.getDrawable(R.drawable.ic_tv_app_96x96));
}
}
@Override
public void onUnbindViewHolder(ViewHolder viewHolder) {
// Do nothing here.
}
};
private static ImageLoader.ImageLoaderCallback<ImageCardView> createImageLoaderCallback(
ImageCardView cardView) {
return new ImageLoader.ImageLoaderCallback<ImageCardView>(cardView) {
@Override
public void onBitmapLoaded(ImageCardView cardView, Bitmap bitmap) {
cardView.setMainImage(
new BitmapDrawable(cardView.getContext().getResources(), bitmap));
}
};
}
private final SearchResultProvider mSearchResultProvider =
new SearchResultProvider() {
@Override
public ObjectAdapter getResultsAdapter() {
return mResultAdapter;
}
@Override
public boolean onQueryTextChange(String query) {
searchAndRefresh(query);
return true;
}
@Override
public boolean onQueryTextSubmit(String query) {
searchAndRefresh(query);
return true;
}
};
private final OnItemViewClickedListener mItemClickedListener =
new OnItemViewClickedListener() {
@Override
public void onItemClicked(
Presenter.ViewHolder viewHolder,
Object o,
RowPresenter.ViewHolder viewHolder1,
Row row) {
LocalSearchProvider.SearchResult result = (LocalSearchProvider.SearchResult) o;
mMainActivity.getFragmentManager().popBackStack();
mMainActivity.tuneToChannel(
mMainActivity
.getChannelDataManager()
.getChannel(result.getChannelId()));
}
};
private final ArrayObjectAdapter mResultAdapter =
new ArrayObjectAdapter(new ListRowPresenter());
private MainActivity mMainActivity;
private SearchInterface mSearch;
private int mMainCardWidth;
private int mMainCardHeight;
private SearchTask mSearchTask;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mMainActivity = (MainActivity) getActivity();
if (PermissionUtils.hasAccessAllEpg(mMainActivity)) {
mSearch = new TvProviderSearch(mMainActivity);
} else {
mSearch = new DataManagerSearch(mMainActivity);
}
Resources res = getResources();
mMainCardWidth = res.getDimensionPixelSize(R.dimen.card_image_layout_width);
mMainCardHeight = res.getDimensionPixelSize(R.dimen.card_image_layout_height);
}
@Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = super.onCreateView(inflater, container, savedInstanceState);
v.setBackgroundResource(R.color.program_guide_scrim);
setBadgeDrawable(mMainActivity.getDrawable(R.drawable.ic_tv_app_96x96));
setSearchResultProvider(mSearchResultProvider);
setOnItemViewClickedListener(mItemClickedListener);
return v;
}
@Override
public void onResume() {
super.onResume();
SearchBar searchBar = (SearchBar) getView().findViewById(R.id.lb_search_bar);
searchBar.setSearchQuery("");
mResultAdapter.clear();
}
private void searchAndRefresh(String query) {
// TODO: Search directly from program data manager for performance.
// TODO: Search upcoming programs.
if (mSearchTask != null) {
mSearchTask.cancel(true);
}
mSearchTask = new SearchTask(query);
mSearchTask.execute();
}
private class SearchTask extends AsyncTask<Void, Void, List<LocalSearchProvider.SearchResult>> {
private final String mQuery;
public SearchTask(String query) {
mQuery = query;
}
@Override
protected List<LocalSearchProvider.SearchResult> doInBackground(Void... params) {
return mSearch.search(
mQuery, SEARCH_RESULT_MAX, TvProviderSearch.ACTION_TYPE_AMBIGUOUS);
}
@Override
protected void onPostExecute(List<LocalSearchProvider.SearchResult> results) {
super.onPostExecute(results);
mResultAdapter.clear();
if (DEBUG) {
Log.d(
TAG,
"searchAndRefresh query="
+ mQuery
+ " results="
+ ((results == null) ? 0 : results.size()));
}
if (results == null || results.size() == 0) {
HeaderItem header =
new HeaderItem(
0, mMainActivity.getString(R.string.search_result_no_result));
ArrayObjectAdapter resultsAdapter = new ArrayObjectAdapter(mPresenter);
mResultAdapter.add(new ListRow(header, resultsAdapter));
} else {
HeaderItem header =
new HeaderItem(0, mMainActivity.getString(R.string.search_result_title));
ArrayObjectAdapter resultsAdapter = new ArrayObjectAdapter(mPresenter);
resultsAdapter.addAll(0, results);
mResultAdapter.add(new ListRow(header, resultsAdapter));
}
mSearchTask = null;
}
}
}