BrowseInfo.java revision 0898ab0f3d589be95488997e7ec1a8cc2a06b399
165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane/* 265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Copyright (C) 2014 The Android Open Source Project 365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Licensed under the Apache License, Version 2.0 (the "License"); 565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * you may not use this file except in compliance with the License. 665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * You may obtain a copy of the License at 765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * http://www.apache.org/licenses/LICENSE-2.0 965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 1065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Unless required by applicable law or agreed to in writing, software 1165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * distributed under the License is distributed on an "AS IS" BASIS, 1265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * See the License for the specific language governing permissions and 1465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * limitations under the License. 1565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 1665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 1765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lanepackage com.android.tv.settings; 1865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 1965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.accounts.Account; 2065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.accounts.AccountManager; 2165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.bluetooth.BluetoothAdapter; 2265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.bluetooth.BluetoothDevice; 2365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.content.ComponentName; 2465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.content.Context; 2565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.content.Intent; 2665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.content.res.TypedArray; 2765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.content.res.XmlResourceParser; 2865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.media.tv.TvInputInfo; 2965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.media.tv.TvInputManager; 3065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.os.Bundle; 3165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.os.Handler; 3265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.preference.PreferenceActivity; 3365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.support.v17.leanback.widget.ArrayObjectAdapter; 3465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.support.v17.leanback.widget.HeaderItem; 3565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.support.v17.leanback.widget.ObjectAdapter; 3665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.support.v17.leanback.widget.ListRow; 3765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.util.AttributeSet; 3865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.util.Log; 3965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.util.TypedValue; 4065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.util.Xml; 4165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 4265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.internal.util.XmlUtils; 4365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 4465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.accessories.AccessoryUtils; 4565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.accessories.BluetoothAccessoryActivity; 4665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.accounts.AccountImageUriGetter; 4765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.accounts.AccountSettingsActivity; 4865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.accounts.AuthenticatorHelper; 4965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.connectivity.ConnectivityStatusIconUriGetter; 5065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.connectivity.ConnectivityStatusTextGetter; 5165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.connectivity.WifiNetworksActivity; 5265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.device.sound.SoundActivity; 530898ab0f3d589be95488997e7ec1a8cc2a06b399Tim Kilbournimport com.android.tv.settings.users.RestrictedProfileActivity; 5465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.util.UriUtils; 5565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 5665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport org.xmlpull.v1.XmlPullParser; 5765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport org.xmlpull.v1.XmlPullParserException; 5865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 5965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport java.io.IOException; 6065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport java.util.HashSet; 6165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport java.util.Set; 6265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 6365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane/** 6465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Gets the list of browse headers and browse items. 6565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 6665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lanepublic class BrowseInfo extends BrowseInfoBase { 6765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 6865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String TAG = "CanvasSettings.BrowseInfo"; 6965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final boolean DEBUG = false; 7065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 7165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public static final String EXTRA_ACCESSORY_ADDRESS = "accessory_address"; 7265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public static final String EXTRA_ACCESSORY_NAME = "accessory_name"; 7365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public static final String EXTRA_ACCESSORY_ICON_ID = "accessory_icon_res"; 7465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 7565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String ACCOUNT_TYPE_GOOGLE = "com.google"; 7665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 7765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String ETHERNET_PREFERENCE_KEY = "ethernet"; 7865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 7965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane interface XmlReaderListener { 8065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane void handleRequestedNode(Context context, XmlResourceParser parser, AttributeSet attrs) 8165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane throws org.xmlpull.v1.XmlPullParserException, IOException; 8265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 8365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 8465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane static class SoundActivityImageUriGetter implements MenuItem.UriGetter { 8565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 8665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private final Context mContext; 8765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 8865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane SoundActivityImageUriGetter(Context context) { 8965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mContext = context; 9065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 9165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 9265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 9365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public String getUri() { 9465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return UriUtils.getAndroidResourceUri(mContext.getResources(), 9565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane SoundActivity.getIconResource(mContext.getContentResolver())); 9665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 9765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 9865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 9965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane static class XmlReader { 10065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 10165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private final Context mContext; 10265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private final int mXmlResource; 10365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private final String mRootNodeName; 10465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private final String mNodeNameRequested; 10565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private final XmlReaderListener mListener; 10665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 10765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane XmlReader(Context context, int xmlResource, String rootNodeName, String nodeNameRequested, 10865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane XmlReaderListener listener) { 10965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mContext = context; 11065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mXmlResource = xmlResource; 11165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mRootNodeName = rootNodeName; 11265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mNodeNameRequested = nodeNameRequested; 11365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mListener = listener; 11465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 11565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 11665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane void read() { 11765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane XmlResourceParser parser = null; 11865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane try { 11965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane parser = mContext.getResources().getXml(mXmlResource); 12065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane AttributeSet attrs = Xml.asAttributeSet(parser); 12165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 12265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int type; 12365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 12465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane && type != XmlPullParser.START_TAG) { 12565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // Parse next until start tag is found 12665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 12765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 12865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String nodeName = parser.getName(); 12965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (!mRootNodeName.equals(nodeName)) { 13065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane throw new RuntimeException("XML document must start with <" + mRootNodeName 13165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane + "> tag; found" + nodeName + " at " + parser.getPositionDescription()); 13265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 13365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 13465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Bundle curBundle = null; 13565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 13665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane final int outerDepth = parser.getDepth(); 13765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 13865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 13965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 14065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane continue; 14165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 14265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 14365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane nodeName = parser.getName(); 14465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (mNodeNameRequested.equals(nodeName)) { 14565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mListener.handleRequestedNode(mContext, parser, attrs); 14665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 14765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane XmlUtils.skipCurrentTag(parser); 14865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 14965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 15065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 15165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } catch (XmlPullParserException e) { 15265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane throw new RuntimeException("Error parsing headers", e); 15365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } catch (IOException e) { 15465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane throw new RuntimeException("Error parsing headers", e); 15565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } finally { 15665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (parser != null) 15765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane parser.close(); 15865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 15965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 16065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 16165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 16265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String PREF_KEY_ADD_ACCOUNT = "add_account"; 16365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String PREF_KEY_ADD_ACCESSORY = "add_accessory"; 16465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String PREF_KEY_WIFI = "wifi"; 16565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String PREF_KEY_DEVELOPER = "developer"; 16665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String PREF_KEY_INPUTS = "inputs"; 16765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 16865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private final Context mContext; 16965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private final AuthenticatorHelper mAuthenticatorHelper; 17065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private int mNextItemId; 17165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private int mAccountHeaderId; 17265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private final BluetoothAdapter mBtAdapter; 17365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private final Set<BluetoothDevice> mConnectedDevices; 17465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private final Object mGuard = new Object(); 17565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private final boolean mAllowMultipleAccounts; 17665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private MenuItem mWifiItem = null; 17765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private ArrayObjectAdapter mWifiRow = null; 17865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private final Handler mHandler = new Handler(); 17965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 18065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private PreferenceUtils mPreferenceUtils; 18165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private boolean mDeveloperEnabled; 18265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private boolean mInputSettingNeeded; 18365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 18465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private final Runnable refreshWifiCardRunnable = new Runnable() { 18565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void run() { 18665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane refreshWifiCard(); 18765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 18865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane }; 18965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 19065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane BrowseInfo(Context context) { 19165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mContext = context; 19265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mAuthenticatorHelper = new AuthenticatorHelper(); 19365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mAuthenticatorHelper.updateAuthDescriptions(context); 19465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mAuthenticatorHelper.onAccountsUpdated(context, null); 19565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mBtAdapter = BluetoothAdapter.getDefaultAdapter(); 19665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mConnectedDevices = new HashSet<BluetoothDevice>(); 19765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mNextItemId = 0; 19865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mAllowMultipleAccounts = 19965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane context.getResources().getBoolean(R.bool.multiple_accounts_enabled); 20065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mPreferenceUtils = new PreferenceUtils(context); 20165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mDeveloperEnabled = mPreferenceUtils.isDeveloperEnabled(); 20265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mInputSettingNeeded = isInputSettingNeeded(); 20365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 20465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 20565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 20665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void refreshContent() { 20765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane init(); 20865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 20965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 21065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane void init() { 21165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane synchronized (mGuard) { 21265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mHeaderItems.clear(); 21365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mRows.clear(); 21465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane new XmlReader(mContext, R.xml.main, "preference-headers", "header", 21565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane new HeaderXmlReaderListener()).read(); 21665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane updateAccessories(R.id.accessories); 21765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 21865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 21965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 22065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane void checkForDeveloperOptionUpdate() { 22165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane final boolean developerEnabled = mPreferenceUtils.isDeveloperEnabled(); 22265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (developerEnabled != mDeveloperEnabled) { 22365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mDeveloperEnabled = developerEnabled; 22465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane init(); 22565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 22665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 22765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 22865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private class HeaderXmlReaderListener implements XmlReaderListener { 22965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 23065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void handleRequestedNode(Context context, XmlResourceParser parser, 23165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane AttributeSet attrs) 23265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane throws XmlPullParserException, IOException { 23365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane TypedArray sa = mContext.getResources().obtainAttributes(attrs, 23465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane com.android.internal.R.styleable.PreferenceHeader); 23565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane final int headerId = sa.getResourceId( 23665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane com.android.internal.R.styleable.PreferenceHeader_id, 23765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane (int) PreferenceActivity.HEADER_ID_UNDEFINED); 23865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String title = getStringFromTypedArray(sa, 23965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane com.android.internal.R.styleable.PreferenceHeader_title); 24065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane sa.recycle(); 24165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane sa = context.getResources().obtainAttributes(attrs, R.styleable.CanvasSettings); 24265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int preferenceRes = sa.getResourceId(R.styleable.CanvasSettings_preference, 0); 24365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane sa.recycle(); 24465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mHeaderItems.add(new HeaderItem(headerId, title, null)); 24565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane final ArrayObjectAdapter currentRow = new ArrayObjectAdapter(); 24665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mRows.put(headerId, currentRow); 24765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (headerId != R.id.accessories) { 24865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane new XmlReader(context, preferenceRes, "PreferenceScreen", "Preference", 24965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane new PreferenceXmlReaderListener(headerId, currentRow)).read(); 25065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 25165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 25265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 25365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 2540898ab0f3d589be95488997e7ec1a8cc2a06b399Tim Kilbourn private boolean canAddAccount() { 2550898ab0f3d589be95488997e7ec1a8cc2a06b399Tim Kilbourn return !RestrictedProfileActivity.isRestrictedProfileInEffect(mContext); 2560898ab0f3d589be95488997e7ec1a8cc2a06b399Tim Kilbourn } 2570898ab0f3d589be95488997e7ec1a8cc2a06b399Tim Kilbourn 25865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private class PreferenceXmlReaderListener implements XmlReaderListener { 25965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 26065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private final int mHeaderId; 26165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private final ArrayObjectAdapter mRow; 26265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 26365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane PreferenceXmlReaderListener(int headerId, ArrayObjectAdapter row) { 26465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mHeaderId = headerId; 26565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mRow = row; 26665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 26765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 26865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 26965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void handleRequestedNode(Context context, XmlResourceParser parser, 27065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane AttributeSet attrs) throws XmlPullParserException, IOException { 27165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane TypedArray sa = context.getResources().obtainAttributes(attrs, 27265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane com.android.internal.R.styleable.Preference); 27365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 27465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String key = getStringFromTypedArray(sa, 27565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane com.android.internal.R.styleable.Preference_key); 27665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String title = getStringFromTypedArray(sa, 27765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane com.android.internal.R.styleable.Preference_title); 27865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int iconRes = sa.getResourceId(com.android.internal.R.styleable.Preference_icon, 27965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane R.drawable.settings_default_icon); 28065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane sa.recycle(); 28165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 28265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (PREF_KEY_ADD_ACCOUNT.equals(key)) { 28365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mAccountHeaderId = mHeaderId; 28465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane addAccounts(mRow); 28565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else if ((!key.equals(PREF_KEY_DEVELOPER) || mDeveloperEnabled) 28665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane && (!key.equals(PREF_KEY_INPUTS) || mInputSettingNeeded)) { 28765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane MenuItem.TextGetter descriptionGetter = getDescriptionTextGetterFromKey(key); 28865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane MenuItem.UriGetter uriGetter = getIconUriGetterFromKey(key); 28965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane MenuItem.Builder builder = new MenuItem.Builder().id(mNextItemId++).title(title) 29065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .descriptionGetter(descriptionGetter) 29165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .intent(getIntent(parser, attrs, mHeaderId)); 29265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if(uriGetter == null) { 29365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane builder.imageResourceId(mContext, iconRes); 29465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 29565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane builder.imageUriGetter(uriGetter); 29665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 29765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (key.equals(PREF_KEY_WIFI)) { 29865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mWifiItem = builder.build(); 29965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mRow.add(mWifiItem); 30065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mWifiRow = mRow; 30165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 30265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mRow.add(builder.build()); 30365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 30465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 30565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 30665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 30765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 30865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private void refreshWifiCard() { 30965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (mWifiItem != null) { 31065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int index = mWifiRow.indexOf(mWifiItem); 31165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (index >= 0) { 31265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mWifiRow.notifyArrayItemRangeChanged(index, 1); 31365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 31465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 31565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 31665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 31765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane void rebuildInfo() { 31865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane init(); 31965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 32065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 32165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane void updateAccounts() { 32265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane synchronized (mGuard) { 32365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ArrayObjectAdapter row = mRows.get(mAccountHeaderId); 32465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // Clear any account row cards that are not "Location" or "Security". 32565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String dontDelete[] = new String[2]; 32665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane dontDelete[0] = mContext.getString(R.string.system_location); 32765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane dontDelete[1] = mContext.getString(R.string.system_security); 32865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int i = 0; 32965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane while (i < row.size ()) { 33065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane MenuItem menuItem = (MenuItem) row.get(i); 33165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String title = menuItem.getTitle (); 33265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane boolean deleteItem = true; 33365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane for (int j = 0; j < dontDelete.length; ++j) { 33465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (title.equals(dontDelete[j])) { 33565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane deleteItem = false; 33665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane break; 33765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 33865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 33965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (deleteItem) { 34065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane row.removeItems(i, 1); 34165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 34265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ++i; 34365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 34465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 34565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // Add accounts to end of row. 34665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane addAccounts(row); 34765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 34865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 34965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 35065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane void updateAccessories() { 35165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane synchronized (mGuard) { 35265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane updateAccessories(R.id.accessories); 35365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 35465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 35565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 35665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void updateWifi() { 35765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mHandler.post(refreshWifiCardRunnable); 35865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 35965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 36065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane void bluetoothDeviceConnected(BluetoothDevice device) { 36165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane synchronized (mConnectedDevices) { 36265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mConnectedDevices.add(device); 36365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 36465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 36565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 36665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane void bluetoothDeviceDisconnected(BluetoothDevice device) { 36765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane synchronized (mConnectedDevices) { 36865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mConnectedDevices.remove(device); 36965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 37065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 37165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 37265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane boolean isDeviceConnected(BluetoothDevice device) { 37365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane synchronized (mConnectedDevices) { 37465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return mConnectedDevices.contains(device); 37565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 37665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 37765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 37865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private boolean isInputSettingNeeded() { 37965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane TvInputManager manager = (TvInputManager) mContext.getSystemService( 38065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Context.TV_INPUT_SERVICE); 38165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane for (TvInputInfo input : manager.getTvInputList()) { 38265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (input.isPassthroughInput()) { 38365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return true; 38465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 38565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 38665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return false; 38765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 38865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 38965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private void updateAccessories(int headerId) { 39065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ArrayObjectAdapter row = mRows.get(headerId); 39165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane row.clear(); 39265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 39365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane addAccessories(row); 39465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 39565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // Add new accessory activity icon 39665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ComponentName componentName = new ComponentName("com.android.tv.settings", 39765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane "com.android.tv.settings.accessories.AddAccessoryActivity"); 39865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Intent i = new Intent().setComponent(componentName); 39965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); 40065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane row.add(new MenuItem.Builder().id(mNextItemId++) 40165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .title(mContext.getString(R.string.accessories_add)) 40265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .imageResourceId(mContext, R.drawable.ic_settings_bluetooth) 40365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .intent(i).build()); 40465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 40565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 40665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private Intent getIntent(XmlResourceParser parser, AttributeSet attrs, int headerId) 40765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane throws org.xmlpull.v1.XmlPullParserException, IOException { 40865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Intent intent = null; 40965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (parser.next() == XmlPullParser.START_TAG && "intent".equals(parser.getName())) { 41065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane TypedArray sa = mContext.getResources() 41165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .obtainAttributes(attrs, com.android.internal.R.styleable.Intent); 41265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String targetClass = getStringFromTypedArray( 41365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane sa, com.android.internal.R.styleable.Intent_targetClass); 41465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String targetPackage = getStringFromTypedArray( 41565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane sa, com.android.internal.R.styleable.Intent_targetPackage); 41665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String action = getStringFromTypedArray( 41765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane sa, com.android.internal.R.styleable.Intent_action); 41865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (targetClass != null && targetPackage != null) { 41965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ComponentName componentName = new ComponentName(targetPackage, targetClass); 42065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane intent = new Intent(); 42165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane intent.setComponent(componentName); 42265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else if (action != null) { 42365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane intent = new Intent(action); 42465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 42565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 42665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane XmlUtils.skipCurrentTag(parser); 42765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 42865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); 42965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return intent; 43065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 43165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 43265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private String getStringFromTypedArray(TypedArray sa, int resourceId) { 43365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String value = null; 43465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane TypedValue tv = sa.peekValue(resourceId); 43565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (tv != null && tv.type == TypedValue.TYPE_STRING) { 43665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (tv.resourceId != 0) { 43765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane value = mContext.getString(tv.resourceId); 43865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 43965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane value = tv.string.toString(); 44065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 44165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 44265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return value; 44365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 44465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 44565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private MenuItem.TextGetter getDescriptionTextGetterFromKey(String key) { 44665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (WifiNetworksActivity.PREFERENCE_KEY.equals(key)) { 44765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return ConnectivityStatusTextGetter.createWifiStatusTextGetter(mContext); 44865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 44965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 45065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (ETHERNET_PREFERENCE_KEY.equals(key)) { 45165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return ConnectivityStatusTextGetter.createEthernetStatusTextGetter(mContext); 45265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 45365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 45465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return null; 45565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 45665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 45765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private MenuItem.UriGetter getIconUriGetterFromKey(String key) { 45865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (SoundActivity.getPreferenceKey().equals(key)) { 45965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return new SoundActivityImageUriGetter(mContext); 46065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 46165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 46265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (WifiNetworksActivity.PREFERENCE_KEY.equals(key)) { 46365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return ConnectivityStatusIconUriGetter.createWifiStatusIconUriGetter(mContext); 46465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 46565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 46665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return null; 46765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 46865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 46965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private void addAccounts(ArrayObjectAdapter row) { 47065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String[] accountTypes = mAuthenticatorHelper.getEnabledAccountTypes(); 47165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (accountTypes.length == 0) { 47265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // That's weird, let's try updating. 47365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mAuthenticatorHelper.onAccountsUpdated(mContext, null); 47465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane accountTypes = mAuthenticatorHelper.getEnabledAccountTypes(); 47565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 47665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 47765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int googleAccountCount = 0; 47865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 47965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane for (String accountType : accountTypes) { 48065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane CharSequence label = mAuthenticatorHelper.getLabelForType(mContext, accountType); 48165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (label == null) { 48265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane continue; 48365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 48465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 48565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Account[] accounts = AccountManager.get(mContext).getAccountsByType(accountType); 48665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (ACCOUNT_TYPE_GOOGLE.equals(accountType)) { 48765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane googleAccountCount = accounts.length; 48865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 48965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane for (final Account account : accounts) { 49065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Intent i = new Intent(mContext, AccountSettingsActivity.class) 49165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .putExtra(AccountSettingsActivity.EXTRA_ACCOUNT, account.name); 49265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); 49365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane row.add(new MenuItem.Builder().id(mNextItemId++).title(account.name) 49465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .imageUriGetter(new AccountImageUriGetter(mContext, account)) 49565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .intent(i) 49665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .build()); 49765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 49865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 49965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 5000898ab0f3d589be95488997e7ec1a8cc2a06b399Tim Kilbourn if (canAddAccount() && (mAllowMultipleAccounts || googleAccountCount == 0)) { 50165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ComponentName componentName = new ComponentName("com.android.tv.settings", 50265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane "com.android.tv.settings.accounts.AddAccountWithTypeActivity"); 50365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Intent i = new Intent().setComponent(componentName); 50465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); 50565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (accountTypes.length == 1) { 50665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane i.putExtra(AccountManager.KEY_ACCOUNT_TYPE, accountTypes[0]); 50765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 50865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane row.add(new MenuItem.Builder().id(mNextItemId++) 50965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .title(mContext.getString(R.string.add_account)) 51065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .imageResourceId(mContext, R.drawable.ic_settings_add) 51165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .intent(i).build()); 51265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 51365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 51465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 51565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private void addAccessories(ArrayObjectAdapter row) { 51665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (mBtAdapter != null) { 51765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Set<BluetoothDevice> bondedDevices = mBtAdapter.getBondedDevices(); 51865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (DEBUG) { 51965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Log.d(TAG, "List of Bonded BT Devices:"); 52065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 52165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 52265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane for (BluetoothDevice device : bondedDevices) { 52365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (DEBUG) { 52465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Log.d(TAG, " Device name: " + device.getName() + " , Class: " + 52565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane device.getBluetoothClass().getDeviceClass()); 52665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 52765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 52865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int resourceId = AccessoryUtils.getImageIdForDevice(device); 52965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Intent i = BluetoothAccessoryActivity.getIntent(mContext, device.getAddress(), 53065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane device.getName(), resourceId); 53165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); 53265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 53365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String desc = isDeviceConnected(device) ? mContext.getString( 53465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane R.string.accessory_connected) 53565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane : null; 53665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 53765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane row.add(new MenuItem.Builder().id(mNextItemId++).title(device.getName()) 53865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .description(desc).imageResourceId(mContext, resourceId) 53965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .intent(i).build()); 54065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 54165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 54265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 54365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane} 544