diff options
-rw-r--r-- | Settings/res/drawable-hdpi/ic_settings_google_account.png | bin | 0 -> 6162 bytes | |||
-rw-r--r-- | Settings/res/drawable-mdpi/ic_settings_google_account.png | bin | 0 -> 3899 bytes | |||
-rw-r--r-- | Settings/res/drawable-xhdpi/ic_settings_google_account.png | bin | 0 -> 8459 bytes | |||
-rw-r--r-- | Settings/res/drawable-xxhdpi/ic_settings_google_account.png | bin | 0 -> 7900 bytes | |||
-rw-r--r-- | Settings/res/values/config.xml | 1 | ||||
-rw-r--r-- | Settings/src/com/android/tv/settings/BrowseInfo.java | 112 | ||||
-rw-r--r-- | Settings/src/com/android/tv/settings/accounts/AddAccountWithTypeActivity.java | 70 |
7 files changed, 103 insertions, 80 deletions
diff --git a/Settings/res/drawable-hdpi/ic_settings_google_account.png b/Settings/res/drawable-hdpi/ic_settings_google_account.png Binary files differnew file mode 100644 index 000000000..9daeec306 --- /dev/null +++ b/Settings/res/drawable-hdpi/ic_settings_google_account.png diff --git a/Settings/res/drawable-mdpi/ic_settings_google_account.png b/Settings/res/drawable-mdpi/ic_settings_google_account.png Binary files differnew file mode 100644 index 000000000..0d8af1bb3 --- /dev/null +++ b/Settings/res/drawable-mdpi/ic_settings_google_account.png diff --git a/Settings/res/drawable-xhdpi/ic_settings_google_account.png b/Settings/res/drawable-xhdpi/ic_settings_google_account.png Binary files differnew file mode 100644 index 000000000..2e6c304ea --- /dev/null +++ b/Settings/res/drawable-xhdpi/ic_settings_google_account.png diff --git a/Settings/res/drawable-xxhdpi/ic_settings_google_account.png b/Settings/res/drawable-xxhdpi/ic_settings_google_account.png Binary files differnew file mode 100644 index 000000000..ea6d1485a --- /dev/null +++ b/Settings/res/drawable-xxhdpi/ic_settings_google_account.png diff --git a/Settings/res/values/config.xml b/Settings/res/values/config.xml index 565cde3ce..95a5e4b31 100644 --- a/Settings/res/values/config.xml +++ b/Settings/res/values/config.xml @@ -14,7 +14,6 @@ limitations under the License. --> <resources> - <bool name="multiple_accounts_enabled">false</bool> <integer name="settings_fade_in_duration">350</integer> <integer name="settings_fade_out_duration">350</integer> <integer name="action_title_max_lines">3</integer> diff --git a/Settings/src/com/android/tv/settings/BrowseInfo.java b/Settings/src/com/android/tv/settings/BrowseInfo.java index 47e703af6..8f38f821b 100644 --- a/Settings/src/com/android/tv/settings/BrowseInfo.java +++ b/Settings/src/com/android/tv/settings/BrowseInfo.java @@ -18,15 +18,23 @@ package com.android.tv.settings; import android.accounts.Account; import android.accounts.AccountManager; +import android.accounts.AuthenticatorDescription; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.content.ComponentName; +import android.content.ContentResolver; import android.content.Context; import android.content.Intent; +import android.content.Intent.ShortcutIconResource; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; +import android.content.res.Resources; +import android.content.res.Resources.NotFoundException; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.media.tv.TvInputInfo; import android.media.tv.TvInputManager; +import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.preference.PreferenceActivity; @@ -34,6 +42,7 @@ import android.support.v17.leanback.widget.ArrayObjectAdapter; import android.support.v17.leanback.widget.HeaderItem; import android.support.v17.leanback.widget.ObjectAdapter; import android.support.v17.leanback.widget.ListRow; +import android.text.TextUtils; import android.util.AttributeSet; import android.util.Log; import android.util.TypedValue; @@ -45,6 +54,7 @@ import com.android.tv.settings.accessories.BluetoothAccessoryActivity; import com.android.tv.settings.accessories.BluetoothConnectionsManager; import com.android.tv.settings.accounts.AccountImageUriGetter; import com.android.tv.settings.accounts.AccountSettingsActivity; +import com.android.tv.settings.accounts.AddAccountWithTypeActivity; import com.android.tv.settings.accounts.AuthenticatorHelper; import com.android.tv.settings.connectivity.ConnectivityStatusIconUriGetter; import com.android.tv.settings.connectivity.ConnectivityStatusTextGetter; @@ -52,11 +62,13 @@ import com.android.tv.settings.connectivity.WifiNetworksActivity; import com.android.tv.settings.device.sound.SoundActivity; import com.android.tv.settings.users.RestrictedProfileActivity; import com.android.tv.settings.util.UriUtils; +import com.android.tv.settings.util.AccountImageHelper; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; +import java.util.ArrayList; import java.util.Set; /** @@ -170,7 +182,6 @@ public class BrowseInfo extends BrowseInfoBase { private int mAccountHeaderId; private final BluetoothAdapter mBtAdapter; private final Object mGuard = new Object(); - private final boolean mAllowMultipleAccounts; private MenuItem mWifiItem = null; private ArrayObjectAdapter mWifiRow = null; private final Handler mHandler = new Handler(); @@ -186,8 +197,6 @@ public class BrowseInfo extends BrowseInfoBase { mAuthenticatorHelper.onAccountsUpdated(context, null); mBtAdapter = BluetoothAdapter.getDefaultAdapter(); mNextItemId = 0; - mAllowMultipleAccounts = - context.getResources().getBoolean(R.bool.multiple_accounts_enabled); mPreferenceUtils = new PreferenceUtils(context); mDeveloperEnabled = mPreferenceUtils.isDeveloperEnabled(); mInputSettingNeeded = isInputSettingNeeded(); @@ -238,10 +247,6 @@ public class BrowseInfo extends BrowseInfoBase { } } - private boolean canAddAccount() { - return !isRestricted(); - } - private boolean isRestricted() { return RestrictedProfileActivity.isRestrictedProfileInEffect(mContext); } @@ -446,48 +451,85 @@ public class BrowseInfo extends BrowseInfoBase { } private void addAccounts(ArrayObjectAdapter row) { - String[] accountTypes = mAuthenticatorHelper.getEnabledAccountTypes(); - if (accountTypes.length == 0) { - // That's weird, let's try updating. - mAuthenticatorHelper.onAccountsUpdated(mContext, null); - accountTypes = mAuthenticatorHelper.getEnabledAccountTypes(); - } + AccountManager am = AccountManager.get(mContext); + AuthenticatorDescription[] authTypes = am.getAuthenticatorTypes(); + ArrayList<String> allowableAccountTypes = new ArrayList<>(authTypes.length); + PackageManager pm = mContext.getPackageManager(); int googleAccountCount = 0; - for (String accountType : accountTypes) { - CharSequence label = mAuthenticatorHelper.getLabelForType(mContext, accountType); - if (label == null) { + for (AuthenticatorDescription authDesc : authTypes) { + Resources resources = null; + try { + resources = pm.getResourcesForApplication(authDesc.packageName); + } catch (NameNotFoundException e) { + Log.e(TAG, "Authenticator description with bad package name", e); continue; } - Account[] accounts = AccountManager.get(mContext).getAccountsByType(accountType); - if (ACCOUNT_TYPE_GOOGLE.equals(accountType)) { + allowableAccountTypes.add(authDesc.type); + + // Main title text comes from the authenticator description (e.g. "Google"). + String authTitle = null; + try { + authTitle = resources.getString(authDesc.labelId); + if (TextUtils.isEmpty(authTitle)) { + authTitle = null; // Handled later when we add the row. + } + } catch (NotFoundException e) { + Log.e(TAG, "Authenticator description with bad label id", e); + } + + Account[] accounts = am.getAccountsByType(authDesc.type); + + // Icon URI to be displayed for each account is based on the type of authenticator. + String imageUri = null; + if (ACCOUNT_TYPE_GOOGLE.equals(authDesc.type)) { googleAccountCount = accounts.length; + imageUri = googleAccountIconUri(mContext); + } else { + imageUri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + + authDesc.packageName + '/' + + resources.getResourceTypeName(authDesc.iconId) + '/' + + resources.getResourceEntryName(authDesc.iconId)) + .toString(); } + + // Display an entry for each installed account we have. for (final Account account : accounts) { Intent i = new Intent(mContext, AccountSettingsActivity.class) .putExtra(AccountSettingsActivity.EXTRA_ACCOUNT, account.name); i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); - row.add(new MenuItem.Builder().id(mNextItemId++).title(account.name) - .imageUriGetter(new AccountImageUriGetter(mContext, account)) + row.add(new MenuItem.Builder().id(mNextItemId++) + .title(authTitle != null ? authTitle : account.name) + .imageUri(imageUri) + .description(authTitle != null ? account.name : null) .intent(i) .build()); } } - if (canAddAccount() && (mAllowMultipleAccounts || googleAccountCount == 0)) { - ComponentName componentName = new ComponentName("com.android.tv.settings", - "com.android.tv.settings.accounts.AddAccountWithTypeActivity"); - Intent i = new Intent().setComponent(componentName); - i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); - if (accountTypes.length == 1) { - i.putExtra(AccountManager.KEY_ACCOUNT_TYPE, accountTypes[0]); + // Never allow restricted profile to add accounts. + if (!isRestricted()) { + + // If there's already a Google account installed, disallow installing a second one. + if (googleAccountCount > 0) { + allowableAccountTypes.remove(ACCOUNT_TYPE_GOOGLE); + } + + // If there are available account types, add the "add account" button. + if (!allowableAccountTypes.isEmpty()) { + Intent i = new Intent().setComponent(new ComponentName("com.android.tv.settings", + "com.android.tv.settings.accounts.AddAccountWithTypeActivity")); + i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); + i.putExtra(AddAccountWithTypeActivity.EXTRA_ALLOWABLE_ACCOUNT_TYPES_STRING_ARRAY, + allowableAccountTypes.toArray(new String[allowableAccountTypes.size()])); + + row.add(new MenuItem.Builder().id(mNextItemId++) + .title(mContext.getString(R.string.add_account)) + .imageResourceId(mContext, R.drawable.ic_settings_add) + .intent(i).build()); } - row.add(new MenuItem.Builder().id(mNextItemId++) - .title(mContext.getString(R.string.add_account)) - .imageResourceId(mContext, R.drawable.ic_settings_add) - .intent(i).build()); } } @@ -522,4 +564,12 @@ public class BrowseInfo extends BrowseInfoBase { } } } + + private static String googleAccountIconUri(Context context) { + ShortcutIconResource iconResource = new ShortcutIconResource(); + iconResource.packageName = context.getPackageName(); + iconResource.resourceName = context.getResources().getResourceName( + R.drawable.ic_settings_google_account); + return UriUtils.getShortcutIconResourceUri(iconResource).toString(); + } } diff --git a/Settings/src/com/android/tv/settings/accounts/AddAccountWithTypeActivity.java b/Settings/src/com/android/tv/settings/accounts/AddAccountWithTypeActivity.java index 0f0b09fc9..737175f6b 100644 --- a/Settings/src/com/android/tv/settings/accounts/AddAccountWithTypeActivity.java +++ b/Settings/src/com/android/tv/settings/accounts/AddAccountWithTypeActivity.java @@ -27,8 +27,12 @@ import android.accounts.OperationCanceledException; import java.io.IOException; import android.util.Log; + public class AddAccountWithTypeActivity extends Activity { + // Must match com.google.android.gms.common.AccountPicker. + public static final String EXTRA_ALLOWABLE_ACCOUNT_TYPES_STRING_ARRAY = "allowableAccountTypes"; + private static final String TAG = "AddAccountWithTypeActivity"; private static final int REQUEST_CHOOSE_ACCOUNT_TYPE = 0; @@ -36,8 +40,6 @@ public class AddAccountWithTypeActivity extends Activity { private static final String CHOOSE_ACCOUNT_TYPE_ACTION = "com.google.android.gms.common.account.CHOOSE_ACCOUNT_TYPE"; - private boolean mLaunchAccountTypePicker; - private final AccountManagerCallback<Bundle> mCallback = new AccountManagerCallback<Bundle>() { @Override public void run(AccountManagerFuture<Bundle> future) { @@ -46,19 +48,19 @@ public class AddAccountWithTypeActivity extends Activity { .getParcelable(AccountManager.KEY_INTENT); if (addAccountIntent == null) { Log.e(TAG, "Failed to retrieve add account intent from authenticator"); - handleAddAccountError(); + setResultAndFinish(Activity.RESULT_CANCELED); } else { startActivityForResult(addAccountIntent, REQUEST_ADD_ACCOUNT); } } catch (OperationCanceledException e) { Log.e(TAG, "Failed to get add account intent: " + e); - handleAddAccountError(); + setResultAndFinish(Activity.RESULT_CANCELED); } catch (IOException e) { Log.e(TAG, "Failed to get add account intent: " + e); - handleAddAccountError(); + setResultAndFinish(Activity.RESULT_CANCELED); } catch (AuthenticatorException e) { Log.e(TAG, "Failed to get add account intent: " + e); - handleAddAccountError(); + setResultAndFinish(Activity.RESULT_CANCELED); } } }; @@ -70,48 +72,30 @@ public class AddAccountWithTypeActivity extends Activity { if (accountType != null) { startAddAccount(accountType); } else { - startAccountTypePicker(); + String[] allowedTypes = getIntent().getStringArrayExtra( + EXTRA_ALLOWABLE_ACCOUNT_TYPES_STRING_ARRAY); + startAccountTypePicker(allowedTypes); } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { - if (Activity.RESULT_CANCELED == resultCode) { - setResult(resultCode); - finish(); - return; - } - - switch (requestCode) { - case REQUEST_ADD_ACCOUNT: - if (resultCode == Activity.RESULT_OK) { - setResult(resultCode); - finish(); - } else { - handleAddAccountError(resultCode); - } - break; - case REQUEST_CHOOSE_ACCOUNT_TYPE: - if (resultCode == Activity.RESULT_OK) { - String accountType = data.getExtras() - .getString(AccountManager.KEY_ACCOUNT_TYPE); - startAddAccount(accountType); - } else { - setResult(resultCode); - finish(); - } - break; + // User selected an account type, so kick off the add account flow for that. + if (requestCode == REQUEST_CHOOSE_ACCOUNT_TYPE && resultCode == Activity.RESULT_OK) { + String accountType = data.getExtras().getString(AccountManager.KEY_ACCOUNT_TYPE); + startAddAccount(accountType); + } else { + setResultAndFinish(resultCode); } } - private void startAccountTypePicker() { - mLaunchAccountTypePicker = true; + private void startAccountTypePicker(String[] allowedTypes) { Intent i = new Intent(CHOOSE_ACCOUNT_TYPE_ACTION); + i.putExtra(EXTRA_ALLOWABLE_ACCOUNT_TYPES_STRING_ARRAY, allowedTypes); startActivityForResult(i, REQUEST_CHOOSE_ACCOUNT_TYPE); } private void startAddAccount(String accountType) { - mLaunchAccountTypePicker = false; AccountManager.get(this).addAccount( accountType, null, /* authTokenType */ @@ -120,18 +104,8 @@ public class AddAccountWithTypeActivity extends Activity { null, mCallback, null); } - private void handleAddAccountError() { - handleAddAccountError(Activity.RESULT_CANCELED); - } - - private void handleAddAccountError(int resultCode) { - if (mLaunchAccountTypePicker) { - Log.e(TAG, "request add account failed to add account"); - // try again - startAccountTypePicker(); - } else { - setResult(resultCode); - finish(); - } + private void setResultAndFinish(int resultCode) { + setResult(resultCode); + finish(); } } |