Use entity header on AccountDetailDashboardFragment

Bug: 37669238
Test: make RunSettingsRoboTests
Change-Id: Iaf92730e8c6b5c44cb8eca4525fc931487ce9630
This commit is contained in:
Fan Zhang
2017-05-18 15:11:01 -07:00
parent d7414259d0
commit 98289a887b
8 changed files with 216 additions and 96 deletions

View File

@@ -1,53 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2016 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/EntityHeader"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:gravity="center_vertical"
android:paddingTop="24dip"
android:paddingBottom="24dip"
android:orientation="horizontal">
<LinearLayout
android:id="@+id/icon_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="56dp"
android:orientation="horizontal"
android:paddingEnd="12dp"
android:paddingTop="12dp"
android:paddingBottom="12dp">
<ImageView
android:id="@android:id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxWidth="48dp"
android:maxHeight="48dp"/>
</LinearLayout>
<TextView
android:id="@android:id/title"
style="@style/TextAppearance.EntityHeaderTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"/>
</LinearLayout>

View File

@@ -29,8 +29,8 @@
<ImageView
android:id="@+id/entity_header_icon"
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_width="48dp"
android:layout_height="48dp"
android:scaleType="fitXY"
android:layout_gravity="center_horizontal"
android:antialias="true" />

View File

@@ -19,9 +19,9 @@
android:title="@string/account_settings_title"
settings:keywords="@string/keywords_accounts">
<Preference
<com.android.settings.applications.LayoutPreference
android:key="account_header"
android:layout="@layout/account_header"
android:layout="@layout/settings_entity_header"
android:selectable="false"
android:order="-10000"/>

View File

@@ -22,9 +22,8 @@ import android.os.Bundle;
import android.os.UserHandle;
import android.os.UserManager;
import android.support.annotation.VisibleForTesting;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.Utils;
@@ -45,7 +44,6 @@ public class AccountDetailDashboardFragment extends DashboardFragment {
public static final String KEY_ACCOUNT_TYPE = "account_type";
public static final String KEY_ACCOUNT_LABEL = "account_label";
public static final String KEY_ACCOUNT_TITLE_RES = "account_title_res";
public static final String KEY_ACCOUNT_HEADER = "account_header";
public static final String KEY_USER_HANDLE = "user_handle";
@VisibleForTesting
@@ -110,6 +108,8 @@ public class AccountDetailDashboardFragment extends DashboardFragment {
controllers.add(mAccountSynController);
mRemoveAccountController = new RemoveAccountPreferenceController(context, this);
controllers.add(mRemoveAccountController);
controllers.add(new AccountHeaderPreferenceController(
context, getActivity(), this, getArguments()));
return controllers;
}
@@ -127,8 +127,6 @@ public class AccountDetailDashboardFragment extends DashboardFragment {
@VisibleForTesting
void updateUi() {
final Preference headerPreference = findPreference(KEY_ACCOUNT_HEADER);
headerPreference.setTitle(mAccount.name);
final Context context = getContext();
UserHandle userHandle = null;
Bundle args = getArguments();
@@ -136,14 +134,12 @@ public class AccountDetailDashboardFragment extends DashboardFragment {
userHandle = args.getParcelable(KEY_USER_HANDLE);
}
final AuthenticatorHelper helper = new AuthenticatorHelper(context, userHandle, null);
headerPreference.setIcon(helper.getDrawableForType(context, mAccountType));
final AccountTypePreferenceLoader accountTypePreferenceLoader =
new AccountTypePreferenceLoader(this, helper, userHandle);
PreferenceScreen prefs =
accountTypePreferenceLoader.addPreferencesForType(mAccountType, getPreferenceScreen());
PreferenceScreen prefs = accountTypePreferenceLoader.addPreferencesForType(
mAccountType, getPreferenceScreen());
if (prefs != null) {
accountTypePreferenceLoader.updatePreferenceIntents(prefs, mAccountType, mAccount);
}
}
}

View File

@@ -0,0 +1,87 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.accounts;
import android.accounts.Account;
import android.app.Activity;
import android.app.Fragment;
import android.content.Context;
import android.os.Bundle;
import android.os.UserHandle;
import android.support.v7.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.applications.LayoutPreference;
import com.android.settings.core.PreferenceController;
import com.android.settings.widget.EntityHeaderController;
import com.android.settingslib.accounts.AuthenticatorHelper;
import static com.android.settings.accounts.AccountDetailDashboardFragment.KEY_ACCOUNT;
import static com.android.settings.accounts.AccountDetailDashboardFragment.KEY_USER_HANDLE;
public class AccountHeaderPreferenceController extends PreferenceController {
private static final String KEY_ACCOUNT_HEADER = "account_header";
private final Activity mActivity;
private final Fragment mHost;
private final Account mAccount;
private final UserHandle mUserHandle;
public AccountHeaderPreferenceController(Context context, Activity activity, Fragment host,
Bundle args) {
super(context);
mActivity = activity;
mHost = host;
if (args != null && args.containsKey(KEY_ACCOUNT)) {
mAccount = args.getParcelable(KEY_ACCOUNT);
} else {
mAccount = null;
}
if (args != null && args.containsKey(KEY_USER_HANDLE)) {
mUserHandle = args.getParcelable(KEY_USER_HANDLE);
} else {
mUserHandle = null;
}
}
@Override
public boolean isAvailable() {
return mAccount != null && mUserHandle != null;
}
@Override
public String getPreferenceKey() {
return KEY_ACCOUNT_HEADER;
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
final LayoutPreference headerPreference =
(LayoutPreference) screen.findPreference(KEY_ACCOUNT_HEADER);
final AuthenticatorHelper helper = new AuthenticatorHelper(mContext, mUserHandle, null);
EntityHeaderController
.newInstance(mActivity, mHost, headerPreference.findViewById(R.id.entity_header))
.setLabel(mAccount.name)
.setIcon(helper.getDrawableForType(mContext, mAccount.type))
.done(mActivity, true /* rebindButtons */);
}
}

View File

@@ -175,7 +175,7 @@ public class EntityHeaderController {
}
/**
* Done mutating appheader, rebinds everything and return a new {@link LayoutPreference}.
* Done mutating entity header, rebinds everything and return a new {@link LayoutPreference}.
*/
public LayoutPreference done(Activity activity, Context uiContext) {
final LayoutPreference pref = new LayoutPreference(uiContext, done(activity));
@@ -209,7 +209,7 @@ public class EntityHeaderController {
}
/**
* Only binds app header with button actions.
* Only binds entity header with button actions.
*/
public EntityHeaderController bindHeaderButtons() {
ImageButton button1 = mHeader.findViewById(android.R.id.button1);

View File

@@ -17,7 +17,6 @@ package com.android.settings.accounts;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AuthenticatorDescription;
import android.content.Context;
import android.os.Bundle;
import android.os.UserHandle;
@@ -26,8 +25,6 @@ import android.support.v7.preference.PreferenceScreen;
import com.android.settings.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
import com.android.settings.testutils.shadow.ShadowAccountManager;
import com.android.settings.testutils.shadow.ShadowContentResolver;
import com.android.settingslib.drawer.CategoryKey;
import com.android.settingslib.drawer.Tile;
@@ -41,11 +38,7 @@ import org.robolectric.shadows.ShadowApplication;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Answers.RETURNS_DEEP_STUBS;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
@@ -54,7 +47,6 @@ public class AccountDetailDashboardFragmentTest {
private static final String METADATA_CATEGORY = "com.android.settings.category";
private static final String METADATA_ACCOUNT_TYPE = "com.android.settings.ia.account";
private static final String METADATA_USER_HANDLE = "user_handle";
private static final String PREF_ACCOUNT_HEADER = "account_header";
@Mock(answer = RETURNS_DEEP_STUBS)
private AccountManager mAccountManager;
@@ -118,20 +110,4 @@ public class AccountDetailDashboardFragmentTest {
assertThat(mFragment.displayTile(tile)).isFalse();
}
@Test
@Config(shadows = {ShadowAccountManager.class, ShadowContentResolver.class})
public void updateAccountHeader_shouldShowAccountName() throws Exception {
when(mAccountManager.getAuthenticatorTypesAsUser(anyInt())).thenReturn(
new AuthenticatorDescription[0]);
when(mAccountManager.getAccountsAsUser(anyInt())).thenReturn(new Account[0]);
when(mFragment.getContext()).thenReturn(mContext);
doReturn(mScreen).when(mFragment).getPreferenceScreen();
doReturn(mPreference).when(mFragment).findPreference(PREF_ACCOUNT_HEADER);
mFragment.updateUi();
verify(mPreference).setTitle("name1@abc.com");
}
}

View File

@@ -0,0 +1,114 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.accounts;
import android.accounts.Account;
import android.app.Activity;
import android.app.Fragment;
import android.content.Context;
import android.os.Bundle;
import android.os.UserHandle;
import android.support.v7.preference.PreferenceScreen;
import android.widget.TextView;
import com.android.settings.R;
import com.android.settings.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
import com.android.settings.applications.LayoutPreference;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settingslib.accounts.AuthenticatorHelper;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.when;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class AccountHeaderPreferenceControllerTest {
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private Context mContext;
@Mock
private Activity mActivity;
@Mock
private Fragment mFragment;
@Mock
private PreferenceScreen mScreen;
private LayoutPreference mHeaderPreference;
private AccountHeaderPreferenceController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
FakeFeatureFactory.setupForTest(mContext);
mHeaderPreference = new LayoutPreference(
RuntimeEnvironment.application, R.layout.settings_entity_header);
}
@Test
public void isAvailable_noArgs_shouldReturnNull() {
mController = new AccountHeaderPreferenceController(RuntimeEnvironment.application,
mActivity, mFragment, null /* args */);
assertThat(mController.isAvailable()).isFalse();
}
@Test
@Config(shadows = ShadowAuthenticatorHelper.class)
public void displayPreference_shouldDisplayAccountInEntityHeader() {
final Account account = new Account("name1@abc.com", "com.abc");
Bundle args = new Bundle();
args.putParcelable(AccountDetailDashboardFragment.KEY_ACCOUNT, account);
args.putParcelable(AccountDetailDashboardFragment.KEY_USER_HANDLE, UserHandle.CURRENT);
mController = new AccountHeaderPreferenceController(RuntimeEnvironment.application,
mActivity, mFragment, args);
assertThat(mController.isAvailable()).isTrue();
when(mScreen.findPreference(anyString())).thenReturn(mHeaderPreference);
mController.displayPreference(mScreen);
final CharSequence label =
((TextView) mHeaderPreference.findViewById(R.id.entity_header_title)).getText();
assertThat(label).isEqualTo(account.name);
}
@Implements(AuthenticatorHelper.class)
public static class ShadowAuthenticatorHelper {
@Implementation
public void onAccountsUpdated(Account[] accounts) {
}
}
}