Merge "Import translations. DO NOT MERGE" into oc-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 4529891..9e23380 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -2373,8 +2373,6 @@
             </intent-filter>
             <meta-data android:name="com.android.settings.category"
                 android:value="com.android.settings.category.ia.accounts" />
-            <meta-data android:name="com.android.settings.summary"
-                android:resource="@string/summary_empty"/>
             <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
                 android:value="com.android.settings.users.UserSettings" />
             <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
diff --git a/res/layout/app_details.xml b/res/layout/app_details.xml
index c3ffe1a..2db23e4 100644
--- a/res/layout/app_details.xml
+++ b/res/layout/app_details.xml
@@ -85,6 +85,7 @@
                 android:singleLine="false"
                 android:ellipsize="marquee"
                 android:gravity="start"
+                android:textDirection="locale"
                 android:paddingTop="8dp"/>
 
             <TextView
diff --git a/src/com/android/settings/accounts/AccountPreferenceController.java b/src/com/android/settings/accounts/AccountPreferenceController.java
index 6d22620..a782a7d 100644
--- a/src/com/android/settings/accounts/AccountPreferenceController.java
+++ b/src/com/android/settings/accounts/AccountPreferenceController.java
@@ -34,6 +34,7 @@
 import android.support.v7.preference.Preference.OnPreferenceClickListener;
 import android.support.v7.preference.PreferenceGroup;
 import android.support.v7.preference.PreferenceScreen;
+import android.util.ArrayMap;
 import android.util.Log;
 import android.util.SparseArray;
 
@@ -117,6 +118,14 @@
          * The {@link UserInfo} of the profile.
          */
         public UserInfo userInfo;
+        /**
+         * The {@link UserInfo} of the profile.
+         */
+        public boolean pendingRemoval;
+        /**
+         * The map from account name to account preference
+         */
+        public ArrayMap<CharSequence, AccountTypePreference> accountPreferences = new ArrayMap<>();
     }
 
     public AccountPreferenceController(Context context, SettingsPreferenceFragment parent,
@@ -150,6 +159,12 @@
     }
 
     @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        updateUi();
+    }
+
+    @Override
     public void updateRawDataToIndex(List<SearchIndexableRaw> rawData) {
         if (!isAvailable()) {
             return;
@@ -189,7 +204,6 @@
 
     @Override
     public void onResume() {
-        cleanUpPreferences();
         updateUi();
         mManagedProfileBroadcastReceiver.register(mContext);
         listenToAccountUpdates();
@@ -253,6 +267,9 @@
             return;
         }
 
+        for (int i = 0, size = mProfiles.size(); i < size; i++) {
+            mProfiles.valueAt(i).pendingRemoval = true;
+        }
         if (mUm.isLinkedUser()) {
             // Restricted user or similar
             UserInfo userInfo = mUm.getUserInfo(UserHandle.myUserId());
@@ -264,6 +281,7 @@
                 updateProfileUi(profiles.get(i));
             }
         }
+        cleanUpPreferences();
 
         // Add all preferences, starting with one for the primary profile.
         // Note that we're relying on the ordering given by the SparseArray keys, and on the
@@ -278,6 +296,11 @@
         if (mParent.getPreferenceManager() == null) {
             return;
         }
+        final ProfileData data = mProfiles.get(userInfo.id);
+        if (data != null) {
+            data.pendingRemoval = false;
+            return;
+        }
         final Context context = mContext;
         final ProfileData profileData = new ProfileData();
         profileData.userInfo = userInfo;
@@ -366,12 +389,14 @@
         if (screen == null) {
             return;
         }
-        for (int i = 0; i < mProfiles.size(); i++) {
-            final PreferenceGroup preferenceGroup = mProfiles.valueAt(i).preferenceGroup;
-            screen.removePreference(preferenceGroup);
+        final int count = mProfiles.size();
+        for (int i = count-1; i >= 0; i--) {
+            final ProfileData data = mProfiles.valueAt(i);
+            if (data.pendingRemoval) {
+                screen.removePreference(data.preferenceGroup);
+                mProfiles.removeAt(i);
+            }
         }
-        mProfiles.clear();
-        mAccountProfileOrder = ORDER_ACCOUNT_PROFILES;
     }
 
     private void listenToAccountUpdates() {
@@ -400,18 +425,31 @@
             // This could happen if activity is finishing
             return;
         }
-        profileData.preferenceGroup.removeAll();
         if (profileData.userInfo.isEnabled()) {
+            final ArrayMap<CharSequence, AccountTypePreference> preferenceToRemove =
+                    new ArrayMap<>(profileData.accountPreferences);
             final ArrayList<AccountTypePreference> preferences = getAccountTypePreferences(
-                    profileData.authenticatorHelper, profileData.userInfo.getUserHandle());
+                    profileData.authenticatorHelper, profileData.userInfo.getUserHandle(),
+                    preferenceToRemove);
             final int count = preferences.size();
             for (int i = 0; i < count; i++) {
-                profileData.preferenceGroup.addPreference(preferences.get(i));
+                final AccountTypePreference preference = preferences.get(i);
+                preference.setOrder(i);
+                if (!profileData.accountPreferences.containsValue(preference)) {
+                    profileData.preferenceGroup.addPreference(preferences.get(i));
+                    profileData.accountPreferences.put(preference.getTitle(), preference);
+                }
             }
             if (profileData.addAccountPreference != null) {
                 profileData.preferenceGroup.addPreference(profileData.addAccountPreference);
             }
+            for (CharSequence name : preferenceToRemove.keySet()) {
+                profileData.preferenceGroup.removePreference(
+                    profileData.accountPreferences.get(name));
+                profileData.accountPreferences.remove(name);
+            }
         } else {
+            profileData.preferenceGroup.removeAll();
             // Put a label instead of the accounts list
             if (mProfileNotAvailablePreference == null) {
                 mProfileNotAvailablePreference =
@@ -433,7 +471,8 @@
     }
 
     private ArrayList<AccountTypePreference> getAccountTypePreferences(AuthenticatorHelper helper,
-            UserHandle userHandle) {
+            UserHandle userHandle,
+            ArrayMap<CharSequence, AccountTypePreference> preferenceToRemove) {
         final String[] accountTypes = helper.getEnabledAccountTypes();
         final ArrayList<AccountTypePreference> accountTypePreferences =
                 new ArrayList<>(accountTypes.length);
@@ -453,13 +492,16 @@
 
             final Account[] accounts = AccountManager.get(mContext)
                     .getAccountsByTypeAsUser(accountType, userHandle);
-            final boolean skipToAccount = accounts.length == 1
-                    && !helper.hasAccountPreferences(accountType);
             final Drawable icon = helper.getDrawableForType(mContext, accountType);
             final Context prefContext = mParent.getPreferenceManager().getContext();
 
             // Add a preference row for each individual account
             for (Account account : accounts) {
+                final AccountTypePreference preference = preferenceToRemove.remove(account.name);
+                if (preference != null) {
+                    accountTypePreferences.add(preference);
+                    continue;
+                }
                 final ArrayList<String> auths =
                     helper.getAuthoritiesForAccountType(account.type);
                 if (!AccountRestrictionHelper.showAccount(mAuthorities, auths)) {
@@ -531,7 +573,6 @@
                     || action.equals(Intent.ACTION_MANAGED_PROFILE_ADDED)) {
                 // Clean old state
                 stopListeningToAccountUpdates();
-                cleanUpPreferences();
                 // Build new state
                 updateUi();
                 listenToAccountUpdates();
diff --git a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java
index 0cbfd54..7a2e4c0 100644
--- a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java
+++ b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java
@@ -28,7 +28,6 @@
 import android.support.annotation.VisibleForTesting;
 import android.support.v14.preference.PreferenceFragment;
 import android.support.v7.preference.Preference;
-import android.text.TextUtils;
 import android.view.View;
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -45,6 +44,7 @@
 import com.android.settings.enterprise.DevicePolicyManagerWrapper;
 import com.android.settings.enterprise.DevicePolicyManagerWrapperImpl;
 import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.applications.AppUtils;
 import com.android.settingslib.applications.ApplicationsState;
 
 import java.util.ArrayList;
@@ -202,7 +202,11 @@
             mState.ensureIcon(mAppEntry);
             controller.setLabel(mAppEntry);
             controller.setIcon(mAppEntry);
-            controller.setSummary(getString(Utils.getInstallationStatus(mAppEntry.info)));
+            boolean isInstantApp = AppUtils.isInstant(mAppEntry.info);
+            CharSequence summary = isInstantApp
+                    ? null : getString(Utils.getInstallationStatus(mAppEntry.info));
+            controller.setIsInstantApp(AppUtils.isInstant(mAppEntry.info));
+            controller.setSummary(summary);
         }
 
         controller.done(context, true /* rebindActions */);
diff --git a/src/com/android/settings/search2/DatabaseIndexingManager.java b/src/com/android/settings/search2/DatabaseIndexingManager.java
index c627ea5..647219b 100644
--- a/src/com/android/settings/search2/DatabaseIndexingManager.java
+++ b/src/com/android/settings/search2/DatabaseIndexingManager.java
@@ -33,6 +33,7 @@
 import android.provider.SearchIndexableData;
 import android.provider.SearchIndexableResource;
 import android.provider.SearchIndexablesContract;
+import android.support.annotation.DrawableRes;
 import android.support.annotation.VisibleForTesting;
 import android.text.TextUtils;
 import android.util.AttributeSet;
@@ -525,8 +526,6 @@
             final int count = cursor.getCount();
             if (count > 0) {
                 while (cursor.moveToNext()) {
-                    final int providerRank = cursor.getInt(COLUMN_INDEX_XML_RES_RANK);
-                    // TODO remove provider rank
                     final int xmlResId = cursor.getInt(COLUMN_INDEX_XML_RES_RESID);
 
                     final String className = cursor.getString(COLUMN_INDEX_XML_RES_CLASS_NAME);
@@ -720,7 +719,6 @@
             final AttributeSet attrs = Xml.asAttributeSet(parser);
 
             final String screenTitle = XmlParserUtils.getDataTitle(context, attrs);
-
             String key = XmlParserUtils.getDataKey(context, attrs);
 
             String title;
@@ -730,10 +728,11 @@
             String keywords;
             String headerKeywords;
             String childFragment;
+            @DrawableRes
+            int iconResId;
             ResultPayload payload;
             boolean enabled;
             final String fragmentName = sir.className;
-            final int iconResId = sir.iconResId;
             final int rank = sir.rank;
             final String intentAction = sir.intentAction;
             final String intentTargetPackage = sir.intentTargetPackage;
@@ -784,6 +783,7 @@
                 key = XmlParserUtils.getDataKey(context, attrs);
                 enabled = ! nonIndexableKeys.contains(key);
                 keywords = XmlParserUtils.getDataKeywords(context, attrs);
+                iconResId = XmlParserUtils.getDataIcon(context, attrs);
 
                 if (isHeaderUnique && TextUtils.equals(headerTitle, title)) {
                     isHeaderUnique = false;
@@ -853,7 +853,6 @@
             List<String> nonIndexableKeys) {
 
         final String className = sir.className;
-        final int iconResId = sir.iconResId;
         final int rank = sir.rank;
 
         if (provider == null) {
@@ -881,7 +880,7 @@
                         .setEntries(raw.entries)
                         .setClassName(className)
                         .setScreenTitle(raw.screenTitle)
-                        .setIconResId(iconResId)
+                        .setIconResId(raw.iconResId)
                         .setRank(rank)
                         .setIntentAction(raw.intentAction)
                         .setIntentTargetPackage(raw.intentTargetPackage)
@@ -907,7 +906,6 @@
                     continue;
                 }
 
-                item.iconResId = (item.iconResId == 0) ? iconResId : item.iconResId;
                 item.className = (TextUtils.isEmpty(item.className)) ? className : item.className;
 
                 indexFromResource(database, localeStr, item, nonIndexableKeys);
diff --git a/src/com/android/settings/search2/SearchViewHolder.java b/src/com/android/settings/search2/SearchViewHolder.java
index 67653e0..1175fcb 100644
--- a/src/com/android/settings/search2/SearchViewHolder.java
+++ b/src/com/android/settings/search2/SearchViewHolder.java
@@ -69,11 +69,9 @@
             AppSearchResult appResult = (AppSearchResult) result;
             PackageManager pm = fragment.getActivity().getPackageManager();
             iconView.setImageDrawable(appResult.info.loadIcon(pm));
-        } else if (result.icon != null) {
-            iconView.setImageDrawable(result.icon);
-            // TODO set color of icon
         } else {
-            iconView.setBackgroundResource(R.drawable.empty_icon);
+            // Valid even when result.icon is null.
+            iconView.setImageDrawable(result.icon);
         }
 
         bindBreadcrumbView(result);
diff --git a/src/com/android/settings/search2/XmlParserUtils.java b/src/com/android/settings/search2/XmlParserUtils.java
index 90b1c1f..17f1743 100644
--- a/src/com/android/settings/search2/XmlParserUtils.java
+++ b/src/com/android/settings/search2/XmlParserUtils.java
@@ -71,6 +71,14 @@
         return getData(context, attrs, R.styleable.Preference, R.styleable.Preference_keywords);
     }
 
+    public static int getDataIcon(Context context, AttributeSet attrs) {
+        final TypedArray ta = context.obtainStyledAttributes(attrs,
+                com.android.internal.R.styleable.Preference);
+        final int dataIcon = ta.getResourceId(com.android.internal.R.styleable.Icon_icon, 0);
+        ta.recycle();
+        return dataIcon;
+    }
+
     /**
      * Returns the fragment name if this preference launches a child fragment.
      */
@@ -80,17 +88,9 @@
     }
 
     private static String getData(Context context, AttributeSet set, int[] attrs, int resId) {
-        final TypedArray sa = context.obtainStyledAttributes(set, attrs);
-        final TypedValue tv = sa.peekValue(resId);
-
-        CharSequence data = null;
-        if (tv != null && tv.type == TypedValue.TYPE_STRING) {
-            if (tv.resourceId != 0) {
-                data = context.getText(tv.resourceId);
-            } else {
-                data = tv.string;
-            }
-        }
+        final TypedArray ta = context.obtainStyledAttributes(set, attrs);
+        String data = ta.getString(resId);
+        ta.recycle();
         return (data != null) ? data.toString() : null;
     }
 
diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java
index 9963da1..01ccfee 100644
--- a/src/com/android/settings/wifi/WifiSettings.java
+++ b/src/com/android/settings/wifi/WifiSettings.java
@@ -853,11 +853,18 @@
 
     private void setAdditionalSettingsSummaries() {
         mAdditionalSettingsPreferenceCategory.addPreference(mConfigureWifiSettingsPreference);
-        boolean wifiWakeupEnabled = Settings.Global.getInt(
-                getContentResolver(), Settings.Global.WIFI_WAKEUP_ENABLED, 0) == 1;
-        mConfigureWifiSettingsPreference.setSummary(getString(wifiWakeupEnabled
-                ? R.string.wifi_configure_settings_preference_summary_wakeup_on
-                : R.string.wifi_configure_settings_preference_summary_wakeup_off));
+        final int defaultWakeupAvailable = getResources().getInteger(
+                com.android.internal.R.integer.config_wifi_wakeup_available);
+        boolean wifiWakeupAvailable = Settings.Global.getInt(
+                getContentResolver(), Settings.Global.WIFI_WAKEUP_AVAILABLE, defaultWakeupAvailable)
+                == 1;
+        if (wifiWakeupAvailable) {
+            boolean wifiWakeupEnabled = Settings.Global.getInt(
+                    getContentResolver(), Settings.Global.WIFI_WAKEUP_ENABLED, 0) == 1;
+            mConfigureWifiSettingsPreference.setSummary(getString(wifiWakeupEnabled
+                    ? R.string.wifi_configure_settings_preference_summary_wakeup_on
+                    : R.string.wifi_configure_settings_preference_summary_wakeup_off));
+        }
         int numSavedNetworks = mWifiTracker.getNumSavedNetworks();
         if (numSavedNetworks > 0) {
             mAdditionalSettingsPreferenceCategory.addPreference(mSavedNetworksPreference);
diff --git a/src/com/android/settings/wifi/WifiWakeupPreferenceController.java b/src/com/android/settings/wifi/WifiWakeupPreferenceController.java
index 2c33fc5..9eea74a 100644
--- a/src/com/android/settings/wifi/WifiWakeupPreferenceController.java
+++ b/src/com/android/settings/wifi/WifiWakeupPreferenceController.java
@@ -70,7 +70,10 @@
 
     @Override
     public boolean isAvailable() {
-        return true;
+        final int defaultValue = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_wifi_wakeup_available);
+        return Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.WIFI_WAKEUP_AVAILABLE, defaultValue) == 1;
     }
 
     @Override
diff --git a/tests/robotests/src/com/android/settings/accounts/AccountPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accounts/AccountPreferenceControllerTest.java
index d2ded86..8453da5 100644
--- a/tests/robotests/src/com/android/settings/accounts/AccountPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accounts/AccountPreferenceControllerTest.java
@@ -27,6 +27,7 @@
 import android.support.v7.preference.PreferenceManager;
 import android.support.v7.preference.PreferenceScreen;
 
+import android.text.TextUtils;
 import com.android.settings.AccessiblePreferenceCategory;
 import com.android.settings.R;
 import com.android.settings.SettingsPreferenceFragment;
@@ -39,6 +40,7 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentMatcher;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.robolectric.annotation.Config;
@@ -51,20 +53,22 @@
 import static org.mockito.Answers.RETURNS_DEEP_STUBS;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.argThat;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 @RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
+        shadows = {ShadowAccountManager.class, ShadowContentResolver.class})
 public class AccountPreferenceControllerTest {
 
     @Mock(answer = RETURNS_DEEP_STUBS)
     private PreferenceScreen mScreen;
-
     @Mock(answer = RETURNS_DEEP_STUBS)
     private UserManager mUserManager;
     @Mock(answer = RETURNS_DEEP_STUBS)
@@ -145,43 +149,56 @@
 
     @Test
     @Config(shadows = {ShadowAccountManager.class, ShadowContentResolver.class})
-    public void onResume_oneProfiles_shouldRemoveOneAccountCategory() {
-        final List<UserInfo> infos = new ArrayList<>();
-        infos.add(new UserInfo(1, "user 1", UserInfo.FLAG_MANAGED_PROFILE));
-        when(mUserManager.isManagedProfile()).thenReturn(false);
-        when(mUserManager.isLinkedUser()).thenReturn(false);
-        when(mUserManager.getProfiles(anyInt())).thenReturn(infos);
-        AccessiblePreferenceCategory preferenceGroup = mock(AccessiblePreferenceCategory.class);
-        when(mAccountHelper.createAccessiblePreferenceCategory(any(Context.class))).thenReturn(
-            preferenceGroup);
-
-        // First time resume will build the UI, 2nd time will refresh the UI
-        mController.onResume();
-        mController.onResume();
-
-        verify(mScreen, times(1)).removePreference(any(PreferenceGroup.class));
-        verify(mScreen).removePreference(preferenceGroup);
-    }
-
-    @Test
-    @Config(shadows = {ShadowAccountManager.class, ShadowContentResolver.class})
-    public void onResume_twoProfiles_shouldRemoveTwoAccountCategory() {
+    public void onResume_noProfileChange_shouldNotAddOrRemoveAccountCategory() {
         final List<UserInfo> infos = new ArrayList<>();
         infos.add(new UserInfo(1, "user 1", 0));
         infos.add(new UserInfo(2, "user 2", UserInfo.FLAG_MANAGED_PROFILE));
         when(mUserManager.isManagedProfile()).thenReturn(false);
         when(mUserManager.isLinkedUser()).thenReturn(false);
         when(mUserManager.getProfiles(anyInt())).thenReturn(infos);
-        AccessiblePreferenceCategory preferenceGroup = mock(AccessiblePreferenceCategory.class);
-        when(mAccountHelper.createAccessiblePreferenceCategory(any(Context.class))).thenReturn(
-            preferenceGroup);
-
-        // First time resume will build the UI, 2nd time will refresh the UI
+        // First time resume will build the UI
         mController.onResume();
-        mController.onResume();
+        reset(mScreen);
 
-        verify(mScreen, times(2)).removePreference(any(PreferenceGroup.class));
-        verify(mScreen, times(2)).removePreference(preferenceGroup);
+        mController.onResume();
+        verify(mScreen, never()).addPreference(any(PreferenceGroup.class));
+        verify(mScreen, never()).removePreference(any(PreferenceGroup.class));
+    }
+
+    @Test
+    @Config(shadows = {ShadowAccountManager.class, ShadowContentResolver.class})
+    public void onResume_oneNewProfile_shouldAddOneAccountCategory() {
+        final List<UserInfo> infos = new ArrayList<>();
+        infos.add(new UserInfo(1, "user 1", 0));
+        when(mUserManager.isManagedProfile()).thenReturn(false);
+        when(mUserManager.isLinkedUser()).thenReturn(false);
+        when(mUserManager.getProfiles(anyInt())).thenReturn(infos);
+        // First time resume will build the UI
+        mController.onResume();
+        // add a new profile
+        infos.add(new UserInfo(2, "user 2", UserInfo.FLAG_MANAGED_PROFILE));
+        reset(mScreen);
+
+        mController.onResume();
+        verify(mScreen, times(1)).addPreference(any(PreferenceGroup.class));
+    }
+
+    @Test
+    @Config(shadows = {ShadowAccountManager.class, ShadowContentResolver.class})
+    public void onResume_oneProfileRemoved_shouldRemoveOneAccountCategory() {
+        final List<UserInfo> infos = new ArrayList<>();
+        infos.add(new UserInfo(1, "user 1", 0));
+        infos.add(new UserInfo(2, "user 2", UserInfo.FLAG_MANAGED_PROFILE));
+        when(mUserManager.isManagedProfile()).thenReturn(false);
+        when(mUserManager.isLinkedUser()).thenReturn(false);
+        when(mUserManager.getProfiles(anyInt())).thenReturn(infos);
+        // First time resume will build the UI
+        mController.onResume();
+        // remove a profile
+        infos.remove(1);
+
+        mController.onResume();
+        verify(mScreen, times(1)).removePreference(any(PreferenceGroup.class));
     }
 
     @Test
@@ -348,4 +365,144 @@
         verify(preferenceGroup, times(3)).addPreference(any(Preference.class));
     }
 
+    @Test
+    @Config(shadows = {ShadowAccountManager.class, ShadowContentResolver.class})
+    public void onResume_noAccountChange_shouldNotAddAccountPreference() {
+        final List<UserInfo> infos = new ArrayList<>();
+        infos.add(new UserInfo(1, "user 1", 0));
+        when(mUserManager.isManagedProfile()).thenReturn(false);
+        when(mUserManager.isLinkedUser()).thenReturn(false);
+        when(mUserManager.getProfiles(anyInt())).thenReturn(infos);
+        Account[] accounts = {new Account("Acct1", "com.acct1")};
+        when(mAccountManager.getAccountsAsUser(anyInt())).thenReturn(accounts);
+
+        Account[] accountType1 = new Account[2];
+        accountType1[0] = new Account("Acct11", "com.acct1");
+        accountType1[1] = new Account("Acct12", "com.acct1");
+        when(mAccountManager.getAccountsByTypeAsUser(eq("com.acct1"), any(UserHandle.class)))
+            .thenReturn(accountType1);
+
+        AuthenticatorDescription[] authDescs = {
+            new AuthenticatorDescription("com.acct1", "com.android.settings",
+                R.string.account_settings_title, 0, 0, 0, false)
+        };
+        when(mAccountManager.getAuthenticatorTypesAsUser(anyInt())).thenReturn(authDescs);
+
+        AccessiblePreferenceCategory preferenceGroup = mock(AccessiblePreferenceCategory.class);
+        when(preferenceGroup.getPreferenceManager()).thenReturn(mock(PreferenceManager.class));
+        when(mAccountHelper.createAccessiblePreferenceCategory(any(Context.class))).thenReturn(
+            preferenceGroup);
+        mController.onResume();
+
+        mController.onResume();
+
+        // each account should be added only once
+        verify(preferenceGroup).addPreference(argThat(new PreferenceMatcher("Acct11")));
+        verify(preferenceGroup).addPreference(argThat(new PreferenceMatcher("Acct12")));
+    }
+
+    @Test
+    public void onResume_oneNewAccount_shouldAddOneAccountPreference() {
+        final List<UserInfo> infos = new ArrayList<>();
+        infos.add(new UserInfo(1, "user 1", 0));
+        when(mUserManager.isManagedProfile()).thenReturn(false);
+        when(mUserManager.isLinkedUser()).thenReturn(false);
+        when(mUserManager.getProfiles(anyInt())).thenReturn(infos);
+        Account[] accounts = {new Account("Acct1", "com.acct1")};
+        when(mAccountManager.getAccountsAsUser(anyInt())).thenReturn(accounts);
+
+        Account[] accountType1 = new Account[2];
+        accountType1[0] = new Account("Acct11", "com.acct1");
+        accountType1[1] = new Account("Acct12", "com.acct1");
+        when(mAccountManager.getAccountsByTypeAsUser(eq("com.acct1"), any(UserHandle.class)))
+            .thenReturn(accountType1);
+
+        AuthenticatorDescription[] authDescs = {
+            new AuthenticatorDescription("com.acct1", "com.android.settings",
+                R.string.account_settings_title, 0, 0, 0, false)
+        };
+        when(mAccountManager.getAuthenticatorTypesAsUser(anyInt())).thenReturn(authDescs);
+
+        AccessiblePreferenceCategory preferenceGroup = mock(AccessiblePreferenceCategory.class);
+        when(preferenceGroup.getPreferenceManager()).thenReturn(mock(PreferenceManager.class));
+        when(mAccountHelper.createAccessiblePreferenceCategory(any(Context.class))).thenReturn(
+            preferenceGroup);
+
+        mController.onResume();
+
+        // add a new account
+        accountType1 = new Account[3];
+        accountType1[0] = new Account("Acct11", "com.acct1");
+        accountType1[1] = new Account("Acct12", "com.acct1");
+        accountType1[2] = new Account("Acct13", "com.acct1");
+        when(mAccountManager.getAccountsByTypeAsUser(eq("com.acct1"), any(UserHandle.class)))
+            .thenReturn(accountType1);
+
+        mController.onResume();
+
+        // each account should be added only once
+        verify(preferenceGroup, times(1)).addPreference(argThat(new PreferenceMatcher("Acct11")));
+        verify(preferenceGroup, times(1)).addPreference(argThat(new PreferenceMatcher("Acct12")));
+        verify(preferenceGroup, times(1)).addPreference(argThat(new PreferenceMatcher("Acct13")));
+    }
+
+    @Test
+    @Config(shadows = {ShadowAccountManager.class, ShadowContentResolver.class})
+    public void onResume_oneAccountRemoved_shouldRemoveOneAccountPreference() {
+        final List<UserInfo> infos = new ArrayList<>();
+        infos.add(new UserInfo(1, "user 1", 0));
+        when(mUserManager.isManagedProfile()).thenReturn(false);
+        when(mUserManager.isLinkedUser()).thenReturn(false);
+        when(mUserManager.getProfiles(anyInt())).thenReturn(infos);
+        Account[] accounts = {new Account("Acct1", "com.acct1")};
+        when(mAccountManager.getAccountsAsUser(anyInt())).thenReturn(accounts);
+
+        Account[] accountType1 = new Account[2];
+        accountType1[0] = new Account("Acct11", "com.acct1");
+        accountType1[1] = new Account("Acct12", "com.acct1");
+        when(mAccountManager.getAccountsByTypeAsUser(eq("com.acct1"), any(UserHandle.class)))
+            .thenReturn(accountType1);
+
+        AuthenticatorDescription[] authDescs = {
+            new AuthenticatorDescription("com.acct1", "com.android.settings",
+                R.string.account_settings_title, 0, 0, 0, false)
+        };
+        when(mAccountManager.getAuthenticatorTypesAsUser(anyInt())).thenReturn(authDescs);
+
+        AccessiblePreferenceCategory preferenceGroup = mock(AccessiblePreferenceCategory.class);
+        when(preferenceGroup.getPreferenceManager()).thenReturn(mock(PreferenceManager.class));
+        when(mAccountHelper.createAccessiblePreferenceCategory(any(Context.class))).thenReturn(
+            preferenceGroup);
+
+        mController.onResume();
+
+        // remove an account
+        accountType1 = new Account[1];
+        accountType1[0] = new Account("Acct11", "com.acct1");
+        when(mAccountManager.getAccountsByTypeAsUser(eq("com.acct1"), any(UserHandle.class)))
+            .thenReturn(accountType1);
+
+        mController.onResume();
+
+        verify(preferenceGroup, times(1)).addPreference(argThat(new PreferenceMatcher("Acct11")));
+        verify(preferenceGroup, times(1)).addPreference(argThat(new PreferenceMatcher("Acct12")));
+        verify(preferenceGroup, times(1)).removePreference(
+            argThat(new PreferenceMatcher("Acct12")));
+    }
+
+    private static class PreferenceMatcher extends ArgumentMatcher<Preference> {
+
+        private final String mExpectedTitle;
+
+        public PreferenceMatcher(String title) {
+            mExpectedTitle = title;
+        }
+
+        @Override
+        public boolean matches(Object arg) {
+            final Preference preference = (Preference) arg;
+            return TextUtils.equals(mExpectedTitle, preference.getTitle());
+        }
+    }
+
 }
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java b/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java
index d9934b1..69bd767 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java
@@ -17,6 +17,7 @@
 package com.android.settings.fuelgauge;
 
 import static com.google.common.truth.Truth.assertThat;
+
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.anyLong;
@@ -46,7 +47,9 @@
 import com.android.settings.applications.AppHeaderController;
 import com.android.settings.applications.LayoutPreference;
 import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settingslib.applications.AppUtils;
 import com.android.settingslib.applications.ApplicationsState;
+import com.android.settingslib.applications.instantapps.InstantAppDataProvider;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -58,7 +61,6 @@
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 import org.robolectric.RuntimeEnvironment;
-
 import org.robolectric.annotation.Config;
 import org.robolectric.util.ReflectionHelpers;
 
@@ -175,11 +177,37 @@
 
     @Test
     public void testInitHeader_HasAppEntry_BuildByAppEntry() {
+        ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
+                new InstantAppDataProvider() {
+                    @Override
+                    public boolean isInstantApp(ApplicationInfo info) {
+                        return false;
+                    }
+                });
         mFragment.mAppEntry = mAppEntry;
         mFragment.initHeader();
 
         verify(mAppHeaderController).setIcon(mAppEntry);
         verify(mAppHeaderController).setLabel(mAppEntry);
+        verify(mAppHeaderController).setIsInstantApp(false);
+    }
+
+    @Test
+    public void testInitHeader_HasAppEntry_InstantApp() {
+        ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
+                new InstantAppDataProvider() {
+                    @Override
+                    public boolean isInstantApp(ApplicationInfo info) {
+                        return true;
+                    }
+                });
+        mFragment.mAppEntry = mAppEntry;
+        mFragment.initHeader();
+
+        verify(mAppHeaderController).setIcon(mAppEntry);
+        verify(mAppHeaderController).setLabel(mAppEntry);
+        verify(mAppHeaderController).setIsInstantApp(true);
+        verify(mAppHeaderController).setSummary((CharSequence) null);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/search/IntentSearchViewHolderTest.java b/tests/robotests/src/com/android/settings/search/IntentSearchViewHolderTest.java
index cc7e4ec..51cd484 100644
--- a/tests/robotests/src/com/android/settings/search/IntentSearchViewHolderTest.java
+++ b/tests/robotests/src/com/android/settings/search/IntentSearchViewHolderTest.java
@@ -82,7 +82,7 @@
     }
 
     @Test
-    public void testConstructor_MembersNotNull() {
+    public void testConstructor_membersNotNull() {
         assertThat(mHolder.titleView).isNotNull();
         assertThat(mHolder.summaryView).isNotNull();
         assertThat(mHolder.iconView).isNotNull();
@@ -90,8 +90,8 @@
     }
 
     @Test
-    public void testBindViewElements_AllUpdated() {
-        SearchResult result = getSearchResult();
+    public void testBindViewElements_allUpdated() {
+        SearchResult result = getSearchResult(TITLE, SUMMARY, mIcon);
         mHolder.onBind(mFragment, result);
         mHolder.itemView.performClick();
 
@@ -110,6 +110,14 @@
     }
 
     @Test
+    public void testBindViewIcon_nullIcon_imageDrawableIsNull() {
+        final SearchResult result = getSearchResult(TITLE, SUMMARY, null);
+        mHolder.onBind(mFragment, result);
+
+        assertThat(mHolder.iconView.getDrawable()).isNull();
+    }
+
+    @Test
     public void testBindViewElements_emptySummary_hideSummaryView() {
         final SearchResult result = new Builder()
                 .addTitle(TITLE)
@@ -155,15 +163,15 @@
         assertThat(mHolder.summaryView.getVisibility()).isEqualTo(View.GONE);
     }
 
-    private SearchResult getSearchResult() {
+    private SearchResult getSearchResult(String title, String summary, Drawable icon) {
         Builder builder = new Builder();
-        builder.addTitle(TITLE)
-                .addSummary(SUMMARY)
+        builder.addTitle(title)
+                .addSummary(summary)
                 .addRank(1)
                 .addPayload(new IntentPayload(
                         new Intent().setComponent(new ComponentName("pkg", "class"))))
                 .addBreadcrumbs(new ArrayList<>())
-                .addIcon(mIcon);
+                .addIcon(icon);
 
         return builder.build();
     }
diff --git a/tests/robotests/src/com/android/settings/search2/DatabaseIndexingManagerTest.java b/tests/robotests/src/com/android/settings/search2/DatabaseIndexingManagerTest.java
index 0a8326d..b76feff1 100644
--- a/tests/robotests/src/com/android/settings/search2/DatabaseIndexingManagerTest.java
+++ b/tests/robotests/src/com/android/settings/search2/DatabaseIndexingManagerTest.java
@@ -99,6 +99,7 @@
     private final String screenTitle = "screen title";
     private final String className = "class name";
     private final int iconResId = 0xff;
+    private final int noIcon = 0;
     private final String action = "action";
     private final String targetPackage = "target package";
     private final String targetClass = "target class";
@@ -388,7 +389,7 @@
         // Class Name
         assertThat(cursor.getString(11)).isEqualTo(className);
         // Icon
-        assertThat(cursor.getInt(12)).isEqualTo(iconResId);
+        assertThat(cursor.getInt(12)).isEqualTo(noIcon);
         // Intent Action
         assertThat(cursor.getString(13)).isEqualTo(action);
         // Target Package
@@ -442,7 +443,7 @@
         // Class Name
         assertThat(cursor.getString(11)).isEqualTo(className);
         // Icon
-        assertThat(cursor.getInt(12)).isEqualTo(iconResId);
+        assertThat(cursor.getInt(12)).isEqualTo(noIcon);
         // Intent Action
         assertThat(cursor.getString(13)).isEqualTo(action);
         // Target Package
@@ -496,7 +497,7 @@
         // Class Name
         assertThat(cursor.getString(11)).isEqualTo(className);
         // Icon
-        assertThat(cursor.getInt(12)).isEqualTo(iconResId);
+        assertThat(cursor.getInt(12)).isEqualTo(noIcon);
         // Intent Action
         assertThat(cursor.getString(13)).isEqualTo(action);
         // Target Package
@@ -515,6 +516,18 @@
         assertThat(cursor.getBlob(20)).isNull();
     }
 
+    @Test
+    public void testAddResource_iconAddedFromXml() {
+        SearchIndexableResource resource = getFakeResource(R.xml.connected_devices);
+        mManager.indexOneSearchIndexableData(mDb, localeStr, resource, new HashMap<>());
+
+        Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index ORDER BY data_title", null);
+        cursor.moveToPosition(0);
+
+        // Icon
+        assertThat(cursor.getInt(12)).isNotEqualTo(noIcon);
+    }
+
     // Tests for the flow: IndexOneResource -> IndexFromProvider -> IndexFromResource ->
     //                     UpdateOneRowWithFilteredData -> UpdateOneRow
 
@@ -565,7 +578,7 @@
         assertThat(cursor.getString(11))
                 .isEqualTo("com.android.settings.display.ScreenZoomSettings");
         // Icon
-        assertThat(cursor.getInt(12)).isEqualTo(iconResId);
+        assertThat(cursor.getInt(12)).isEqualTo(noIcon);
         // Intent Action
         assertThat(cursor.getString(13)).isNull();
         // Target Package
@@ -630,7 +643,7 @@
         assertThat(cursor.getString(11))
                 .isEqualTo("com.android.settings.display.ScreenZoomSettings");
         // Icon
-        assertThat(cursor.getInt(12)).isEqualTo(iconResId);
+        assertThat(cursor.getInt(12)).isEqualTo(noIcon);
         // Intent Action
         assertThat(cursor.getString(13)).isNull();
         // Target Package
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/SettingsShadowResources.java b/tests/robotests/src/com/android/settings/testutils/shadow/SettingsShadowResources.java
index ba82835..565aff9 100644
--- a/tests/robotests/src/com/android/settings/testutils/shadow/SettingsShadowResources.java
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/SettingsShadowResources.java
@@ -127,6 +127,16 @@
                 realResources, Resources.class, "getString", ClassParameter.from(int.class, id));
     }
 
+    @Implementation
+    public int getInteger(int id) {
+        final Object override = sResourceOverrides.get(id);
+        if (override instanceof Integer) {
+            return (Integer) override;
+        }
+        return Shadow.directlyOn(
+                realResources, Resources.class, "getInteger", ClassParameter.from(int.class, id));
+    }
+
     @Implements(Theme.class)
     public static class SettingsShadowTheme extends ShadowTheme {
 
diff --git a/tests/robotests/src/com/android/settings/wifi/WifiWakeupPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/WifiWakeupPreferenceControllerTest.java
index 7df5c9a..61981c4 100644
--- a/tests/robotests/src/com/android/settings/wifi/WifiWakeupPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/WifiWakeupPreferenceControllerTest.java
@@ -18,10 +18,9 @@
 
 import static android.provider.Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED;
 import static android.provider.Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE;
+import static android.provider.Settings.Global.WIFI_WAKEUP_AVAILABLE;
 import static android.provider.Settings.Global.WIFI_WAKEUP_ENABLED;
-
 import static com.google.common.truth.Truth.assertThat;
-
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 
@@ -34,7 +33,9 @@
 import com.android.settings.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
 import com.android.settings.core.lifecycle.Lifecycle;
+import com.android.settings.testutils.shadow.SettingsShadowResources;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -43,7 +44,10 @@
 import org.robolectric.annotation.Config;
 
 @RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+@Config(
+        manifest = TestConfig.MANIFEST_PATH,
+        sdk = TestConfig.SDK_VERSION,
+        shadows = { SettingsShadowResources.class })
 public class WifiWakeupPreferenceControllerTest {
 
     private Context mContext;
@@ -55,10 +59,24 @@
         mContext = RuntimeEnvironment.application;
         mController = new WifiWakeupPreferenceController(mContext, mock(Lifecycle.class));
         Settings.System.putInt(mContext.getContentResolver(), WIFI_SCAN_ALWAYS_AVAILABLE, 1);
+        SettingsShadowResources.overrideResource(
+                com.android.internal.R.integer.config_wifi_wakeup_available, 0);
+    }
+
+    @After
+    public void tearDown() {
+        SettingsShadowResources.reset();
     }
 
     @Test
-    public void testIsAvailable_shouldAlwaysReturnTrue() {
+    public void testIsAvailable_returnsFalseWhenSettingIsNotAvailable() {
+        Settings.System.putInt(mContext.getContentResolver(), WIFI_WAKEUP_AVAILABLE, 0);
+        assertThat(mController.isAvailable()).isFalse();
+    }
+
+    @Test
+    public void testIsAvailable_returnsTrueWhenSettingIsAvailable() {
+        Settings.System.putInt(mContext.getContentResolver(), WIFI_WAKEUP_AVAILABLE, 1);
         assertThat(mController.isAvailable()).isTrue();
     }