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; 213ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Laneimport android.accounts.AuthenticatorDescription; 2265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.bluetooth.BluetoothAdapter; 2365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.bluetooth.BluetoothDevice; 2465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.content.ComponentName; 253ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Laneimport android.content.ContentResolver; 2665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.content.Context; 2765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.content.Intent; 283ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Laneimport android.content.Intent.ShortcutIconResource; 296185d3293f176c8c23e27c48eaff43dee745e1adChristopher Laneimport android.content.pm.ApplicationInfo; 303ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Laneimport android.content.pm.PackageManager; 313ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Laneimport android.content.pm.PackageManager.NameNotFoundException; 326185d3293f176c8c23e27c48eaff43dee745e1adChristopher Laneimport android.content.pm.ResolveInfo; 333ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Laneimport android.content.res.Resources; 343ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Laneimport android.content.res.Resources.NotFoundException; 3565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.content.res.TypedArray; 3665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.content.res.XmlResourceParser; 3765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.media.tv.TvInputInfo; 3865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.media.tv.TvInputManager; 393ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Laneimport android.net.Uri; 4065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.preference.PreferenceActivity; 4165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.support.v17.leanback.widget.ArrayObjectAdapter; 4265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.support.v17.leanback.widget.HeaderItem; 433ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Laneimport android.text.TextUtils; 4465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.util.AttributeSet; 4565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.util.Log; 4665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.util.TypedValue; 4765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.util.Xml; 4865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 4965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.internal.util.XmlUtils; 5065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.accessories.AccessoryUtils; 5165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.accessories.BluetoothAccessoryActivity; 52fee5c8e0161abcb376b09eb9fb379d32b84d46b0bulicimport com.android.tv.settings.accessories.BluetoothConnectionsManager; 5365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.accounts.AccountSettingsActivity; 543ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Laneimport com.android.tv.settings.accounts.AddAccountWithTypeActivity; 5565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.accounts.AuthenticatorHelper; 5665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.connectivity.ConnectivityStatusIconUriGetter; 5765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.connectivity.ConnectivityStatusTextGetter; 5865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.connectivity.WifiNetworksActivity; 5965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.device.sound.SoundActivity; 603150b12e5df05eec2c3ebb85360661f1d034c188Andrew Wilsonimport com.android.tv.settings.users.RestrictedProfileDialogFragment; 6165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.util.UriUtils; 6265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 6365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport org.xmlpull.v1.XmlPullParser; 6465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport org.xmlpull.v1.XmlPullParserException; 6565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 6665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport java.io.IOException; 673ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Laneimport java.util.ArrayList; 6865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport java.util.Set; 6965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 7065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane/** 7165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Gets the list of browse headers and browse items. 7265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 7365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lanepublic class BrowseInfo extends BrowseInfoBase { 7465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 751a51291a6bc498c63149f8c540bb7a57485c6802Tony Mantler private static final String TAG = "TvSettings.BrowseInfo"; 7665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final boolean DEBUG = false; 7765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 7865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String ACCOUNT_TYPE_GOOGLE = "com.google"; 7965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 8065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String ETHERNET_PREFERENCE_KEY = "ethernet"; 8165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 8265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane interface XmlReaderListener { 8365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane void handleRequestedNode(Context context, XmlResourceParser parser, AttributeSet attrs) 8465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane throws org.xmlpull.v1.XmlPullParserException, IOException; 8565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 8665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 8765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane static class SoundActivityImageUriGetter implements MenuItem.UriGetter { 8865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 8965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private final Context mContext; 9065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 9165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane SoundActivityImageUriGetter(Context context) { 9265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mContext = context; 9365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 9465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 9565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 9665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public String getUri() { 9765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return UriUtils.getAndroidResourceUri(mContext.getResources(), 9865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane SoundActivity.getIconResource(mContext.getContentResolver())); 9965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 10065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 10165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 10265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane static class XmlReader { 10365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 10465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private final Context mContext; 10565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private final int mXmlResource; 10665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private final String mRootNodeName; 10765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private final String mNodeNameRequested; 10865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private final XmlReaderListener mListener; 10965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 11065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane XmlReader(Context context, int xmlResource, String rootNodeName, String nodeNameRequested, 11165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane XmlReaderListener listener) { 11265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mContext = context; 11365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mXmlResource = xmlResource; 11465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mRootNodeName = rootNodeName; 11565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mNodeNameRequested = nodeNameRequested; 11665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mListener = listener; 11765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 11865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 11965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane void read() { 12065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane XmlResourceParser parser = null; 12165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane try { 12265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane parser = mContext.getResources().getXml(mXmlResource); 12365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane AttributeSet attrs = Xml.asAttributeSet(parser); 12465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 12565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int type; 12665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 12765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane && type != XmlPullParser.START_TAG) { 12865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // Parse next until start tag is found 12965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 13065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 13165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String nodeName = parser.getName(); 13265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (!mRootNodeName.equals(nodeName)) { 13365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane throw new RuntimeException("XML document must start with <" + mRootNodeName 13465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane + "> tag; found" + nodeName + " at " + parser.getPositionDescription()); 13565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 13665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 13765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane final int outerDepth = parser.getDepth(); 13865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 13965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 14065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 14165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane continue; 14265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 14365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 14465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane nodeName = parser.getName(); 14565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (mNodeNameRequested.equals(nodeName)) { 14665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mListener.handleRequestedNode(mContext, parser, attrs); 14765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 14865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane XmlUtils.skipCurrentTag(parser); 14965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 15065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 15165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 1521a51291a6bc498c63149f8c540bb7a57485c6802Tony Mantler } catch (XmlPullParserException|IOException e) { 15365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane throw new RuntimeException("Error parsing headers", e); 15465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } finally { 15565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (parser != null) 15665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane parser.close(); 15765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 15865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 15965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 16065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 16165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String PREF_KEY_ADD_ACCOUNT = "add_account"; 162cf1e7e11bb6b59a6f62a956e91b471e4542ae0feJaewan Kim private static final String PREF_KEY_WIFI = "network"; 16365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String PREF_KEY_DEVELOPER = "developer"; 16465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String PREF_KEY_INPUTS = "inputs"; 1656185d3293f176c8c23e27c48eaff43dee745e1adChristopher Lane private static final String PREF_KEY_HOME = "home"; 1661a51291a6bc498c63149f8c540bb7a57485c6802Tony Mantler private static final String PREF_KEY_CAST = "cast"; 1670bfaa3c0275e825c67af2f021e48e2d092fa76cbTony Mantler private static final String PREF_KEY_GOOGLESETTINGS = "googleSettings"; 16865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 16965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private final Context mContext; 17065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private final AuthenticatorHelper mAuthenticatorHelper; 17165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private int mNextItemId; 17265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private int mAccountHeaderId; 17365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private final BluetoothAdapter mBtAdapter; 17465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private final Object mGuard = new Object(); 17565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private MenuItem mWifiItem = null; 176324436e9129d6e8a85f416cb5aacce0a829f015aKris Giesing private MenuItem mSoundsItem = null; 1771d60d6f066d5a6108fdcf2c2505093d4fc8f0359William Bourke private MenuItem mDeveloperOptionItem = null; 17865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private ArrayObjectAdapter mWifiRow = null; 179324436e9129d6e8a85f416cb5aacce0a829f015aKris Giesing private ArrayObjectAdapter mSoundsRow = null; 1801d60d6f066d5a6108fdcf2c2505093d4fc8f0359William Bourke private ArrayObjectAdapter mDeveloperRow = null; 18165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 1826e995161147d9110d77ae1fe38b697e52891d3f2Tony Mantler private final PreferenceUtils mPreferenceUtils; 18365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private boolean mDeveloperEnabled; 1846e995161147d9110d77ae1fe38b697e52891d3f2Tony Mantler private final boolean mInputSettingNeeded; 18565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 18665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane BrowseInfo(Context context) { 18765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mContext = context; 18865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mAuthenticatorHelper = new AuthenticatorHelper(); 18965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mAuthenticatorHelper.updateAuthDescriptions(context); 19065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mAuthenticatorHelper.onAccountsUpdated(context, null); 19165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mBtAdapter = BluetoothAdapter.getDefaultAdapter(); 19265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mNextItemId = 0; 19365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mPreferenceUtils = new PreferenceUtils(context); 19465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mDeveloperEnabled = mPreferenceUtils.isDeveloperEnabled(); 19565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mInputSettingNeeded = isInputSettingNeeded(); 19665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 19765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 19865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane void init() { 19965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane synchronized (mGuard) { 20065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mHeaderItems.clear(); 20165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mRows.clear(); 202dcc41237e48da2859b97f3ea5618558a4bea676fRoboErik int settingsXml = isRestricted() ? R.xml.restricted_main : R.xml.main; 203dcc41237e48da2859b97f3ea5618558a4bea676fRoboErik new XmlReader(mContext, settingsXml, "preference-headers", "header", 20465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane new HeaderXmlReaderListener()).read(); 20565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane updateAccessories(R.id.accessories); 20665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 20765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 20865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 20965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane void checkForDeveloperOptionUpdate() { 21065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane final boolean developerEnabled = mPreferenceUtils.isDeveloperEnabled(); 21165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (developerEnabled != mDeveloperEnabled) { 21265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mDeveloperEnabled = developerEnabled; 2131d60d6f066d5a6108fdcf2c2505093d4fc8f0359William Bourke if (mDeveloperOptionItem != null) { 2141d60d6f066d5a6108fdcf2c2505093d4fc8f0359William Bourke mDeveloperRow.add (mDeveloperOptionItem); 2151d60d6f066d5a6108fdcf2c2505093d4fc8f0359William Bourke mDeveloperOptionItem = null; 2161d60d6f066d5a6108fdcf2c2505093d4fc8f0359William Bourke } 21765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 21865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 21965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 22065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private class HeaderXmlReaderListener implements XmlReaderListener { 22165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 22265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void handleRequestedNode(Context context, XmlResourceParser parser, 22365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane AttributeSet attrs) 22465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane throws XmlPullParserException, IOException { 22565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane TypedArray sa = mContext.getResources().obtainAttributes(attrs, 22665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane com.android.internal.R.styleable.PreferenceHeader); 22765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane final int headerId = sa.getResourceId( 22865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane com.android.internal.R.styleable.PreferenceHeader_id, 22965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane (int) PreferenceActivity.HEADER_ID_UNDEFINED); 23065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String title = getStringFromTypedArray(sa, 23165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane com.android.internal.R.styleable.PreferenceHeader_title); 23265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane sa.recycle(); 23365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane sa = context.getResources().obtainAttributes(attrs, R.styleable.CanvasSettings); 23465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int preferenceRes = sa.getResourceId(R.styleable.CanvasSettings_preference, 0); 23565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane sa.recycle(); 23637641441bc659fef6df673621dec77bc08b3be27Craig Stout mHeaderItems.add(new HeaderItem(headerId, title)); 23765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane final ArrayObjectAdapter currentRow = new ArrayObjectAdapter(); 23865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mRows.put(headerId, currentRow); 23965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (headerId != R.id.accessories) { 24065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane new XmlReader(context, preferenceRes, "PreferenceScreen", "Preference", 24165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane new PreferenceXmlReaderListener(headerId, currentRow)).read(); 24265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 24365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 24465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 24565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 246dcc41237e48da2859b97f3ea5618558a4bea676fRoboErik private boolean isRestricted() { 2473150b12e5df05eec2c3ebb85360661f1d034c188Andrew Wilson return RestrictedProfileDialogFragment.isRestrictedProfileInEffect(mContext); 2480898ab0f3d589be95488997e7ec1a8cc2a06b399Tim Kilbourn } 2490898ab0f3d589be95488997e7ec1a8cc2a06b399Tim Kilbourn 25065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private class PreferenceXmlReaderListener implements XmlReaderListener { 25165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 25265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private final int mHeaderId; 25365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private final ArrayObjectAdapter mRow; 25465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 25565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane PreferenceXmlReaderListener(int headerId, ArrayObjectAdapter row) { 25665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mHeaderId = headerId; 25765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mRow = row; 25865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 25965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 26065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 26165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void handleRequestedNode(Context context, XmlResourceParser parser, 26265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane AttributeSet attrs) throws XmlPullParserException, IOException { 26365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane TypedArray sa = context.getResources().obtainAttributes(attrs, 26465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane com.android.internal.R.styleable.Preference); 26565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 26665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String key = getStringFromTypedArray(sa, 26765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane com.android.internal.R.styleable.Preference_key); 26865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String title = getStringFromTypedArray(sa, 26965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane com.android.internal.R.styleable.Preference_title); 27065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int iconRes = sa.getResourceId(com.android.internal.R.styleable.Preference_icon, 27165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane R.drawable.settings_default_icon); 27265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane sa.recycle(); 27365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 27465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (PREF_KEY_ADD_ACCOUNT.equals(key)) { 27565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mAccountHeaderId = mHeaderId; 27665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane addAccounts(mRow); 2776185d3293f176c8c23e27c48eaff43dee745e1adChristopher Lane } else if (PREF_KEY_HOME.equals(key)) { 2786185d3293f176c8c23e27c48eaff43dee745e1adChristopher Lane // Only show home screen setting if there's a system app to handle the intent. 2791a51291a6bc498c63149f8c540bb7a57485c6802Tony Mantler Intent recIntent = getIntent(parser, attrs); 2800bfaa3c0275e825c67af2f021e48e2d092fa76cbTony Mantler if (systemIntentIsHandled(recIntent) != null) { 2816185d3293f176c8c23e27c48eaff43dee745e1adChristopher Lane mRow.add(new MenuItem.Builder() 2826185d3293f176c8c23e27c48eaff43dee745e1adChristopher Lane .id(mNextItemId++) 2836185d3293f176c8c23e27c48eaff43dee745e1adChristopher Lane .title(title) 2846185d3293f176c8c23e27c48eaff43dee745e1adChristopher Lane .imageResourceId(mContext, iconRes) 2856185d3293f176c8c23e27c48eaff43dee745e1adChristopher Lane .intent(recIntent) 2866185d3293f176c8c23e27c48eaff43dee745e1adChristopher Lane .build()); 2876185d3293f176c8c23e27c48eaff43dee745e1adChristopher Lane } 2881a51291a6bc498c63149f8c540bb7a57485c6802Tony Mantler } else if (PREF_KEY_CAST.equals(key)) { 2891a51291a6bc498c63149f8c540bb7a57485c6802Tony Mantler Intent i = getIntent(parser, attrs); 2900bfaa3c0275e825c67af2f021e48e2d092fa76cbTony Mantler if (systemIntentIsHandled(i) != null) { 2911a51291a6bc498c63149f8c540bb7a57485c6802Tony Mantler mRow.add(new MenuItem.Builder() 2921a51291a6bc498c63149f8c540bb7a57485c6802Tony Mantler .id(mNextItemId++) 2931a51291a6bc498c63149f8c540bb7a57485c6802Tony Mantler .title(title) 2941a51291a6bc498c63149f8c540bb7a57485c6802Tony Mantler .imageResourceId(mContext, iconRes) 2951a51291a6bc498c63149f8c540bb7a57485c6802Tony Mantler .intent(i) 2961a51291a6bc498c63149f8c540bb7a57485c6802Tony Mantler .build()); 2971a51291a6bc498c63149f8c540bb7a57485c6802Tony Mantler } 2980bfaa3c0275e825c67af2f021e48e2d092fa76cbTony Mantler } else if (PREF_KEY_GOOGLESETTINGS.equals(key)) { 2990bfaa3c0275e825c67af2f021e48e2d092fa76cbTony Mantler Intent i = getIntent(parser, attrs); 3000bfaa3c0275e825c67af2f021e48e2d092fa76cbTony Mantler final ResolveInfo info = systemIntentIsHandled(i); 3010bfaa3c0275e825c67af2f021e48e2d092fa76cbTony Mantler if (info != null) { 3020bfaa3c0275e825c67af2f021e48e2d092fa76cbTony Mantler try { 3030bfaa3c0275e825c67af2f021e48e2d092fa76cbTony Mantler final PackageManager packageManager = context.getPackageManager(); 3040bfaa3c0275e825c67af2f021e48e2d092fa76cbTony Mantler final String packageName = info.resolvePackageName != null ? 3050bfaa3c0275e825c67af2f021e48e2d092fa76cbTony Mantler info.resolvePackageName : info.activityInfo.packageName; 3060bfaa3c0275e825c67af2f021e48e2d092fa76cbTony Mantler final Resources targetResources = 3070bfaa3c0275e825c67af2f021e48e2d092fa76cbTony Mantler packageManager.getResourcesForApplication(packageName); 3080bfaa3c0275e825c67af2f021e48e2d092fa76cbTony Mantler final String targetTitle = info.loadLabel(packageManager).toString(); 3090bfaa3c0275e825c67af2f021e48e2d092fa76cbTony Mantler mRow.add(new MenuItem.Builder() 3100bfaa3c0275e825c67af2f021e48e2d092fa76cbTony Mantler .id(mNextItemId++) 3110bfaa3c0275e825c67af2f021e48e2d092fa76cbTony Mantler .title(targetTitle) 3120bfaa3c0275e825c67af2f021e48e2d092fa76cbTony Mantler .imageResourceId(targetResources, info.iconResourceId) 3130bfaa3c0275e825c67af2f021e48e2d092fa76cbTony Mantler .intent(i) 3140bfaa3c0275e825c67af2f021e48e2d092fa76cbTony Mantler .build()); 3150bfaa3c0275e825c67af2f021e48e2d092fa76cbTony Mantler } catch (Exception e) { 3160bfaa3c0275e825c67af2f021e48e2d092fa76cbTony Mantler Log.e(TAG, "Error adding google settings", e); 3170bfaa3c0275e825c67af2f021e48e2d092fa76cbTony Mantler } 3180bfaa3c0275e825c67af2f021e48e2d092fa76cbTony Mantler } 3191a51291a6bc498c63149f8c540bb7a57485c6802Tony Mantler } else if (!PREF_KEY_INPUTS.equals(key) || mInputSettingNeeded) { 32065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane MenuItem.TextGetter descriptionGetter = getDescriptionTextGetterFromKey(key); 32165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane MenuItem.UriGetter uriGetter = getIconUriGetterFromKey(key); 32265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane MenuItem.Builder builder = new MenuItem.Builder().id(mNextItemId++).title(title) 32365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .descriptionGetter(descriptionGetter) 3241a51291a6bc498c63149f8c540bb7a57485c6802Tony Mantler .intent(getIntent(parser, attrs)); 32565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if(uriGetter == null) { 32665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane builder.imageResourceId(mContext, iconRes); 32765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 32865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane builder.imageUriGetter(uriGetter); 32965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 3301d60d6f066d5a6108fdcf2c2505093d4fc8f0359William Bourke final MenuItem item = builder.build(); 33165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (key.equals(PREF_KEY_WIFI)) { 332324436e9129d6e8a85f416cb5aacce0a829f015aKris Giesing mWifiRow = mRow; 3331d60d6f066d5a6108fdcf2c2505093d4fc8f0359William Bourke mWifiItem = item; 33465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mRow.add(mWifiItem); 335324436e9129d6e8a85f416cb5aacce0a829f015aKris Giesing } else if (key.equals(SoundActivity.getPreferenceKey())) { 336324436e9129d6e8a85f416cb5aacce0a829f015aKris Giesing mSoundsRow = mRow; 337324436e9129d6e8a85f416cb5aacce0a829f015aKris Giesing mSoundsItem = item; 338324436e9129d6e8a85f416cb5aacce0a829f015aKris Giesing mRow.add(mSoundsItem); 339324436e9129d6e8a85f416cb5aacce0a829f015aKris Giesing } else if (key.equals(PREF_KEY_DEVELOPER) && !mDeveloperEnabled) { 3401d60d6f066d5a6108fdcf2c2505093d4fc8f0359William Bourke mDeveloperRow = mRow; 3411d60d6f066d5a6108fdcf2c2505093d4fc8f0359William Bourke mDeveloperOptionItem = item; 342324436e9129d6e8a85f416cb5aacce0a829f015aKris Giesing } else { 343324436e9129d6e8a85f416cb5aacce0a829f015aKris Giesing mRow.add(item); 34465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 34565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 34665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 34765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 34865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 34965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane void rebuildInfo() { 35065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane init(); 35165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 35265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 35365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane void updateAccounts() { 35465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane synchronized (mGuard) { 355dcc41237e48da2859b97f3ea5618558a4bea676fRoboErik if (isRestricted()) { 356dcc41237e48da2859b97f3ea5618558a4bea676fRoboErik // We don't display the accounts in restricted mode 357dcc41237e48da2859b97f3ea5618558a4bea676fRoboErik return; 358dcc41237e48da2859b97f3ea5618558a4bea676fRoboErik } 35965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ArrayObjectAdapter row = mRows.get(mAccountHeaderId); 36065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // Clear any account row cards that are not "Location" or "Security". 36165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String dontDelete[] = new String[2]; 36265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane dontDelete[0] = mContext.getString(R.string.system_location); 36365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane dontDelete[1] = mContext.getString(R.string.system_security); 36465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int i = 0; 36565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane while (i < row.size ()) { 36665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane MenuItem menuItem = (MenuItem) row.get(i); 36765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String title = menuItem.getTitle (); 36865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane boolean deleteItem = true; 36965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane for (int j = 0; j < dontDelete.length; ++j) { 37065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (title.equals(dontDelete[j])) { 37165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane deleteItem = false; 37265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane break; 37365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 37465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 37565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (deleteItem) { 37665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane row.removeItems(i, 1); 37765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 37865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ++i; 37965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 38065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 38165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // Add accounts to end of row. 38265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane addAccounts(row); 38365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 38465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 38565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 38665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane void updateAccessories() { 38765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane synchronized (mGuard) { 38865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane updateAccessories(R.id.accessories); 38965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 39065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 39165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 392cf1e7e11bb6b59a6f62a956e91b471e4542ae0feJaewan Kim public void updateWifi(final boolean isEthernetAvailable) { 393cf1e7e11bb6b59a6f62a956e91b471e4542ae0feJaewan Kim if (mWifiItem != null) { 394cf1e7e11bb6b59a6f62a956e91b471e4542ae0feJaewan Kim int index = mWifiRow.indexOf(mWifiItem); 395cf1e7e11bb6b59a6f62a956e91b471e4542ae0feJaewan Kim if (index >= 0) { 396cf1e7e11bb6b59a6f62a956e91b471e4542ae0feJaewan Kim mWifiItem = new MenuItem.Builder().from(mWifiItem) 397cf1e7e11bb6b59a6f62a956e91b471e4542ae0feJaewan Kim .title(mContext.getString(isEthernetAvailable 398cf1e7e11bb6b59a6f62a956e91b471e4542ae0feJaewan Kim ? R.string.connectivity_network : R.string.connectivity_wifi)) 399cf1e7e11bb6b59a6f62a956e91b471e4542ae0feJaewan Kim .build(); 400cf1e7e11bb6b59a6f62a956e91b471e4542ae0feJaewan Kim mWifiRow.replace(index, mWifiItem); 401cf1e7e11bb6b59a6f62a956e91b471e4542ae0feJaewan Kim } 402cf1e7e11bb6b59a6f62a956e91b471e4542ae0feJaewan Kim } 40365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 40465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 405324436e9129d6e8a85f416cb5aacce0a829f015aKris Giesing public void updateSounds() { 406324436e9129d6e8a85f416cb5aacce0a829f015aKris Giesing if (mSoundsItem != null) { 407324436e9129d6e8a85f416cb5aacce0a829f015aKris Giesing int index = mSoundsRow.indexOf(mSoundsItem); 408324436e9129d6e8a85f416cb5aacce0a829f015aKris Giesing if (index >= 0) { 409324436e9129d6e8a85f416cb5aacce0a829f015aKris Giesing mSoundsRow.notifyArrayItemRangeChanged(index, 1); 410324436e9129d6e8a85f416cb5aacce0a829f015aKris Giesing } 411324436e9129d6e8a85f416cb5aacce0a829f015aKris Giesing } 412324436e9129d6e8a85f416cb5aacce0a829f015aKris Giesing } 413324436e9129d6e8a85f416cb5aacce0a829f015aKris Giesing 41465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private boolean isInputSettingNeeded() { 41565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane TvInputManager manager = (TvInputManager) mContext.getSystemService( 41665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Context.TV_INPUT_SERVICE); 41721d707d5d9ebe7b0b6594fa959f9eb2ff9df69a9Christopher Lane if (manager != null) { 41821d707d5d9ebe7b0b6594fa959f9eb2ff9df69a9Christopher Lane for (TvInputInfo input : manager.getTvInputList()) { 41921d707d5d9ebe7b0b6594fa959f9eb2ff9df69a9Christopher Lane if (input.isPassthroughInput()) { 42021d707d5d9ebe7b0b6594fa959f9eb2ff9df69a9Christopher Lane return true; 42121d707d5d9ebe7b0b6594fa959f9eb2ff9df69a9Christopher Lane } 42265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 42365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 42465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return false; 42565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 42665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 42765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private void updateAccessories(int headerId) { 42865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ArrayObjectAdapter row = mRows.get(headerId); 42965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane row.clear(); 43065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 43165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane addAccessories(row); 43265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 43365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // Add new accessory activity icon 43465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ComponentName componentName = new ComponentName("com.android.tv.settings", 43565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane "com.android.tv.settings.accessories.AddAccessoryActivity"); 43665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Intent i = new Intent().setComponent(componentName); 43765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane row.add(new MenuItem.Builder().id(mNextItemId++) 43865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .title(mContext.getString(R.string.accessories_add)) 43965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .imageResourceId(mContext, R.drawable.ic_settings_bluetooth) 44065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .intent(i).build()); 44165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 44265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 4431a51291a6bc498c63149f8c540bb7a57485c6802Tony Mantler private Intent getIntent(XmlResourceParser parser, AttributeSet attrs) 44465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane throws org.xmlpull.v1.XmlPullParserException, IOException { 44565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Intent intent = null; 44665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (parser.next() == XmlPullParser.START_TAG && "intent".equals(parser.getName())) { 44765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane TypedArray sa = mContext.getResources() 44865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .obtainAttributes(attrs, com.android.internal.R.styleable.Intent); 44965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String targetClass = getStringFromTypedArray( 45065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane sa, com.android.internal.R.styleable.Intent_targetClass); 45165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String targetPackage = getStringFromTypedArray( 45265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane sa, com.android.internal.R.styleable.Intent_targetPackage); 45365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String action = getStringFromTypedArray( 45465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane sa, com.android.internal.R.styleable.Intent_action); 45565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (targetClass != null && targetPackage != null) { 45665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ComponentName componentName = new ComponentName(targetPackage, targetClass); 45765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane intent = new Intent(); 45865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane intent.setComponent(componentName); 45965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else if (action != null) { 46065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane intent = new Intent(action); 4610bfaa3c0275e825c67af2f021e48e2d092fa76cbTony Mantler if (targetPackage != null) { 4620bfaa3c0275e825c67af2f021e48e2d092fa76cbTony Mantler intent.setPackage(targetPackage); 4630bfaa3c0275e825c67af2f021e48e2d092fa76cbTony Mantler } 46465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 46565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 46665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane XmlUtils.skipCurrentTag(parser); 46765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 46865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return intent; 46965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 47065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 47165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private String getStringFromTypedArray(TypedArray sa, int resourceId) { 47265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String value = null; 47365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane TypedValue tv = sa.peekValue(resourceId); 47465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (tv != null && tv.type == TypedValue.TYPE_STRING) { 47565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (tv.resourceId != 0) { 47665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane value = mContext.getString(tv.resourceId); 47765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 47865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane value = tv.string.toString(); 47965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 48065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 48165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return value; 48265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 48365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 48465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private MenuItem.TextGetter getDescriptionTextGetterFromKey(String key) { 48565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (WifiNetworksActivity.PREFERENCE_KEY.equals(key)) { 48665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return ConnectivityStatusTextGetter.createWifiStatusTextGetter(mContext); 48765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 48865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 48965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (ETHERNET_PREFERENCE_KEY.equals(key)) { 49065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return ConnectivityStatusTextGetter.createEthernetStatusTextGetter(mContext); 49165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 49265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 49365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return null; 49465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 49565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 49665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private MenuItem.UriGetter getIconUriGetterFromKey(String key) { 49765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (SoundActivity.getPreferenceKey().equals(key)) { 49865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return new SoundActivityImageUriGetter(mContext); 49965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 50065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 50165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (WifiNetworksActivity.PREFERENCE_KEY.equals(key)) { 50265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return ConnectivityStatusIconUriGetter.createWifiStatusIconUriGetter(mContext); 50365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 50465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 50565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return null; 50665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 50765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 50865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private void addAccounts(ArrayObjectAdapter row) { 5093ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane AccountManager am = AccountManager.get(mContext); 5103ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane AuthenticatorDescription[] authTypes = am.getAuthenticatorTypes(); 5113ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane ArrayList<String> allowableAccountTypes = new ArrayList<>(authTypes.length); 5123ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane PackageManager pm = mContext.getPackageManager(); 51365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 51465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int googleAccountCount = 0; 51565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 5163ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane for (AuthenticatorDescription authDesc : authTypes) { 5171a51291a6bc498c63149f8c540bb7a57485c6802Tony Mantler final Resources resources; 5183ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane try { 5193ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane resources = pm.getResourcesForApplication(authDesc.packageName); 5203ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane } catch (NameNotFoundException e) { 5213ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane Log.e(TAG, "Authenticator description with bad package name", e); 52265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane continue; 52365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 52465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 5253ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane // Main title text comes from the authenticator description (e.g. "Google"). 5263ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane String authTitle = null; 5273ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane try { 5283ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane authTitle = resources.getString(authDesc.labelId); 5293ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane if (TextUtils.isEmpty(authTitle)) { 5303ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane authTitle = null; // Handled later when we add the row. 5313ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane } 5323ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane } catch (NotFoundException e) { 53309da53e7ba6177cfa808f1a87b3c53ff4d92c5b9Christopher Lane if (DEBUG) Log.e(TAG, "Authenticator description with bad label id", e); 53409da53e7ba6177cfa808f1a87b3c53ff4d92c5b9Christopher Lane } 53509da53e7ba6177cfa808f1a87b3c53ff4d92c5b9Christopher Lane 53609da53e7ba6177cfa808f1a87b3c53ff4d92c5b9Christopher Lane // There exist some authenticators which aren't intended to be user-facing. 53709da53e7ba6177cfa808f1a87b3c53ff4d92c5b9Christopher Lane // If the authenticator doesn't have a title or an icon, don't present it to 53809da53e7ba6177cfa808f1a87b3c53ff4d92c5b9Christopher Lane // the user as an option. 53909da53e7ba6177cfa808f1a87b3c53ff4d92c5b9Christopher Lane if (authTitle != null || authDesc.iconId != 0) { 54009da53e7ba6177cfa808f1a87b3c53ff4d92c5b9Christopher Lane allowableAccountTypes.add(authDesc.type); 5413ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane } 5423ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane 5433ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane Account[] accounts = am.getAccountsByType(authDesc.type); 54409da53e7ba6177cfa808f1a87b3c53ff4d92c5b9Christopher Lane if (accounts == null || accounts.length == 0) { 54509da53e7ba6177cfa808f1a87b3c53ff4d92c5b9Christopher Lane continue; // No point in continuing; there aren't any accounts to show. 54609da53e7ba6177cfa808f1a87b3c53ff4d92c5b9Christopher Lane } 5473ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane 5483ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane // Icon URI to be displayed for each account is based on the type of authenticator. 5493ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane String imageUri = null; 5503ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane if (ACCOUNT_TYPE_GOOGLE.equals(authDesc.type)) { 55165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane googleAccountCount = accounts.length; 5523ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane imageUri = googleAccountIconUri(mContext); 5533ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane } else { 55409da53e7ba6177cfa808f1a87b3c53ff4d92c5b9Christopher Lane try { 55509da53e7ba6177cfa808f1a87b3c53ff4d92c5b9Christopher Lane imageUri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + 55609da53e7ba6177cfa808f1a87b3c53ff4d92c5b9Christopher Lane authDesc.packageName + '/' + 55709da53e7ba6177cfa808f1a87b3c53ff4d92c5b9Christopher Lane resources.getResourceTypeName(authDesc.iconId) + '/' + 55809da53e7ba6177cfa808f1a87b3c53ff4d92c5b9Christopher Lane resources.getResourceEntryName(authDesc.iconId)) 55909da53e7ba6177cfa808f1a87b3c53ff4d92c5b9Christopher Lane .toString(); 56009da53e7ba6177cfa808f1a87b3c53ff4d92c5b9Christopher Lane } catch (NotFoundException e) { 56109da53e7ba6177cfa808f1a87b3c53ff4d92c5b9Christopher Lane if (DEBUG) Log.e(TAG, "Authenticator has bad resource ids", e); 56209da53e7ba6177cfa808f1a87b3c53ff4d92c5b9Christopher Lane } 56365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 5643ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane 5653ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane // Display an entry for each installed account we have. 56665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane for (final Account account : accounts) { 56765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Intent i = new Intent(mContext, AccountSettingsActivity.class) 56865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .putExtra(AccountSettingsActivity.EXTRA_ACCOUNT, account.name); 5693ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane row.add(new MenuItem.Builder().id(mNextItemId++) 5703ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane .title(authTitle != null ? authTitle : account.name) 5713ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane .imageUri(imageUri) 5723ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane .description(authTitle != null ? account.name : null) 57365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .intent(i) 57465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .build()); 57565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 57665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 57765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 5783ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane // Never allow restricted profile to add accounts. 5793ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane if (!isRestricted()) { 5803ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane 5813ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane // If there's already a Google account installed, disallow installing a second one. 5823ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane if (googleAccountCount > 0) { 5833ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane allowableAccountTypes.remove(ACCOUNT_TYPE_GOOGLE); 5843ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane } 5853ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane 5863ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane // If there are available account types, add the "add account" button. 5873ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane if (!allowableAccountTypes.isEmpty()) { 5883ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane Intent i = new Intent().setComponent(new ComponentName("com.android.tv.settings", 5893ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane "com.android.tv.settings.accounts.AddAccountWithTypeActivity")); 5903ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane i.putExtra(AddAccountWithTypeActivity.EXTRA_ALLOWABLE_ACCOUNT_TYPES_STRING_ARRAY, 5913ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane allowableAccountTypes.toArray(new String[allowableAccountTypes.size()])); 5923ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane 5933ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane row.add(new MenuItem.Builder().id(mNextItemId++) 5943ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane .title(mContext.getString(R.string.add_account)) 5953ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane .imageResourceId(mContext, R.drawable.ic_settings_add) 5963ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane .intent(i).build()); 59765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 59865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 59965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 60065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 60165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private void addAccessories(ArrayObjectAdapter row) { 60265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (mBtAdapter != null) { 60365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Set<BluetoothDevice> bondedDevices = mBtAdapter.getBondedDevices(); 60465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (DEBUG) { 60565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Log.d(TAG, "List of Bonded BT Devices:"); 60665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 60765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 608fee5c8e0161abcb376b09eb9fb379d32b84d46b0bulic Set<String> connectedBluetoothAddresses = 609fee5c8e0161abcb376b09eb9fb379d32b84d46b0bulic BluetoothConnectionsManager.getConnectedSet(mContext); 610fee5c8e0161abcb376b09eb9fb379d32b84d46b0bulic 61165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane for (BluetoothDevice device : bondedDevices) { 61265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (DEBUG) { 61365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Log.d(TAG, " Device name: " + device.getName() + " , Class: " + 61465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane device.getBluetoothClass().getDeviceClass()); 61565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 61665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 61765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int resourceId = AccessoryUtils.getImageIdForDevice(device); 61865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Intent i = BluetoothAccessoryActivity.getIntent(mContext, device.getAddress(), 61965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane device.getName(), resourceId); 62065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 621fee5c8e0161abcb376b09eb9fb379d32b84d46b0bulic String desc = connectedBluetoothAddresses.contains(device.getAddress()) 622fee5c8e0161abcb376b09eb9fb379d32b84d46b0bulic ? mContext.getString(R.string.accessory_connected) 62365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane : null; 62465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 62565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane row.add(new MenuItem.Builder().id(mNextItemId++).title(device.getName()) 62665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .description(desc).imageResourceId(mContext, resourceId) 62765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .intent(i).build()); 62865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 62965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 63065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 6313ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane 6323ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane private static String googleAccountIconUri(Context context) { 6333ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane ShortcutIconResource iconResource = new ShortcutIconResource(); 6343ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane iconResource.packageName = context.getPackageName(); 6353ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane iconResource.resourceName = context.getResources().getResourceName( 6363ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane R.drawable.ic_settings_google_account); 6373ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane return UriUtils.getShortcutIconResourceUri(iconResource).toString(); 6383ef05b7da4ecd6565b6b00797af9fb4f45eaa926Christopher Lane } 6396185d3293f176c8c23e27c48eaff43dee745e1adChristopher Lane 6400bfaa3c0275e825c67af2f021e48e2d092fa76cbTony Mantler private ResolveInfo systemIntentIsHandled(Intent intent) { 6416185d3293f176c8c23e27c48eaff43dee745e1adChristopher Lane if (mContext == null || intent == null) { 6420bfaa3c0275e825c67af2f021e48e2d092fa76cbTony Mantler return null; 6436185d3293f176c8c23e27c48eaff43dee745e1adChristopher Lane } 6446185d3293f176c8c23e27c48eaff43dee745e1adChristopher Lane 6456185d3293f176c8c23e27c48eaff43dee745e1adChristopher Lane PackageManager pm = mContext.getPackageManager(); 6466185d3293f176c8c23e27c48eaff43dee745e1adChristopher Lane if (pm == null) { 6470bfaa3c0275e825c67af2f021e48e2d092fa76cbTony Mantler return null; 6486185d3293f176c8c23e27c48eaff43dee745e1adChristopher Lane } 6496185d3293f176c8c23e27c48eaff43dee745e1adChristopher Lane 6506185d3293f176c8c23e27c48eaff43dee745e1adChristopher Lane for (ResolveInfo info : pm.queryIntentActivities(intent, 0)) { 6516185d3293f176c8c23e27c48eaff43dee745e1adChristopher Lane if (info.activityInfo != null && info.activityInfo.enabled && 6526185d3293f176c8c23e27c48eaff43dee745e1adChristopher Lane (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 6536185d3293f176c8c23e27c48eaff43dee745e1adChristopher Lane ApplicationInfo.FLAG_SYSTEM) { 6540bfaa3c0275e825c67af2f021e48e2d092fa76cbTony Mantler return info; 6556185d3293f176c8c23e27c48eaff43dee745e1adChristopher Lane } 6566185d3293f176c8c23e27c48eaff43dee745e1adChristopher Lane } 6570bfaa3c0275e825c67af2f021e48e2d092fa76cbTony Mantler return null; 6586185d3293f176c8c23e27c48eaff43dee745e1adChristopher Lane } 65965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane} 660