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(); 214dcc41237e48da2859b97f3ea5618558a4bea676fRoboErik int settingsXml = isRestricted() ? R.xml.restricted_main : R.xml.main; 215dcc41237e48da2859b97f3ea5618558a4bea676fRoboErik new XmlReader(mContext, settingsXml, "preference-headers", "header", 21665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane new HeaderXmlReaderListener()).read(); 21765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane updateAccessories(R.id.accessories); 21865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 21965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 22065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 22165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane void checkForDeveloperOptionUpdate() { 22265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane final boolean developerEnabled = mPreferenceUtils.isDeveloperEnabled(); 22365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (developerEnabled != mDeveloperEnabled) { 22465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mDeveloperEnabled = developerEnabled; 22565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane init(); 22665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 22765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 22865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 22965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private class HeaderXmlReaderListener implements XmlReaderListener { 23065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 23165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void handleRequestedNode(Context context, XmlResourceParser parser, 23265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane AttributeSet attrs) 23365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane throws XmlPullParserException, IOException { 23465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane TypedArray sa = mContext.getResources().obtainAttributes(attrs, 23565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane com.android.internal.R.styleable.PreferenceHeader); 23665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane final int headerId = sa.getResourceId( 23765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane com.android.internal.R.styleable.PreferenceHeader_id, 23865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane (int) PreferenceActivity.HEADER_ID_UNDEFINED); 23965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String title = getStringFromTypedArray(sa, 24065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane com.android.internal.R.styleable.PreferenceHeader_title); 24165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane sa.recycle(); 24265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane sa = context.getResources().obtainAttributes(attrs, R.styleable.CanvasSettings); 24365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int preferenceRes = sa.getResourceId(R.styleable.CanvasSettings_preference, 0); 24465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane sa.recycle(); 24565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mHeaderItems.add(new HeaderItem(headerId, title, null)); 24665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane final ArrayObjectAdapter currentRow = new ArrayObjectAdapter(); 24765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mRows.put(headerId, currentRow); 24865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (headerId != R.id.accessories) { 24965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane new XmlReader(context, preferenceRes, "PreferenceScreen", "Preference", 25065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane new PreferenceXmlReaderListener(headerId, currentRow)).read(); 25165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 25265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 25365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 25465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 2550898ab0f3d589be95488997e7ec1a8cc2a06b399Tim Kilbourn private boolean canAddAccount() { 256dcc41237e48da2859b97f3ea5618558a4bea676fRoboErik return !isRestricted(); 257dcc41237e48da2859b97f3ea5618558a4bea676fRoboErik } 258dcc41237e48da2859b97f3ea5618558a4bea676fRoboErik 259dcc41237e48da2859b97f3ea5618558a4bea676fRoboErik private boolean isRestricted() { 260dcc41237e48da2859b97f3ea5618558a4bea676fRoboErik return RestrictedProfileActivity.isRestrictedProfileInEffect(mContext); 2610898ab0f3d589be95488997e7ec1a8cc2a06b399Tim Kilbourn } 2620898ab0f3d589be95488997e7ec1a8cc2a06b399Tim Kilbourn 26365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private class PreferenceXmlReaderListener implements XmlReaderListener { 26465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 26565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private final int mHeaderId; 26665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private final ArrayObjectAdapter mRow; 26765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 26865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane PreferenceXmlReaderListener(int headerId, ArrayObjectAdapter row) { 26965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mHeaderId = headerId; 27065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mRow = row; 27165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 27265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 27365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 27465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void handleRequestedNode(Context context, XmlResourceParser parser, 27565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane AttributeSet attrs) throws XmlPullParserException, IOException { 27665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane TypedArray sa = context.getResources().obtainAttributes(attrs, 27765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane com.android.internal.R.styleable.Preference); 27865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 27965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String key = getStringFromTypedArray(sa, 28065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane com.android.internal.R.styleable.Preference_key); 28165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String title = getStringFromTypedArray(sa, 28265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane com.android.internal.R.styleable.Preference_title); 28365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int iconRes = sa.getResourceId(com.android.internal.R.styleable.Preference_icon, 28465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane R.drawable.settings_default_icon); 28565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane sa.recycle(); 28665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 28765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (PREF_KEY_ADD_ACCOUNT.equals(key)) { 28865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mAccountHeaderId = mHeaderId; 28965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane addAccounts(mRow); 29065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else if ((!key.equals(PREF_KEY_DEVELOPER) || mDeveloperEnabled) 29165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane && (!key.equals(PREF_KEY_INPUTS) || mInputSettingNeeded)) { 29265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane MenuItem.TextGetter descriptionGetter = getDescriptionTextGetterFromKey(key); 29365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane MenuItem.UriGetter uriGetter = getIconUriGetterFromKey(key); 29465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane MenuItem.Builder builder = new MenuItem.Builder().id(mNextItemId++).title(title) 29565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .descriptionGetter(descriptionGetter) 29665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .intent(getIntent(parser, attrs, mHeaderId)); 29765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if(uriGetter == null) { 29865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane builder.imageResourceId(mContext, iconRes); 29965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 30065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane builder.imageUriGetter(uriGetter); 30165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 30265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (key.equals(PREF_KEY_WIFI)) { 30365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mWifiItem = builder.build(); 30465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mRow.add(mWifiItem); 30565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mWifiRow = mRow; 30665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 30765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mRow.add(builder.build()); 30865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 30965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 31065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 31165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 31265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 31365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private void refreshWifiCard() { 31465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (mWifiItem != null) { 31565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int index = mWifiRow.indexOf(mWifiItem); 31665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (index >= 0) { 31765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mWifiRow.notifyArrayItemRangeChanged(index, 1); 31865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 31965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 32065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 32165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 32265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane void rebuildInfo() { 32365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane init(); 32465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 32565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 32665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane void updateAccounts() { 32765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane synchronized (mGuard) { 328dcc41237e48da2859b97f3ea5618558a4bea676fRoboErik if (isRestricted()) { 329dcc41237e48da2859b97f3ea5618558a4bea676fRoboErik // We don't display the accounts in restricted mode 330dcc41237e48da2859b97f3ea5618558a4bea676fRoboErik return; 331dcc41237e48da2859b97f3ea5618558a4bea676fRoboErik } 33265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ArrayObjectAdapter row = mRows.get(mAccountHeaderId); 33365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // Clear any account row cards that are not "Location" or "Security". 33465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String dontDelete[] = new String[2]; 33565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane dontDelete[0] = mContext.getString(R.string.system_location); 33665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane dontDelete[1] = mContext.getString(R.string.system_security); 33765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int i = 0; 33865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane while (i < row.size ()) { 33965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane MenuItem menuItem = (MenuItem) row.get(i); 34065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String title = menuItem.getTitle (); 34165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane boolean deleteItem = true; 34265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane for (int j = 0; j < dontDelete.length; ++j) { 34365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (title.equals(dontDelete[j])) { 34465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane deleteItem = false; 34565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane break; 34665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 34765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 34865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (deleteItem) { 34965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane row.removeItems(i, 1); 35065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 35165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ++i; 35265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 35365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 35465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // Add accounts to end of row. 35565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane addAccounts(row); 35665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 35765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 35865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 35965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane void updateAccessories() { 36065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane synchronized (mGuard) { 36165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane updateAccessories(R.id.accessories); 36265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 36365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 36465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 36565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void updateWifi() { 36665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mHandler.post(refreshWifiCardRunnable); 36765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 36865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 36965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane void bluetoothDeviceConnected(BluetoothDevice device) { 37065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane synchronized (mConnectedDevices) { 37165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mConnectedDevices.add(device); 37265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 37365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 37465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 37565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane void bluetoothDeviceDisconnected(BluetoothDevice device) { 37665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane synchronized (mConnectedDevices) { 37765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mConnectedDevices.remove(device); 37865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 37965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 38065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 38165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane boolean isDeviceConnected(BluetoothDevice device) { 38265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane synchronized (mConnectedDevices) { 38365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return mConnectedDevices.contains(device); 38465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 38565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 38665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 38765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private boolean isInputSettingNeeded() { 38865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane TvInputManager manager = (TvInputManager) mContext.getSystemService( 38965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Context.TV_INPUT_SERVICE); 39021d707d5d9ebe7b0b6594fa959f9eb2ff9df69a9Christopher Lane if (manager != null) { 39121d707d5d9ebe7b0b6594fa959f9eb2ff9df69a9Christopher Lane for (TvInputInfo input : manager.getTvInputList()) { 39221d707d5d9ebe7b0b6594fa959f9eb2ff9df69a9Christopher Lane if (input.isPassthroughInput()) { 39321d707d5d9ebe7b0b6594fa959f9eb2ff9df69a9Christopher Lane return true; 39421d707d5d9ebe7b0b6594fa959f9eb2ff9df69a9Christopher Lane } 39565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 39665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 39765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return false; 39865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 39965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 40065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private void updateAccessories(int headerId) { 40165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ArrayObjectAdapter row = mRows.get(headerId); 40265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane row.clear(); 40365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 40465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane addAccessories(row); 40565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 40665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // Add new accessory activity icon 40765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ComponentName componentName = new ComponentName("com.android.tv.settings", 40865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane "com.android.tv.settings.accessories.AddAccessoryActivity"); 40965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Intent i = new Intent().setComponent(componentName); 41065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); 41165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane row.add(new MenuItem.Builder().id(mNextItemId++) 41265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .title(mContext.getString(R.string.accessories_add)) 41365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .imageResourceId(mContext, R.drawable.ic_settings_bluetooth) 41465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .intent(i).build()); 41565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 41665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 41765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private Intent getIntent(XmlResourceParser parser, AttributeSet attrs, int headerId) 41865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane throws org.xmlpull.v1.XmlPullParserException, IOException { 41965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Intent intent = null; 42065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (parser.next() == XmlPullParser.START_TAG && "intent".equals(parser.getName())) { 42165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane TypedArray sa = mContext.getResources() 42265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .obtainAttributes(attrs, com.android.internal.R.styleable.Intent); 42365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String targetClass = getStringFromTypedArray( 42465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane sa, com.android.internal.R.styleable.Intent_targetClass); 42565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String targetPackage = getStringFromTypedArray( 42665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane sa, com.android.internal.R.styleable.Intent_targetPackage); 42765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String action = getStringFromTypedArray( 42865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane sa, com.android.internal.R.styleable.Intent_action); 42965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (targetClass != null && targetPackage != null) { 43065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ComponentName componentName = new ComponentName(targetPackage, targetClass); 43165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane intent = new Intent(); 43265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane intent.setComponent(componentName); 43365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else if (action != null) { 43465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane intent = new Intent(action); 43565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 43665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 43765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane XmlUtils.skipCurrentTag(parser); 43865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 43965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); 44065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return intent; 44165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 44265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 44365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private String getStringFromTypedArray(TypedArray sa, int resourceId) { 44465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String value = null; 44565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane TypedValue tv = sa.peekValue(resourceId); 44665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (tv != null && tv.type == TypedValue.TYPE_STRING) { 44765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (tv.resourceId != 0) { 44865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane value = mContext.getString(tv.resourceId); 44965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 45065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane value = tv.string.toString(); 45165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 45265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 45365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return value; 45465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 45565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 45665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private MenuItem.TextGetter getDescriptionTextGetterFromKey(String key) { 45765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (WifiNetworksActivity.PREFERENCE_KEY.equals(key)) { 45865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return ConnectivityStatusTextGetter.createWifiStatusTextGetter(mContext); 45965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 46065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 46165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (ETHERNET_PREFERENCE_KEY.equals(key)) { 46265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return ConnectivityStatusTextGetter.createEthernetStatusTextGetter(mContext); 46365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 46465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 46565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return null; 46665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 46765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 46865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private MenuItem.UriGetter getIconUriGetterFromKey(String key) { 46965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (SoundActivity.getPreferenceKey().equals(key)) { 47065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return new SoundActivityImageUriGetter(mContext); 47165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 47265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 47365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (WifiNetworksActivity.PREFERENCE_KEY.equals(key)) { 47465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return ConnectivityStatusIconUriGetter.createWifiStatusIconUriGetter(mContext); 47565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 47665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 47765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return null; 47865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 47965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 48065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private void addAccounts(ArrayObjectAdapter row) { 48165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String[] accountTypes = mAuthenticatorHelper.getEnabledAccountTypes(); 48265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (accountTypes.length == 0) { 48365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // That's weird, let's try updating. 48465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mAuthenticatorHelper.onAccountsUpdated(mContext, null); 48565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane accountTypes = mAuthenticatorHelper.getEnabledAccountTypes(); 48665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 48765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 48865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int googleAccountCount = 0; 48965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 49065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane for (String accountType : accountTypes) { 49165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane CharSequence label = mAuthenticatorHelper.getLabelForType(mContext, accountType); 49265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (label == null) { 49365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane continue; 49465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 49565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 49665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Account[] accounts = AccountManager.get(mContext).getAccountsByType(accountType); 49765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (ACCOUNT_TYPE_GOOGLE.equals(accountType)) { 49865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane googleAccountCount = accounts.length; 49965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 50065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane for (final Account account : accounts) { 50165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Intent i = new Intent(mContext, AccountSettingsActivity.class) 50265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .putExtra(AccountSettingsActivity.EXTRA_ACCOUNT, account.name); 50365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); 50465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane row.add(new MenuItem.Builder().id(mNextItemId++).title(account.name) 50565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .imageUriGetter(new AccountImageUriGetter(mContext, account)) 50665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .intent(i) 50765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .build()); 50865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 50965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 51065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 5110898ab0f3d589be95488997e7ec1a8cc2a06b399Tim Kilbourn if (canAddAccount() && (mAllowMultipleAccounts || googleAccountCount == 0)) { 51265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ComponentName componentName = new ComponentName("com.android.tv.settings", 51365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane "com.android.tv.settings.accounts.AddAccountWithTypeActivity"); 51465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Intent i = new Intent().setComponent(componentName); 51565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); 51665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (accountTypes.length == 1) { 51765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane i.putExtra(AccountManager.KEY_ACCOUNT_TYPE, accountTypes[0]); 51865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 51965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane row.add(new MenuItem.Builder().id(mNextItemId++) 52065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .title(mContext.getString(R.string.add_account)) 52165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .imageResourceId(mContext, R.drawable.ic_settings_add) 52265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .intent(i).build()); 52365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 52465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 52565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 52665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private void addAccessories(ArrayObjectAdapter row) { 52765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (mBtAdapter != null) { 52865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Set<BluetoothDevice> bondedDevices = mBtAdapter.getBondedDevices(); 52965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (DEBUG) { 53065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Log.d(TAG, "List of Bonded BT Devices:"); 53165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 53265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 53365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane for (BluetoothDevice device : bondedDevices) { 53465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (DEBUG) { 53565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Log.d(TAG, " Device name: " + device.getName() + " , Class: " + 53665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane device.getBluetoothClass().getDeviceClass()); 53765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 53865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 53965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int resourceId = AccessoryUtils.getImageIdForDevice(device); 54065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Intent i = BluetoothAccessoryActivity.getIntent(mContext, device.getAddress(), 54165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane device.getName(), resourceId); 54265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); 54365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 54465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String desc = isDeviceConnected(device) ? mContext.getString( 54565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane R.string.accessory_connected) 54665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane : null; 54765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 54865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane row.add(new MenuItem.Builder().id(mNextItemId++).title(device.getName()) 54965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .description(desc).imageResourceId(mContext, resourceId) 55065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .intent(i).build()); 55165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 55265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 55365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 55465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane} 555