Add a new About Phone page.

This adds the "Me Card" page. The current functionality is to show
information based upon the first account added to the system. The page
shows the user's avatar, name, primary account, and phone number.

Bug: 63819909
Test: Robotest

Change-Id: I64bfae922e828994b2b87009d0647e67dab0da42
This commit is contained in:
Daniel Nishi
2017-12-19 10:15:14 -08:00
parent 663b2d9bd3
commit 1e620957b8
16 changed files with 461 additions and 0 deletions

View File

@@ -1004,6 +1004,34 @@
android:value="true" /> android:value="true" />
</activity> </activity>
<activity android:name="Settings$MeCardActivity"
android:label="@string/device_info_settings"
android:icon="@drawable/ic_settings_about"
android:taskAffinity="com.android.settings"
android:parentActivityName="Settings">
<intent-filter android:priority="1">
<action android:name="android.settings.DEVICE_HEALTH_SETTINGS" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.VOICE_LAUNCH" />
</intent-filter>
<intent-filter android:priority="10">
<action android:name="com.android.settings.action.SETTINGS" />
</intent-filter>
<meta-data android:name="com.android.settings.category"
android:value="com.android.settings.category.ia.system" />
<meta-data android:name="com.android.settings.title"
android:resource="@string/about_settings" />
<meta-data android:name="com.android.settings.FRAGMENT_CLASS"
android:value="com.android.settings.MeCardFragment" />
<meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
android:value="true" />
</activity>
<activity android:name="SettingsLicenseActivity" <activity android:name="SettingsLicenseActivity"
android:label="@string/settings_license_activity_title" android:label="@string/settings_license_activity_title"
android:theme="@android:style/Theme.DeviceDefault.Light.Panel" android:theme="@android:style/Theme.DeviceDefault.Light.Panel"

View File

@@ -9216,4 +9216,15 @@
[DO NOT TRANSLATE] --> [DO NOT TRANSLATE] -->
<string name="account_confirmation_package"></string> <string name="account_confirmation_package"></string>
<!-- Title for the new About Phone screen [CHAR LIMIT=40] -->
<string name="me_card_title" product="default">My Phone</string>
<!-- Title for the new About Phone screen [CHAR LIMIT=40] -->
<string name="me_card_title" product="tablet">My Tablet</string>
<!-- Title for the new About Phone screen [CHAR LIMIT=40] -->
<string name="me_card_title" product="device">My Device</string>
<!-- Title for preference showing the primary account on the device [CHAR LIMIT=60]-->
<string name="me_card_account_preference_title">Account</string>
<!-- Title for preference showing the name of the device. [CHAR LIMIT=60]-->
<string name="me_card_device_name_preference_title">Device name</string>
</resources> </resources>

50
res/xml/me_card.xml Normal file
View File

@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2018 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.
-->
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
android:key="me_card_pref_screen"
android:title="@string/me_card_title">
<com.android.settings.applications.LayoutPreference
android:key="me_card_header"
android:order="0"
android:layout="@layout/settings_entity_header"
android:selectable="false"/>
<!-- Account name -->
<Preference
android:key="account"
android:order="1"
android:title="@string/me_card_account_preference_title"
android:summary="@string/summary_placeholder"/>
<!-- Phone number -->
<Preference
android:key="phone_number"
android:order="2"
android:title="@string/status_number"
android:summary="@string/summary_placeholder"/>
<!-- Device name -->
<Preference
android:key="device_name"
android:order="3"
android:title="@string/me_card_device_name_preference_title"
android:summary="@string/summary_placeholder"/>
</PreferenceScreen>

View File

@@ -0,0 +1,137 @@
/*
* Copyright (C) 2018 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;
import android.app.Activity;
import android.app.Fragment;
import android.content.Context;
import android.content.pm.UserInfo;
import android.os.Bundle;
import android.os.UserManager;
import android.provider.SearchIndexableResource;
import android.view.View;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.applications.LayoutPreference;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.deviceinfo.BrandedAccountPreferenceController;
import com.android.settings.deviceinfo.PhoneNumberPreferenceController;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
import com.android.settings.widget.EntityHeaderController;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.lifecycle.Lifecycle;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class MeCardFragment extends DashboardFragment implements Indexable {
private static final String LOG_TAG = "MeCardFragment";
private static final String KEY_ME_CARD_HEADER = "me_card_header";
@Override
public int getMetricsCategory() {
return MetricsEvent.DEVICEINFO;
}
@Override
public int getHelpResource() {
return R.string.help_uri_about;
}
@Override
public void onResume() {
super.onResume();
initHeader();
}
@Override
protected String getLogTag() {
return LOG_TAG;
}
@Override
protected int getPreferenceScreenResId() {
return R.xml.me_card;
}
@Override
protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
return buildPreferenceControllers(context, getActivity(), this /* fragment */,
getLifecycle());
}
private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
Activity activity, Fragment fragment, Lifecycle lifecycle) {
final List<AbstractPreferenceController> controllers = new ArrayList<>();
controllers.add(new PhoneNumberPreferenceController(context));
controllers.add(new BrandedAccountPreferenceController(context));
// TODO: Add preference controller for getting the device name.
return controllers;
}
private void initHeader() {
// TODO: Migrate into its own controller.
final LayoutPreference headerPreference =
(LayoutPreference) getPreferenceScreen().findPreference(KEY_ME_CARD_HEADER);
final View appSnippet = headerPreference.findViewById(R.id.entity_header);
final Activity context = getActivity();
final Bundle bundle = getArguments();
EntityHeaderController controller = EntityHeaderController
.newInstance(context, this, appSnippet)
.setRecyclerView(getListView(), getLifecycle())
.setButtonActions(EntityHeaderController.ActionType.ACTION_NONE,
EntityHeaderController.ActionType.ACTION_NONE);
// TODO: There may be an avatar setting action we can use here.
final int iconId = bundle.getInt("icon_id", 0);
if (iconId == 0) {
UserManager userManager = (UserManager) getActivity().getSystemService(
Context.USER_SERVICE);
UserInfo info = Utils.getExistingUser(userManager, android.os.Process.myUserHandle());
controller.setLabel(info.name);
controller.setIcon(
com.android.settingslib.Utils.getUserIcon(getActivity(), userManager, info));
}
controller.done(context, true /* rebindActions */);
}
/**
* For Search.
*/
public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider() {
@Override
public List<SearchIndexableResource> getXmlResourcesToIndex(
Context context, boolean enabled) {
final SearchIndexableResource sir = new SearchIndexableResource(context);
sir.xmlResId = R.xml.me_card;
return Arrays.asList(sir);
}
@Override
public List<AbstractPreferenceController> getPreferenceControllers(
Context context) {
return buildPreferenceControllers(context, null /*activity */,
null /* fragment */, null /* lifecycle */);
}
};
}

View File

@@ -55,6 +55,7 @@ public class Settings extends SettingsActivity {
public static class NightDisplaySettingsActivity extends SettingsActivity { /* empty */ } public static class NightDisplaySettingsActivity extends SettingsActivity { /* empty */ }
public static class NightDisplaySuggestionActivity extends NightDisplaySettingsActivity { /* empty */ } public static class NightDisplaySuggestionActivity extends NightDisplaySettingsActivity { /* empty */ }
public static class DeviceInfoSettingsActivity extends SettingsActivity { /* empty */ } public static class DeviceInfoSettingsActivity extends SettingsActivity { /* empty */ }
public static class MeCardActivity extends SettingsActivity { /* empty */ }
public static class ApplicationSettingsActivity extends SettingsActivity { /* empty */ } public static class ApplicationSettingsActivity extends SettingsActivity { /* empty */ }
public static class ManageApplicationsActivity extends SettingsActivity { /* empty */ } public static class ManageApplicationsActivity extends SettingsActivity { /* empty */ }
public static class ManageAssistActivity extends SettingsActivity { /* empty */ } public static class ManageAssistActivity extends SettingsActivity { /* empty */ }

View File

@@ -873,6 +873,19 @@ public class SettingsActivity extends SettingsDrawerActivity
WifiDisplaySettings.isAvailable(this), isAdmin) WifiDisplaySettings.isAvailable(this), isAdmin)
|| somethingChanged; || somethingChanged;
// Enable/disable the Me Card page.
final boolean isMeCardEnabled = featureFactory
.getAccountFeatureProvider()
.isMeCardEnabled(this);
somethingChanged = setTileEnabled(new ComponentName(packageName,
Settings.MeCardActivity.class.getName()),
isMeCardEnabled, isAdmin)
|| somethingChanged;
somethingChanged = setTileEnabled(new ComponentName(packageName,
Settings.DeviceInfoSettingsActivity.class.getName()),
!isMeCardEnabled, isAdmin)
|| somethingChanged;
if (UserHandle.MU_ENABLED && !isAdmin) { if (UserHandle.MU_ENABLED && !isAdmin) {
// When on restricted users, disable all extra categories (but only the settings ones). // When on restricted users, disable all extra categories (but only the settings ones).

View File

@@ -0,0 +1,34 @@
/*
* Copyright (C) 2018 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.content.Context;
import android.util.FeatureFlagUtils;
import com.android.settings.core.FeatureFlags;
public interface AccountFeatureProvider {
String getAccountType();
Account[] getAccounts(Context context);
/**
* Checks whether or not to display the new About Phone page.
*/
default boolean isMeCardEnabled(Context context) {
return FeatureFlagUtils.isEnabled(context, FeatureFlags.ABOUT_PHONE_V2);
}
}

View File

@@ -0,0 +1,16 @@
package com.android.settings.accounts;
import android.accounts.Account;
import android.content.Context;
public class AccountFeatureProviderImpl implements AccountFeatureProvider {
@Override
public String getAccountType() {
return null;
}
@Override
public Account[] getAccounts(Context context) {
return new Account[0];
}
}

View File

@@ -27,4 +27,5 @@ public class FeatureFlags {
public static final String SECURITY_SETTINGS_V2 = "settings_security_settings_v2"; public static final String SECURITY_SETTINGS_V2 = "settings_security_settings_v2";
public static final String ZONE_PICKER_V2 = "settings_zone_picker_v2"; public static final String ZONE_PICKER_V2 = "settings_zone_picker_v2";
public static final String SUGGESTION_UI_V2 = "settings_suggestion_ui_v2"; public static final String SUGGESTION_UI_V2 = "settings_suggestion_ui_v2";
public static final String ABOUT_PHONE_V2 = "settings_about_phone_v2";
} }

View File

@@ -298,5 +298,6 @@ public class SettingsGateway {
Settings.DateTimeSettingsActivity.class.getName(), Settings.DateTimeSettingsActivity.class.getName(),
Settings.DeviceInfoSettingsActivity.class.getName(), Settings.DeviceInfoSettingsActivity.class.getName(),
Settings.EnterprisePrivacySettingsActivity.class.getName(), Settings.EnterprisePrivacySettingsActivity.class.getName(),
Settings.MeCardActivity.class.getName(),
}; };
} }

View File

@@ -0,0 +1,78 @@
/*
* Copyright (C) 2018 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.deviceinfo;
import android.accounts.Account;
import android.content.Context;
import android.os.Bundle;
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;
import com.android.settings.accounts.AccountDetailDashboardFragment;
import com.android.settings.accounts.AccountFeatureProvider;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.overlay.FeatureFactory;
public class BrandedAccountPreferenceController extends BasePreferenceController {
private static final String KEY_PREFERENCE_TITLE = "account";
private final Account[] mAccounts;
public BrandedAccountPreferenceController(Context context) {
super(context, KEY_PREFERENCE_TITLE);
final AccountFeatureProvider accountFeatureProvider = FeatureFactory.getFactory(
mContext).getAccountFeatureProvider();
mAccounts = accountFeatureProvider.getAccounts(mContext);
}
@Override
public int getAvailabilityStatus() {
if (mAccounts != null && mAccounts.length > 0) {
return AVAILABLE;
}
return DISABLED_FOR_USER;
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
final AccountFeatureProvider accountFeatureProvider = FeatureFactory.getFactory(
mContext).getAccountFeatureProvider();
final Preference accountPreference = screen.findPreference(KEY_PREFERENCE_TITLE);
if (accountPreference != null && (mAccounts == null || mAccounts.length == 0)) {
screen.removePreference(accountPreference);
return;
}
accountPreference.setSummary(mAccounts[0].name);
accountPreference.setOnPreferenceClickListener(preference -> {
final Bundle args = new Bundle();
args.putParcelable(AccountDetailDashboardFragment.KEY_ACCOUNT,
mAccounts[0]);
args.putParcelable(AccountDetailDashboardFragment.KEY_USER_HANDLE,
android.os.Process.myUserHandle());
args.putString(AccountDetailDashboardFragment.KEY_ACCOUNT_TYPE,
accountFeatureProvider.getAccountType());
Utils.startWithFragment(mContext, AccountDetailDashboardFragment.class.getName(),
args, null, 0,
R.string.account_sync_title, null, MetricsEvent.ACCOUNT);
return true;
});
}
}

View File

@@ -21,6 +21,7 @@ import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.accounts.AccountFeatureProvider;
import com.android.settings.applications.ApplicationFeatureProvider; import com.android.settings.applications.ApplicationFeatureProvider;
import com.android.settings.bluetooth.BluetoothFeatureProvider; import com.android.settings.bluetooth.BluetoothFeatureProvider;
import com.android.settings.connecteddevice.SmsMirroringFeatureProvider; import com.android.settings.connecteddevice.SmsMirroringFeatureProvider;
@@ -109,6 +110,8 @@ public abstract class FeatureFactory {
public abstract SlicesFeatureProvider getSlicesFeatureProvider(); public abstract SlicesFeatureProvider getSlicesFeatureProvider();
public abstract AccountFeatureProvider getAccountFeatureProvider();
public static final class FactoryNotFoundException extends RuntimeException { public static final class FactoryNotFoundException extends RuntimeException {
public FactoryNotFoundException(Throwable throwable) { public FactoryNotFoundException(Throwable throwable) {
super("Unable to create factory. Did you misconfigure Proguard?", throwable); super("Unable to create factory. Did you misconfigure Proguard?", throwable);

View File

@@ -23,6 +23,8 @@ import android.net.ConnectivityManager;
import android.os.UserManager; import android.os.UserManager;
import android.support.annotation.Keep; import android.support.annotation.Keep;
import com.android.settings.accounts.AccountFeatureProvider;
import com.android.settings.accounts.AccountFeatureProviderImpl;
import com.android.settings.applications.ApplicationFeatureProvider; import com.android.settings.applications.ApplicationFeatureProvider;
import com.android.settings.applications.ApplicationFeatureProviderImpl; import com.android.settings.applications.ApplicationFeatureProviderImpl;
import com.android.settings.bluetooth.BluetoothFeatureProvider; import com.android.settings.bluetooth.BluetoothFeatureProvider;
@@ -78,6 +80,7 @@ public class FeatureFactoryImpl extends FeatureFactory {
private DataPlanFeatureProvider mDataPlanFeatureProvider; private DataPlanFeatureProvider mDataPlanFeatureProvider;
private SmsMirroringFeatureProvider mSmsMirroringFeatureProvider; private SmsMirroringFeatureProvider mSmsMirroringFeatureProvider;
private SlicesFeatureProvider mSlicesFeatureProvider; private SlicesFeatureProvider mSlicesFeatureProvider;
private AccountFeatureProvider mAccountFeatureProvider;
@Override @Override
public SupportFeatureProvider getSupportFeatureProvider(Context context) { public SupportFeatureProvider getSupportFeatureProvider(Context context) {
@@ -219,4 +222,12 @@ public class FeatureFactoryImpl extends FeatureFactory {
} }
return mSlicesFeatureProvider; return mSlicesFeatureProvider;
} }
@Override
public AccountFeatureProvider getAccountFeatureProvider() {
if (mAccountFeatureProvider == null) {
mAccountFeatureProvider = new AccountFeatureProviderImpl();
}
return mAccountFeatureProvider;
}
} }

View File

@@ -21,6 +21,7 @@ import android.support.annotation.VisibleForTesting;
import com.android.settings.DateTimeSettings; import com.android.settings.DateTimeSettings;
import com.android.settings.DisplaySettings; import com.android.settings.DisplaySettings;
import com.android.settings.LegalSettings; import com.android.settings.LegalSettings;
import com.android.settings.MeCardFragment;
import com.android.settings.accessibility.AccessibilitySettings; import com.android.settings.accessibility.AccessibilitySettings;
import com.android.settings.accessibility.AccessibilityShortcutPreferenceFragment; import com.android.settings.accessibility.AccessibilityShortcutPreferenceFragment;
import com.android.settings.accessibility.MagnificationPreferenceFragment; import com.android.settings.accessibility.MagnificationPreferenceFragment;
@@ -173,6 +174,7 @@ public class SearchIndexableResourcesImpl implements SearchIndexableResources {
addIndex(ZenModeAutomationSettings.class); addIndex(ZenModeAutomationSettings.class);
addIndex(NightDisplaySettings.class); addIndex(NightDisplaySettings.class);
addIndex(SmartBatterySettings.class); addIndex(SmartBatterySettings.class);
addIndex(MeCardFragment.class);
} }
@Override @Override

View File

@@ -0,0 +1,67 @@
/*
* Copyright (C) 2018 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.deviceinfo;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import android.accounts.Account;
import android.content.Context;
import com.android.settings.TestConfig;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
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.annotation.Config;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class BrandedAccountPreferenceControllerTest {
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private Context mContext;
private BrandedAccountPreferenceController mController;
private FakeFeatureFactory fakeFeatureFactory;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
fakeFeatureFactory = FakeFeatureFactory.setupForTest();
mController = new BrandedAccountPreferenceController(mContext);
}
@Test
public void isAvailable_defaultOff() {
assertThat(mController.isAvailable()).isFalse();
}
@Test
public void isAvailable_onWhenAccountIsAvailable() {
when(fakeFeatureFactory.mAccountFeatureProvider.getAccounts(any(Context.class))).thenReturn(
new Account[]
{new Account("fake@account.foo", "fake.reallyfake")});
mController = new BrandedAccountPreferenceController(mContext);
assertThat(mController.isAvailable()).isTrue();
}
}

View File

@@ -21,6 +21,7 @@ import static org.mockito.Mockito.when;
import android.content.Context; import android.content.Context;
import com.android.settings.accounts.AccountFeatureProvider;
import com.android.settings.applications.ApplicationFeatureProvider; import com.android.settings.applications.ApplicationFeatureProvider;
import com.android.settings.bluetooth.BluetoothFeatureProvider; import com.android.settings.bluetooth.BluetoothFeatureProvider;
import com.android.settings.connecteddevice.SmsMirroringFeatureProvider; import com.android.settings.connecteddevice.SmsMirroringFeatureProvider;
@@ -65,6 +66,7 @@ public class FakeFeatureFactory extends FeatureFactory {
public final SmsMirroringFeatureProvider smsMirroringFeatureProvider; public final SmsMirroringFeatureProvider smsMirroringFeatureProvider;
public final SlicesFeatureProvider slicesFeatureProvider; public final SlicesFeatureProvider slicesFeatureProvider;
public SearchFeatureProvider searchFeatureProvider; public SearchFeatureProvider searchFeatureProvider;
public final AccountFeatureProvider mAccountFeatureProvider;
/** /**
* Call this in {@code @Before} method of the test class to use fake factory. * Call this in {@code @Before} method of the test class to use fake factory.
@@ -104,6 +106,7 @@ public class FakeFeatureFactory extends FeatureFactory {
dataPlanFeatureProvider = mock(DataPlanFeatureProvider.class); dataPlanFeatureProvider = mock(DataPlanFeatureProvider.class);
smsMirroringFeatureProvider = mock(SmsMirroringFeatureProvider.class); smsMirroringFeatureProvider = mock(SmsMirroringFeatureProvider.class);
slicesFeatureProvider = mock(SlicesFeatureProvider.class); slicesFeatureProvider = mock(SlicesFeatureProvider.class);
mAccountFeatureProvider = mock(AccountFeatureProvider.class);
} }
@Override @Override
@@ -190,4 +193,9 @@ public class FakeFeatureFactory extends FeatureFactory {
public SlicesFeatureProvider getSlicesFeatureProvider() { public SlicesFeatureProvider getSlicesFeatureProvider() {
return slicesFeatureProvider; return slicesFeatureProvider;
} }
@Override
public AccountFeatureProvider getAccountFeatureProvider() {
return mAccountFeatureProvider;
}
} }