diff options
author | Christofer Ã…kersten <akersten@google.com> | 2014-07-17 08:59:36 +0900 |
---|---|---|
committer | Christofer Ã…kersten <akersten@google.com> | 2014-07-22 13:33:01 +0900 |
commit | e4896fa00737255cb3870271ea95a14dcf8208fc (patch) | |
tree | df47ba9d85bf02fe3aaf5a4cefc346f7ea81e12d | |
parent | b729a0a89c866665bd831ce250a811159169c749 (diff) | |
download | TV-e4896fa00737255cb3870271ea95a14dcf8208fc.tar.gz |
Add debug options menu.
Bug: 15490500
Change-Id: I16c06d0d24990f7910c2d7448040476e8a025409
-rw-r--r-- | res/drawable/debug_option_background.xml | 22 | ||||
-rw-r--r-- | res/layout/debug_option_action.xml | 36 | ||||
-rw-r--r-- | res/layout/debug_option_check_box.xml | 36 | ||||
-rw-r--r-- | res/layout/debug_option_divider.xml | 22 | ||||
-rw-r--r-- | res/layout/debug_option_radio_button.xml | 36 | ||||
-rw-r--r-- | res/layout/debug_option_sub_menu.xml | 36 | ||||
-rw-r--r-- | res/values/strings.xml | 4 | ||||
-rw-r--r-- | src/com/android/tv/TvActivity.java | 29 | ||||
-rw-r--r-- | src/com/android/tv/ui/BaseSideFragment.java | 17 | ||||
-rw-r--r-- | src/com/android/tv/ui/DebugOptionFragment.java | 334 | ||||
-rw-r--r-- | src/com/android/tv/ui/EditChannelsFragment.java | 2 |
11 files changed, 560 insertions, 14 deletions
diff --git a/res/drawable/debug_option_background.xml b/res/drawable/debug_option_background.xml new file mode 100644 index 00000000..284fd801 --- /dev/null +++ b/res/drawable/debug_option_background.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2014 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. +--> + +<selector xmlns:android="http://schemas.android.com/apk/res/android" > + <item android:state_focused="true" + android:drawable="@color/option_item_focused_background"/> + <item + android:drawable="@color/option_item_background"/> +</selector>
\ No newline at end of file diff --git a/res/layout/debug_option_action.xml b/res/layout/debug_option_action.xml new file mode 100644 index 00000000..d2345df7 --- /dev/null +++ b/res/layout/debug_option_action.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2014 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. +--> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="horizontal" + android:layout_width="match_parent" + android:layout_height="@dimen/option_item_height" + android:paddingLeft="@dimen/side_panel_padding_left" + android:focusable="true" + android:focusableInTouchMode="true" + android:background="@drawable/debug_option_background" > + + <TextView + android:id="@+id/title" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:gravity="center_vertical" + android:clickable="false" + android:fontFamily="@string/font" + android:textSize="@dimen/option_item_text_size" + android:textColor="@color/side_panel_item_text" /> + +</LinearLayout>
\ No newline at end of file diff --git a/res/layout/debug_option_check_box.xml b/res/layout/debug_option_check_box.xml new file mode 100644 index 00000000..4d04279f --- /dev/null +++ b/res/layout/debug_option_check_box.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2014 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. +--> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="horizontal" + android:layout_width="match_parent" + android:layout_height="@dimen/option_item_height" + android:paddingLeft="@dimen/side_panel_padding_left" + android:focusable="true" + android:focusableInTouchMode="true" + android:background="@drawable/debug_option_background" > + + <CheckBox + android:id="@+id/check_box" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:paddingLeft="@dimen/option_item_padding_left" + android:clickable="false" + android:fontFamily="@string/font" + android:textSize="@dimen/option_item_text_size" + android:textColor="@color/side_panel_item_text" /> + +</LinearLayout>
\ No newline at end of file diff --git a/res/layout/debug_option_divider.xml b/res/layout/debug_option_divider.xml new file mode 100644 index 00000000..32177f8d --- /dev/null +++ b/res/layout/debug_option_divider.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2014 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. +--> + +<View xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="1.5dp" + android:focusable="false" + android:focusableInTouchMode="false" + android:background="@color/side_panel_divider" />
\ No newline at end of file diff --git a/res/layout/debug_option_radio_button.xml b/res/layout/debug_option_radio_button.xml new file mode 100644 index 00000000..6e6a05a4 --- /dev/null +++ b/res/layout/debug_option_radio_button.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2014 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. +--> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="horizontal" + android:layout_width="match_parent" + android:layout_height="@dimen/option_item_height" + android:paddingLeft="@dimen/side_panel_padding_left" + android:focusable="true" + android:focusableInTouchMode="true" + android:background="@drawable/debug_option_background" > + + <RadioButton + android:id="@+id/radio_button" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:paddingLeft="@dimen/option_item_padding_left" + android:clickable="false" + android:fontFamily="@string/font" + android:textSize="@dimen/option_item_text_size" + android:textColor="@color/side_panel_item_text" /> + +</LinearLayout>
\ No newline at end of file diff --git a/res/layout/debug_option_sub_menu.xml b/res/layout/debug_option_sub_menu.xml new file mode 100644 index 00000000..d2345df7 --- /dev/null +++ b/res/layout/debug_option_sub_menu.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2014 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. +--> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="horizontal" + android:layout_width="match_parent" + android:layout_height="@dimen/option_item_height" + android:paddingLeft="@dimen/side_panel_padding_left" + android:focusable="true" + android:focusableInTouchMode="true" + android:background="@drawable/debug_option_background" > + + <TextView + android:id="@+id/title" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:gravity="center_vertical" + android:clickable="false" + android:fontFamily="@string/font" + android:textSize="@dimen/option_item_text_size" + android:textColor="@color/side_panel_item_text" /> + +</LinearLayout>
\ No newline at end of file diff --git a/res/values/strings.xml b/res/values/strings.xml index 079dd2d0..d59414fc 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -133,4 +133,8 @@ <!-- The text used when there is no program title. --> <string name="channel_banner_no_title">No title</string> + + <!-- Debug Options --> + <string name="menu_debug_options">Debug Options</string> + <string name="item_watch_history">Watch History</string> </resources> diff --git a/src/com/android/tv/TvActivity.java b/src/com/android/tv/TvActivity.java index 9b9db2e3..7e0db437 100644 --- a/src/com/android/tv/TvActivity.java +++ b/src/com/android/tv/TvActivity.java @@ -67,6 +67,7 @@ import com.android.tv.ui.BaseSideFragment; import com.android.tv.ui.ChannelBannerView; import com.android.tv.ui.ChannelNumberView; import com.android.tv.ui.ClosedCaptionOptionFragment; +import com.android.tv.ui.DebugOptionFragment; import com.android.tv.ui.DisplayModeOptionFragment; import com.android.tv.ui.EditChannelsFragment; import com.android.tv.ui.InputPickerFragment; @@ -80,6 +81,7 @@ import com.android.tv.util.TvInputManagerHelper; import com.android.tv.util.TvSettings; import com.android.tv.util.Utils; +import java.util.ArrayList; import java.util.HashSet; import java.util.List; @@ -555,6 +557,23 @@ public class TvActivity extends Activity implements AudioManager.OnAudioFocusCha showSideFragment(new PipLocationFragment(), initiator); } + public void showDebugOptions(int initiator) { + showSideFragment(new DebugOptionFragment() { + @Override + protected List<Item> buildItems() { + List<Item> items = new ArrayList<>(); + items.add(new ActionItem(getString(R.string.item_watch_history)) { + @Override + protected void onSelected() { + super.onSelected(); + showRecentlyWatchedDialog(); + } + }); + return items; + } + }, initiator); + } + public void showSideFragment(Fragment f, int initiator) { mSidePanelContainer.setTag(SIDE_FRAGMENT_TAG_SHOW); mSidePanelContainer.setKeyDispatchable(true); @@ -1031,9 +1050,6 @@ public class TvActivity extends Activity implements AudioManager.OnAudioFocusCha } if (mChannelMap == null) { switch (keyCode) { - case KeyEvent.KEYCODE_H: - showRecentlyWatchedDialog(); - return true; case KeyEvent.KEYCODE_TV_INPUT: case KeyEvent.KEYCODE_I: case KeyEvent.KEYCODE_CHANNEL_UP: @@ -1055,10 +1071,6 @@ public class TvActivity extends Activity implements AudioManager.OnAudioFocusCha return mChannelNumberView.onKeyUp(keyCode, event); } switch (keyCode) { - case KeyEvent.KEYCODE_H: - showRecentlyWatchedDialog(); - return true; - case KeyEvent.KEYCODE_TV_INPUT: case KeyEvent.KEYCODE_I: showInputPicker(BaseSideFragment.INITIATOR_UNKNOWN); @@ -1129,6 +1141,9 @@ public class TvActivity extends Activity implements AudioManager.OnAudioFocusCha showDisplayModeOption(BaseSideFragment.INITIATOR_SHORTCUT_KEY); return true; } + case KeyEvent.KEYCODE_D: + showDebugOptions(BaseSideFragment.INITIATOR_UNKNOWN); + return true; } } return super.onKeyUp(keyCode, event); diff --git a/src/com/android/tv/ui/BaseSideFragment.java b/src/com/android/tv/ui/BaseSideFragment.java index 8c5347a1..090fcd36 100644 --- a/src/com/android/tv/ui/BaseSideFragment.java +++ b/src/com/android/tv/ui/BaseSideFragment.java @@ -42,7 +42,6 @@ public class BaseSideFragment extends Fragment { private TextView mTitleView; private VerticalGridView mOptionItemListView; private LayoutInflater mLayoutInflater; - protected final OptionItemAdapter mAdapter = new OptionItemAdapter(); private Object[] mItemTags; private int mPrevSelectedItemPosition; private int mFragmentLayoutId; @@ -57,7 +56,7 @@ public class BaseSideFragment extends Fragment { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // initialize should be called before onCreateView. - Preconditions.checkState(mItemTags != null); + Preconditions.checkState(!TextUtils.isEmpty(mTitle)); Bundle arg = getArguments(); if (arg != null && arg.containsKey(KEY_INITIATOR)) { mInitiator = arg.getInt(KEY_INITIATOR); @@ -78,7 +77,7 @@ public class BaseSideFragment extends Fragment { } }); - mOptionItemListView.setAdapter(mAdapter); + mOptionItemListView.setAdapter(new OptionItemAdapter()); mLayoutInflater = inflater; return fragView; } @@ -87,9 +86,15 @@ public class BaseSideFragment extends Fragment { return mInitiator; } + public void notifyDataSetChanged() { + if (mOptionItemListView != null) { + mOptionItemListView.getAdapter().notifyDataSetChanged(); + } + } + public void setPrevSelectedItemPosition(int position) { mPrevSelectedItemPosition = position; - mAdapter.notifyDataSetChanged(); + notifyDataSetChanged(); } public void onItemFocusChanged(View v, boolean focusGained, int position, Object tag) { @@ -121,7 +126,7 @@ public class BaseSideFragment extends Fragment { mItemBgColor = getActivity().getResources().getColor(itemBgColorResId); mItemFocusedBgColor = getActivity().getResources().getColor(itemFocusedBgColorResId); mItemHeight = getActivity().getResources().getDimensionPixelOffset(itemHeightResId); - mAdapter.notifyDataSetChanged(); + notifyDataSetChanged(); } class OptionItemAdapter extends RecyclerView.Adapter<OptionItemAdapter.MyViewHolder> { @@ -140,7 +145,7 @@ public class BaseSideFragment extends Fragment { public void onFocusChange(View v, boolean focusGained) { int position = (Integer) v.getTag(R.id.TAG_OPTION_ITEM_POSITOIN); onItemFocusChanged(v, focusGained, position, mItemTags[position]); - } + } }); onCreatedChildView(v); return new MyViewHolder(v); diff --git a/src/com/android/tv/ui/DebugOptionFragment.java b/src/com/android/tv/ui/DebugOptionFragment.java new file mode 100644 index 00000000..0b6f7bd8 --- /dev/null +++ b/src/com/android/tv/ui/DebugOptionFragment.java @@ -0,0 +1,334 @@ +/* + * Copyright (C) 2014 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.ui; + +import android.app.FragmentManager; +import android.app.FragmentTransaction; +import android.os.Bundle; +import android.support.v17.leanback.widget.VerticalGridView; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.CheckBox; +import android.widget.RadioButton; +import android.widget.TextView; + +import com.android.tv.R; +import com.android.tv.TvActivity; + +import java.util.List; + +public class DebugOptionFragment extends BaseSideFragment { + private final boolean mSubOption; + private final String mHeader; + private final List<Item> mItems; + + public DebugOptionFragment() { + mSubOption = false; + mHeader = null; + mItems = null; + } + + private DebugOptionFragment(String header, List<Item> items) { + mSubOption = true; + mHeader = header; + mItems = items; + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + initialize(mHeader == null ? getString(R.string.menu_debug_options) : mHeader, null, + R.layout.option_fragment, 0, R.color.option_item_background, + R.color.option_item_focused_background, R.dimen.option_item_height); + View view = super.onCreateView(inflater, container, savedInstanceState); + VerticalGridView listView = (VerticalGridView) view.findViewById(R.id.side_panel_list); + listView.setAdapter(new ItemAdapter(inflater, mItems == null ? buildItems() : mItems)); + setSelectedPosition(0); + if (mSubOption) { + view.findViewById(R.id.side_panel_shadow).setVisibility(View.GONE); + } + return view; + } + + @Override + public void onDetach() { + super.onDetach(); + if (!mSubOption) { + getTvActivity().onSideFragmentCanceled(getInitiator()); + getTvActivity().hideOverlays(false, false, true); + } + } + + protected List<Item> buildItems() { + return null; + } + + private TvActivity getTvActivity() { + return (TvActivity) getActivity(); + } + + public static abstract class Item { + protected abstract int getResourceId(); + protected void bind(@SuppressWarnings("unused") View view) { } + protected void unbind() { } + protected void onSelected() { } + protected void onFocused() { } + } + + public static class DividerItem extends Item { + @Override + protected int getResourceId() { + return R.layout.debug_option_divider; + } + } + + public static class ActionItem extends Item { + private final String mTitle; + private TextView mTitleView; + + public ActionItem(String title) { + mTitle = title; + } + + @Override + protected int getResourceId() { + return R.layout.debug_option_action; + } + + @Override + protected void bind(View view) { + mTitleView = (TextView) view.findViewById(R.id.title); + mTitleView.setText(mTitle); + } + + @Override + protected void unbind() { + mTitleView = null; + } + } + + public static class SubMenuItem extends Item { + private final String mTitle; + private final FragmentManager mFragmentManager; + private TextView mTitleView; + + public SubMenuItem(String title, FragmentManager fragmentManager) { + mTitle = title; + mFragmentManager = fragmentManager; + } + + @Override + protected int getResourceId() { + return R.layout.debug_option_sub_menu; + } + + @Override + protected void bind(View view) { + mTitleView = (TextView) view.findViewById(R.id.title); + mTitleView.setText(mTitle); + } + + @Override + protected void unbind() { + mTitleView = null; + } + + @Override + protected void onSelected() { + mFragmentManager + .beginTransaction() + .add(R.id.right_panel, new DebugOptionFragment(mTitle, buildItems())) + .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN) + .addToBackStack(null) + .commit(); + } + + protected List<Item> buildItems() { + return null; + } + } + + public static class CheckBoxItem extends Item { + private final String mTitle; + private boolean mChecked; + private CheckBox mCheckBox; + + public CheckBoxItem(String title) { + mTitle = title; + } + + @Override + protected int getResourceId() { + return R.layout.debug_option_check_box; + } + + @Override + protected void bind(View view) { + mCheckBox = (CheckBox) view.findViewById(R.id.check_box); + mCheckBox.setText(mTitle); + mCheckBox.setChecked(mChecked); + } + + @Override + protected void unbind() { + mCheckBox = null; + } + + @Override + protected void onSelected() { + setChecked(!mChecked); + } + + public void setChecked(boolean checked) { + if (mChecked != checked) { + mChecked = checked; + if (mCheckBox != null) { + mCheckBox.setChecked(mChecked); + } + } + } + } + + public static class RadioButtonItem extends Item { + private final String mTitle; + private boolean mChecked; + private RadioButton mRadioButton; + + public RadioButtonItem(String title) { + mTitle = title; + } + + @Override + protected int getResourceId() { + return R.layout.debug_option_radio_button; + } + + @Override + protected void bind(View view) { + mRadioButton = (RadioButton) view.findViewById(R.id.radio_button); + mRadioButton.setText(mTitle); + mRadioButton.setChecked(mChecked); + } + + @Override + protected void unbind() { + mRadioButton = null; + } + + @Override + protected void onSelected() { + setChecked(true); + } + + public void setChecked(boolean checked) { + if (mChecked != checked) { + mChecked = checked; + if (mRadioButton != null) { + mRadioButton.setChecked(mChecked); + } + } + } + } + + private static class ItemAdapter extends RecyclerView.Adapter<ItemAdapter.ViewHolder> { + private final LayoutInflater mLayoutInflater; + private final List<Item> mItems; + + private ItemAdapter(LayoutInflater layoutInflater, List<Item> items) { + mLayoutInflater = layoutInflater; + mItems = items; + } + + @Override + public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View view = mLayoutInflater.inflate(viewType, parent, false); + final ViewHolder holder = new ViewHolder(view); + view.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if (holder.item instanceof RadioButtonItem) { + clearRadioGroup(holder.item); + } + holder.item.onSelected(); + } + }); + view.setOnFocusChangeListener(new View.OnFocusChangeListener() { + @Override + public void onFocusChange(View view, boolean focusGained) { + if (focusGained) { + holder.item.onFocused(); + } + } + }); + return holder; + } + + @Override + public void onBindViewHolder(ViewHolder holder, int position) { + holder.item = getItem(position); + holder.item.bind(holder.itemView); + } + + @Override + public void onViewRecycled(ViewHolder holder) { + holder.item.unbind(); + holder.item = null; + } + + @Override + public int getItemViewType(int position) { + return getItem(position).getResourceId(); + } + + @Override + public int getItemCount() { + return mItems == null ? 0 : mItems.size(); + } + + private Item getItem(int position) { + return mItems.get(position); + } + + private void clearRadioGroup(Item item) { + int position = mItems.indexOf(item); + for (int i = position - 1; i >= 0; --i) { + if ((item = mItems.get(i)) instanceof RadioButtonItem) { + ((RadioButtonItem) item).setChecked(false); + } else { + break; + } + } + for (int i = position + 1; i < mItems.size(); ++i) { + if ((item = mItems.get(i)) instanceof RadioButtonItem) { + ((RadioButtonItem) item).setChecked(false); + } else { + break; + } + } + } + + private static class ViewHolder extends RecyclerView.ViewHolder { + public Item item; + + private ViewHolder(View view) { + super(view); + } + } + } +}
\ No newline at end of file diff --git a/src/com/android/tv/ui/EditChannelsFragment.java b/src/com/android/tv/ui/EditChannelsFragment.java index 040c23c4..473bd308 100644 --- a/src/com/android/tv/ui/EditChannelsFragment.java +++ b/src/com/android/tv/ui/EditChannelsFragment.java @@ -192,7 +192,7 @@ public class EditChannelsFragment extends BaseSideFragment { for (Channel channel : mChannels) { channel.setBrowsable(browsable); } - mAdapter.notifyDataSetChanged(); + notifyDataSetChanged(); if (browsable) { mBrowsableChannelCount = mChannels.length; |