Merge "Consistent "low storage" behavior." into oc-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index b9c0f9f..c596152 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -81,6 +81,7 @@
     <uses-permission android:name="android.permission.PEERS_MAC_ADDRESS"/>
     <uses-permission android:name="android.permission.MANAGE_NOTIFICATIONS"/>
     <uses-permission android:name="android.permission.DELETE_PACKAGES"/>
+    <uses-permission android:name="android.permission.MANAGE_APP_OPS_RESTRICTIONS"/>
 
     <application android:label="@string/settings_label"
             android:icon="@drawable/ic_launcher_settings"
diff --git a/res/layout/wifi_network_details_two_buttons_panel.xml b/res/layout/wifi_network_details_two_buttons_panel.xml
new file mode 100644
index 0000000..6abfac3
--- /dev/null
+++ b/res/layout/wifi_network_details_two_buttons_panel.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<!--
+  Defines a panel with two buttons and a spacer in between.
+  The right button uses the Material.Button.Colored style.
+-->
+
+<LinearLayout
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:gravity="bottom"
+        android:paddingTop="4dip"
+        android:orientation="horizontal">
+        <Button
+            android:id="@+id/forget_button"
+            android:layout_width="120dip"
+            android:layout_weight="0.4"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_vertical"/>
+        <!-- Spacer -->
+        <View
+            android:id="@+id/buttons_spacer_left"
+            android:layout_width="0dip"
+            android:layout_height="wrap_content"
+            android:visibility="invisible"
+            android:layout_weight="0.2" />
+        <Button
+            style="@android:style/Widget.Material.Button.Colored"
+            android:id="@+id/signin_button"
+            android:layout_width="120dip"
+            android:text="@string/cancel"
+            android:layout_weight="0.4"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_vertical"/>
+</LinearLayout>
diff --git a/res/xml/wifi_network_details_fragment.xml b/res/xml/wifi_network_details_fragment.xml
index 5d5958d..fafbbb0 100644
--- a/res/xml/wifi_network_details_fragment.xml
+++ b/res/xml/wifi_network_details_fragment.xml
@@ -29,7 +29,7 @@
         <!-- Buttons -->
         <com.android.settings.applications.LayoutPreference
             android:key="buttons"
-            android:layout="@layout/two_buttons_panel"
+            android:layout="@layout/wifi_network_details_two_buttons_panel"
             android:selectable="false" />
 
         <com.android.settings.wifi.WifiDetailPreference
diff --git a/src/com/android/settings/DeviceAdminAdd.java b/src/com/android/settings/DeviceAdminAdd.java
index fb2f29f..5978f5e 100644
--- a/src/com/android/settings/DeviceAdminAdd.java
+++ b/src/com/android/settings/DeviceAdminAdd.java
@@ -40,6 +40,7 @@
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Handler;
+import android.os.IBinder;
 import android.os.RemoteCallback;
 import android.os.RemoteException;
 import android.os.UserHandle;
@@ -90,6 +91,7 @@
     public static final String EXTRA_CALLED_FROM_SUPPORT_DIALOG =
             "android.app.extra.CALLED_FROM_SUPPORT_DIALOG";
 
+    private final IBinder mToken = new Binder();
     Handler mHandler;
 
     DevicePolicyManager mDPM;
@@ -118,8 +120,6 @@
     boolean mWaitingForRemoveMsg;
     boolean mAddingProfileOwner;
     boolean mAdminPoliciesInitialized;
-    int mCurSysAppOpMode;
-    int mCurToastAppOpMode;
 
     boolean mIsCalledFromSupportDialog = false;
 
@@ -352,6 +352,9 @@
         restrictedAction.setFilterTouchesWhenObscured(true);
         restrictedAction.setOnClickListener(new View.OnClickListener() {
             public void onClick(View v) {
+                if (!mActionButton.isEnabled()) {
+                    return;
+                }
                 if (mAdding) {
                     addAndFinish();
                 } else if (isManagedProfile(mDeviceAdmin)
@@ -473,24 +476,21 @@
     @Override
     protected void onResume() {
         super.onResume();
+        mActionButton.setEnabled(true);
         updateInterface();
-        // As long as we are running, don't let this admin overlay stuff on top of the screen.
-        final int uid = mDeviceAdmin.getActivityInfo().applicationInfo.uid;
-        final String pkg = mDeviceAdmin.getActivityInfo().applicationInfo.packageName;
-        mCurSysAppOpMode = mAppOps.checkOp(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, uid, pkg);
-        mCurToastAppOpMode = mAppOps.checkOp(AppOpsManager.OP_TOAST_WINDOW, uid, pkg);
-        mAppOps.setMode(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, uid, pkg, AppOpsManager.MODE_IGNORED);
-        mAppOps.setMode(AppOpsManager.OP_TOAST_WINDOW, uid, pkg, AppOpsManager.MODE_IGNORED);
+        // As long as we are running, don't let anyone overlay stuff on top of the screen.
+        mAppOps.setUserRestriction(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, true, mToken);
+        mAppOps.setUserRestriction(AppOpsManager.OP_TOAST_WINDOW, true, mToken);
+
     }
 
     @Override
     protected void onPause() {
         super.onPause();
-        // As long as we are running, don't let this admin overlay stuff on top of the screen.
-        final int uid = mDeviceAdmin.getActivityInfo().applicationInfo.uid;
-        final String pkg = mDeviceAdmin.getActivityInfo().applicationInfo.packageName;
-        mAppOps.setMode(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, uid, pkg, mCurSysAppOpMode);
-        mAppOps.setMode(AppOpsManager.OP_TOAST_WINDOW, uid, pkg, mCurToastAppOpMode);
+        // This just greys out the button. The actual listener is attached to R.id.restricted_action
+        mActionButton.setEnabled(false);
+        mAppOps.setUserRestriction(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, false, mToken);
+        mAppOps.setUserRestriction(AppOpsManager.OP_TOAST_WINDOW, false, mToken);
         try {
             ActivityManager.getService().resumeAppSwitches();
         } catch (RemoteException e) {
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index 0142ea2..9655fd2 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -25,6 +25,7 @@
 import android.app.ActivityManager;
 import android.app.AlertDialog;
 import android.app.AppGlobals;
+import android.app.AppOpsManager;
 import android.app.Dialog;
 import android.app.Fragment;
 import android.app.IActivityManager;
@@ -1272,6 +1273,22 @@
         return info.enabled ? R.string.installed : R.string.disabled;
     }
 
+    /**
+     * Control if other apps can display overlays. By default this is allowed. Be sure to
+     * re-enable overlays, as the effect is system-wide.
+     */
+    public static void setOverlayAllowed(Context context, IBinder token, boolean allowed) {
+        AppOpsManager appOpsManager = context.getSystemService(AppOpsManager.class);
+        if (appOpsManager != null) {
+            appOpsManager.setUserRestriction(AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
+                    !allowed, token);
+            appOpsManager.setUserRestriction(AppOpsManager.OP_TOAST_WINDOW,
+                    !allowed, token);
+        }
+    }
+
+
+
     private static boolean isVolumeValid(VolumeInfo volume) {
         return (volume != null) && (volume.getType() == VolumeInfo.TYPE_PRIVATE)
                 && volume.isMountedReadable();
diff --git a/src/com/android/settings/accessibility/AccessibilityServiceWarning.java b/src/com/android/settings/accessibility/AccessibilityServiceWarning.java
index e0c58db..e0d2c69 100644
--- a/src/com/android/settings/accessibility/AccessibilityServiceWarning.java
+++ b/src/com/android/settings/accessibility/AccessibilityServiceWarning.java
@@ -48,14 +48,14 @@
                 .setTitle(parentActivity.getString(R.string.enable_service_title,
                         getServiceName(parentActivity, info)))
                 .setView(createEnableDialogContentView(parentActivity, info))
-                .setCancelable(true)
                 .setPositiveButton(android.R.string.ok, listener)
                 .setNegativeButton(android.R.string.cancel, listener)
                 .create();
 
         final View.OnTouchListener filterTouchListener = (View v, MotionEvent event) -> {
             // Filter obscured touches by consuming them.
-            if ((event.getFlags() & MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCURED) != 0) {
+            if (((event.getFlags() & MotionEvent.FLAG_WINDOW_IS_OBSCURED) != 0)
+                || ((event.getFlags() & MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCURED) != 0)) {
                 if (event.getAction() == MotionEvent.ACTION_UP) {
                     Toast.makeText(v.getContext(), R.string.touch_filtered_warning,
                             Toast.LENGTH_SHORT).show();
@@ -67,6 +67,8 @@
 
         ad.create();
         ad.getButton(AlertDialog.BUTTON_POSITIVE).setOnTouchListener(filterTouchListener);
+        ad.setCanceledOnTouchOutside(true);
+
         return ad;
     }
 
diff --git a/src/com/android/settings/accessibility/ShortcutServicePickerFragment.java b/src/com/android/settings/accessibility/ShortcutServicePickerFragment.java
index d7749ea..38e6b0f 100644
--- a/src/com/android/settings/accessibility/ShortcutServicePickerFragment.java
+++ b/src/com/android/settings/accessibility/ShortcutServicePickerFragment.java
@@ -17,25 +17,24 @@
 
 import static android.content.DialogInterface.BUTTON_POSITIVE;
 
+import static com.android.settings.Utils.setOverlayAllowed;
+
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.app.Activity;
-import android.app.AlertDialog;
 import android.app.Dialog;
 import android.app.DialogFragment;
 import android.app.Fragment;
 import android.content.ComponentName;
 import android.content.DialogInterface;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageParser;
+import android.os.Binder;
 import android.os.Bundle;
+import android.os.IBinder;
 import android.os.UserHandle;
 import android.provider.Settings;
-import android.support.v7.preference.Preference;
 import android.text.TextUtils;
 import android.view.accessibility.AccessibilityManager;
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.settings.DialogCreatable;
 import com.android.settings.applications.defaultapps.DefaultAppInfo;
 import com.android.settings.applications.defaultapps.DefaultAppPickerFragment;
 import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
@@ -118,6 +117,7 @@
             implements DialogInterface.OnClickListener {
         private static final String EXTRA_KEY = "extra_key";
         private static final String TAG = "ConfirmationDialogFragment";
+        private IBinder mToken;
 
         public static ConfirmationDialogFragment newInstance(ShortcutServicePickerFragment parent,
                 String key) {
@@ -126,6 +126,7 @@
             argument.putString(EXTRA_KEY, key);
             fragment.setArguments(argument);
             fragment.setTargetFragment(parent, 0);
+            fragment.mToken = new Binder();
             return fragment;
         }
 
@@ -147,6 +148,22 @@
         }
 
         @Override
+        public void onResume() {
+            super.onResume();
+            if (mToken != null) {
+                setOverlayAllowed(getActivity(), mToken, false);
+            }
+        }
+
+        @Override
+        public void onPause() {
+            super.onPause();
+            if (mToken != null) {
+                setOverlayAllowed(getActivity(), mToken, true);
+            }
+        }
+
+        @Override
         public void onClick(DialogInterface dialog, int which) {
             final Fragment fragment = getTargetFragment();
             if ((which == BUTTON_POSITIVE) && (fragment instanceof DefaultAppPickerFragment)) {
diff --git a/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
index 9c01a5f..da4bdcf 100644
--- a/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
@@ -16,34 +16,30 @@
 
 package com.android.settings.accessibility;
 
+import static com.android.settings.Utils.setOverlayAllowed;
+
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.Dialog;
 import android.app.admin.DevicePolicyManager;
 import android.content.ComponentName;
-import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.pm.ResolveInfo;
 import android.net.Uri;
+import android.os.Binder;
 import android.os.Bundle;
 import android.os.Handler;
+import android.os.IBinder;
 import android.os.UserHandle;
 import android.os.storage.StorageManager;
 import android.provider.Settings;
 import android.text.TextUtils;
-import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
-import android.view.MotionEvent;
-import android.view.View;
 import android.view.accessibility.AccessibilityManager;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-import android.widget.Toast;
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.widget.LockPatternUtils;
@@ -77,6 +73,8 @@
 
     private int mShownDialogId;
 
+    private final IBinder mToken = new Binder();
+
     @Override
     public int getMetricsCategory() {
         return MetricsEvent.ACCESSIBILITY_SERVICE;
@@ -107,12 +105,18 @@
     public void onResume() {
         mSettingsContentObserver.register(getContentResolver());
         updateSwitchBarToggleSwitch();
+        if (mToken != null) {
+            setOverlayAllowed(getActivity(), mToken, false);
+        }
         super.onResume();
     }
 
     @Override
     public void onPause() {
         mSettingsContentObserver.unregister(getContentResolver());
+        if (mToken != null) {
+            setOverlayAllowed(getActivity(), mToken, true);
+        }
         super.onPause();
     }
 
diff --git a/src/com/android/settings/applications/defaultapps/DefaultHomePicker.java b/src/com/android/settings/applications/defaultapps/DefaultHomePicker.java
index 038267b..dca7ad1 100644
--- a/src/com/android/settings/applications/defaultapps/DefaultHomePicker.java
+++ b/src/com/android/settings/applications/defaultapps/DefaultHomePicker.java
@@ -63,13 +63,15 @@
             }
 
             final String summary;
+            boolean enabled = true;
             if (mustSupportManagedProfile && !launcherHasManagedProfilesFeature(resolveInfo)) {
                 summary = getContext().getString(R.string.home_work_profile_not_supported);
+                enabled = false;
             } else {
                 summary = null;
             }
             final DefaultAppInfo candidate =
-                    new DefaultAppInfo(mPm, mUserId, activityName, summary);
+                    new DefaultAppInfo(mPm, mUserId, activityName, summary, enabled);
             candidates.add(candidate);
         }
         return candidates;
diff --git a/src/com/android/settings/widget/SettingsAppWidgetProvider.java b/src/com/android/settings/widget/SettingsAppWidgetProvider.java
index 38fed94..7dacaf5 100644
--- a/src/com/android/settings/widget/SettingsAppWidgetProvider.java
+++ b/src/com/android/settings/widget/SettingsAppWidgetProvider.java
@@ -395,7 +395,10 @@
                     int wifiApState = wifiManager.getWifiApState();
                     if (desiredState && ((wifiApState == WifiManager.WIFI_AP_STATE_ENABLING) ||
                                          (wifiApState == WifiManager.WIFI_AP_STATE_ENABLED))) {
-                        wifiManager.setWifiApEnabled(null, false);
+                        final ConnectivityManager connectivityManager =
+                                (ConnectivityManager) context.getSystemService(
+                                        Context.CONNECTIVITY_SERVICE);
+                        connectivityManager.stopTethering(ConnectivityManager.TETHERING_WIFI);
                     }
 
                     wifiManager.setWifiEnabled(desiredState);
diff --git a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
index a5d922d..b3f83b3 100644
--- a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
+++ b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
@@ -224,7 +224,7 @@
         mConnectionDetailPref = screen.findPreference(KEY_CONNECTION_DETAIL_PREF);
 
         mButtonsPref = (LayoutPreference) screen.findPreference(KEY_BUTTONS_PREF);
-        mSignInButton = (Button) mButtonsPref.findViewById(R.id.right_button);
+        mSignInButton = (Button) mButtonsPref.findViewById(R.id.signin_button);
         mSignInButton.setText(R.string.support_sign_in_button_text);
         mSignInButton.setOnClickListener(
             view -> mConnectivityManagerWrapper.startCaptivePortalApp(mNetwork));
@@ -245,7 +245,7 @@
                 (PreferenceCategory) screen.findPreference(KEY_IPV6_ADDRESS_CATEGORY);
 
         mSecurityPref.setDetailText(mAccessPoint.getSecurityString(false /* concise */));
-        mForgetButton = (Button) mButtonsPref.findViewById(R.id.left_button);
+        mForgetButton = (Button) mButtonsPref.findViewById(R.id.forget_button);
         mForgetButton.setText(R.string.forget);
         mForgetButton.setOnClickListener(view -> forgetNetwork());
         updateInfo();
diff --git a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultHomePickerTest.java b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultHomePickerTest.java
index 38104a9..f425d2f 100644
--- a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultHomePickerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultHomePickerTest.java
@@ -16,11 +16,17 @@
 
 package com.android.settings.applications.defaultapps;
 
-
 import android.app.Activity;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.IntentFilter;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.ResolveInfo;
+import android.content.pm.UserInfo;
+import android.os.Build;
 import android.os.UserManager;
 
 import com.android.settings.SettingsRobolectricTestRunner;
@@ -33,14 +39,22 @@
 import org.mockito.Answers;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
 import org.robolectric.util.ReflectionHelpers;
 
+import java.util.ArrayList;
+import java.util.List;
+
 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.anyList;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -55,7 +69,9 @@
     @Mock
     private UserManager mUserManager;
     @Mock
-    private PackageManagerWrapper mPackageManager;
+    private PackageManagerWrapper mPackageManagerWrapper;
+    @Mock
+    private PackageManager mPackageManager;
 
     private DefaultHomePicker mPicker;
 
@@ -63,28 +79,89 @@
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         when(mActivity.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
+        when(mPackageManagerWrapper.getPackageManager()).thenReturn(mPackageManager);
 
-        mPicker = new DefaultHomePicker();
+        mPicker = spy(new DefaultHomePicker());
         mPicker.onAttach((Context) mActivity);
 
-        ReflectionHelpers.setField(mPicker, "mPm", mPackageManager);
+        ReflectionHelpers.setField(mPicker, "mPm", mPackageManagerWrapper);
+        doReturn(RuntimeEnvironment.application).when(mPicker).getContext();
     }
 
     @Test
     public void setDefaultAppKey_shouldUpdateDefault() {
         assertThat(mPicker.setDefaultKey(TEST_APP_KEY)).isTrue();
 
-        verify(mPackageManager).replacePreferredActivity(any(IntentFilter.class),
+        verify(mPackageManagerWrapper).replacePreferredActivity(any(IntentFilter.class),
                 anyInt(), any(ComponentName[].class), any(ComponentName.class));
     }
 
     @Test
     public void getDefaultAppKey_shouldReturnDefault() {
         final ComponentName cn = mock(ComponentName.class);
-        when(mPackageManager.getHomeActivities(anyList()))
+        when(mPackageManagerWrapper.getHomeActivities(anyList()))
                 .thenReturn(cn);
         mPicker.getDefaultKey();
         verify(cn).flattenToString();
     }
 
+    @Test
+    public void getCandidates_allLaunchersAvailableIfNoManagedProfile()
+            throws NameNotFoundException {
+        addLaunchers();
+        List<DefaultAppInfo> candidates = mPicker.getCandidates();
+        assertThat(candidates.size()).isEqualTo(2);
+        assertThat(candidates.get(0).summary).isNull();
+        assertThat(candidates.get(0).enabled).isTrue();
+        assertThat(candidates.get(1).summary).isNull();
+        assertThat(candidates.get(1).enabled).isTrue();
+    }
+
+    @Test
+    public void getCandidates_onlyLollipopPlusLaunchersAvailableIfManagedProfile()
+            throws NameNotFoundException {
+        createManagedProfile();
+        addLaunchers();
+        List<DefaultAppInfo> candidates = mPicker.getCandidates();
+        assertThat(candidates.size()).isEqualTo(2);
+        DefaultAppInfo lollipopPlusLauncher = candidates.get(0);
+        assertThat(lollipopPlusLauncher.summary).isNull();
+        assertThat(lollipopPlusLauncher.enabled).isTrue();
+
+        DefaultAppInfo preLollipopLauncher = candidates.get(1);
+        assertThat(preLollipopLauncher.summary).isNotNull();
+        assertThat(preLollipopLauncher.enabled).isFalse();
+    }
+
+    private void createManagedProfile() {
+        ArrayList<UserInfo> profiles = new ArrayList<UserInfo>();
+        profiles.add(new UserInfo(/*id=*/ 10, "TestUserName", UserInfo.FLAG_MANAGED_PROFILE));
+        when(mUserManager.getProfiles(anyInt())).thenReturn(profiles);
+    }
+
+    private ResolveInfo createLauncher(
+            String packageName, String className, int targetSdk) throws NameNotFoundException {
+        ResolveInfo launcher = new ResolveInfo();
+        launcher.activityInfo = new ActivityInfo();
+        launcher.activityInfo.packageName = packageName;
+        launcher.activityInfo.name = className;
+        ApplicationInfo launcherAppInfo = new ApplicationInfo();
+        launcherAppInfo.targetSdkVersion = targetSdk;
+        when(mPackageManager.getApplicationInfo(eq(launcher.activityInfo.packageName), anyInt()))
+                .thenReturn(launcherAppInfo);
+        return launcher;
+    }
+
+    private void addLaunchers() throws NameNotFoundException {
+        doAnswer(invocation -> {
+                // The result of this method is stored in the first parameter...
+                List<ResolveInfo> parameter = (List<ResolveInfo>) invocation.getArguments()[0];
+                parameter.add(createLauncher(
+                        "package.1", "LollipopPlusLauncher", Build.VERSION_CODES.LOLLIPOP));
+                parameter.add(createLauncher(
+                        "package.2", "PreLollipopLauncher", Build.VERSION_CODES.KITKAT));
+                return null;
+                })
+                .when(mPackageManagerWrapper).getHomeActivities(anyList());
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java
index 208c157..0298195 100644
--- a/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java
@@ -195,9 +195,9 @@
                 .thenReturn(mockConnectionDetailPref);
         when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_BUTTONS_PREF))
                 .thenReturn(mockButtonsPref);
-        when(mockButtonsPref.findViewById(R.id.left_button))
+        when(mockButtonsPref.findViewById(R.id.forget_button))
                 .thenReturn(mockForgetButton);
-        when(mockButtonsPref.findViewById(R.id.right_button))
+        when(mockButtonsPref.findViewById(R.id.signin_button))
                 .thenReturn(mockSignInButton);
         when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_SIGNAL_STRENGTH_PREF))
                 .thenReturn(mockSignalStrengthPref);