diff options
author | Nick Chalko <nchalko@google.com> | 2015-12-09 13:48:17 -0800 |
---|---|---|
committer | Nick Chalko <nchalko@google.com> | 2015-12-11 15:09:19 -0800 |
commit | 1abddd9f6225298066094e20a6c29061b6af4590 (patch) | |
tree | 97d701f8681cca9939c86e5e61523775d4c13aea /src/com/android/tv/onboarding/SetupSourcesFragment.java | |
parent | 7d67089aa1e9aa2123c3cd2f386d7019a1544db1 (diff) | |
download | TV-1abddd9f6225298066094e20a6c29061b6af4590.tar.gz |
Sync to ub-tv-heroes at 1.08.301
source change id If9b64d7bbc6e8f77b360e502d34e5452775c0402
Change-Id: I4ffe87911cb85e54880d1d918d1b8fb7bb8cfb7d
Diffstat (limited to 'src/com/android/tv/onboarding/SetupSourcesFragment.java')
-rw-r--r-- | src/com/android/tv/onboarding/SetupSourcesFragment.java | 218 |
1 files changed, 213 insertions, 5 deletions
diff --git a/src/com/android/tv/onboarding/SetupSourcesFragment.java b/src/com/android/tv/onboarding/SetupSourcesFragment.java index 3572a209..ad49dc23 100644 --- a/src/com/android/tv/onboarding/SetupSourcesFragment.java +++ b/src/com/android/tv/onboarding/SetupSourcesFragment.java @@ -16,18 +16,36 @@ package com.android.tv.onboarding; -import android.app.Fragment; +import android.content.ActivityNotFoundException; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.media.tv.TvInputInfo; import android.os.Bundle; import android.support.v17.leanback.widget.GuidanceStylist.Guidance; import android.support.v17.leanback.widget.GuidedAction; +import android.support.v17.leanback.widget.VerticalGridView; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.RecyclerView.ViewHolder; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.Toast; +import com.android.tv.ApplicationSingletons; import com.android.tv.R; +import com.android.tv.SetupPassthroughActivity; +import com.android.tv.TvApplication; +import com.android.tv.common.TvCommonUtils; import com.android.tv.common.ui.setup.SetupGuidedStepFragment; import com.android.tv.common.ui.setup.SetupMultiPaneFragment; +import com.android.tv.data.ChannelDataManager; +import com.android.tv.data.TvInputNewComparator; +import com.android.tv.util.SetupUtils; +import com.android.tv.util.TvInputManagerHelper; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; /** @@ -43,11 +61,61 @@ public class SetupSourcesFragment extends SetupMultiPaneFragment { } @Override - protected Fragment getContentFragment() { - return new ContentFragment(); + protected SetupGuidedStepFragment onCreateContentFragment() { + SetupGuidedStepFragment fragment = new ContentFragment(getActivity()); + Bundle arguments = new Bundle(); + arguments.putBoolean(SetupGuidedStepFragment.KEY_THREE_PANE, true); + fragment.setArguments(arguments); + return fragment; } private class ContentFragment extends SetupGuidedStepFragment { + private static final int REQUEST_CODE_START_SETUP_ACTIVITY = 1; + + private static final int ACTION_DIVIDER = ACTION_DONE + 1; + private static final int ACTION_INPUT_START = ACTION_DONE + 2; + + private final TvInputManagerHelper mInputManager; + private final ChannelDataManager mChannelDataManager; + private final SetupUtils mSetupUtils; + private List<TvInputInfo> mInputList; + private SetupSourcesAdapter mAdapter; + private int mKnownInputStartIndex; + private boolean mShowDivider; + + ContentFragment(Context context) { + // TODO: Handle USB TV tuner differently. + ApplicationSingletons app = TvApplication.getSingletons(context); + mInputManager = app.getTvInputManagerHelper(); + mChannelDataManager = app.getChannelDataManager(); + mSetupUtils = SetupUtils.getInstance(context); + mInputList = mInputManager.getTvInputInfos(true, true); + Collections.sort(mInputList, new TvInputNewComparator(mSetupUtils, mInputManager)); + mKnownInputStartIndex = 0; + for (TvInputInfo input : mInputList) { + if (mSetupUtils.isNewInput(input.getId())) { + mSetupUtils.markAsKnownInput(input.getId()); + ++mKnownInputStartIndex; + } + } + mShowDivider = mKnownInputStartIndex != 0 && mKnownInputStartIndex != mInputList.size(); + if (mAdapter != null) { + mAdapter.notifyDataSetChanged(); + } + } + + @SuppressWarnings("rawtypes") + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View view = super.onCreateView(inflater, container, savedInstanceState); + VerticalGridView gridView = getGuidedActionsStylist().getActionsGridView(); + RecyclerView.Adapter adapter = gridView.getAdapter(); + mAdapter = new SetupSourcesAdapter(adapter); + gridView.setAdapter(mAdapter); + return view; + } + @Override public Guidance onCreateGuidance(Bundle savedInstanceState) { String title = getString(R.string.setup_sources_text); @@ -57,8 +125,148 @@ public class SetupSourcesFragment extends SetupMultiPaneFragment { @Override public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) { - actions.add(new GuidedAction.Builder().id(ACTION_DONE).title("Done") - .description("Return to previous page").build()); + createActionsInternal(actions); + if (!mChannelDataManager.isDbLoadFinished()) { + mChannelDataManager.addListener(new ChannelDataManager.Listener() { + @Override + public void onLoadFinished() { + mChannelDataManager.removeListener(this); + updateActions(); + } + + @Override + public void onChannelListUpdated() { } + + @Override + public void onChannelBrowsableChanged() { } + }); + } + } + + private void updateActions() { + List<GuidedAction> actions = new ArrayList<>(); + createActionsInternal(actions); + setActions(actions); + mAdapter.notifyDataSetChanged(); + } + + private void createActionsInternal(List<GuidedAction> actions) { + for (int i = 0; i < mInputList.size(); ++i) { + if (mShowDivider && i == mKnownInputStartIndex) { + actions.add(new GuidedAction.Builder().id(ACTION_DIVIDER).title(null) + .description(null).build()); + } + TvInputInfo input = mInputList.get(i); + String description; + int channelCount = mChannelDataManager.getChannelCountForInput(input.getId()); + if (mSetupUtils.isSetupDone(input.getId())) { + if (channelCount == 0) { + description = getResources().getString(R.string.setup_input_no_channels); + } else { + description = getResources().getQuantityString( + R.plurals.setup_input_channels, channelCount, channelCount); + } + } else if (i >= mKnownInputStartIndex) { + description = getResources().getString(R.string.channel_description_setup_now); + } else { + description = getResources().getString(R.string.setup_input_new); + } + actions.add(new GuidedAction.Builder().id(ACTION_INPUT_START + i) + .title(input.loadLabel(getActivity()).toString()).description(description) + .build()); + } + } + + @Override + public void onGuidedActionClicked(GuidedAction action) { + TvInputInfo input = mInputList.get((int) action.getId() - ACTION_INPUT_START); + Intent intent = TvCommonUtils.createSetupIntent(input); + if (intent == null) { + Toast.makeText(getActivity(), R.string.msg_no_setup_activity, Toast.LENGTH_SHORT) + .show(); + return; + } + // Even though other app can handle the intent, the setup launched by Live channels + // should go through Live channels SetupPassthroughActivity. + intent.setComponent(new ComponentName(getActivity(), SetupPassthroughActivity.class)); + try { + // Now we know that the user intends to set up this input. Grant permission for writing + // EPG data. + SetupUtils.grantEpgPermission(getActivity(), input.getServiceInfo().packageName); + startActivityForResult(intent, REQUEST_CODE_START_SETUP_ACTIVITY); + } catch (ActivityNotFoundException e) { + Toast.makeText(getActivity(), getString(R.string.msg_unable_to_start_setup_activity, + input.loadLabel(getActivity())), Toast.LENGTH_SHORT).show(); + return; + } + } + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + updateActions(); + } + + @SuppressWarnings("rawtypes") + private class SetupSourcesAdapter extends RecyclerView.Adapter { + private static final int VIEW_TYPE_INPUT = 1; + private static final int VIEW_TYPE_DIVIDER = 2; + + private final RecyclerView.Adapter mGuidedActionAdapter; + + SetupSourcesAdapter(RecyclerView.Adapter adapter) { + mGuidedActionAdapter = adapter; + } + + @Override + public int getItemViewType(int position) { + if (mShowDivider && position == mKnownInputStartIndex) { + return VIEW_TYPE_DIVIDER; + } + return VIEW_TYPE_INPUT; + } + + @Override + public int getItemCount() { + if (mInputList == null) { + return 0; + } + return mInputList.size() + (mShowDivider ? 1 : 0); + } + + @Override + public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + if (viewType == VIEW_TYPE_INPUT) { + return mGuidedActionAdapter.onCreateViewHolder(parent, viewType); + } + View itemView = LayoutInflater.from(parent.getContext()).inflate( + R.layout.onboarding_item_divider, parent, false); + return new MyViewHolder(itemView); + } + + @SuppressWarnings("unchecked") + @Override + public void onBindViewHolder(ViewHolder viewHolder, int position) { + if (mShowDivider && position == mKnownInputStartIndex) { + return; + } + mGuidedActionAdapter.onBindViewHolder(viewHolder, position); + } + + @Override + public void onAttachedToRecyclerView(RecyclerView recyclerView) { + mGuidedActionAdapter.onAttachedToRecyclerView(recyclerView); + } + + @Override + public void onDetachedFromRecyclerView(RecyclerView recyclerView) { + mGuidedActionAdapter.onDetachedFromRecyclerView(recyclerView); + } + } + } + + private static class MyViewHolder extends RecyclerView.ViewHolder { + public MyViewHolder(View itemView) { + super(itemView); } } } |