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