Merge "Show confirmation dialog when user tries to skip fingerprint" into oc-mr1-dev
diff --git a/src/com/android/settings/MasterClear.java b/src/com/android/settings/MasterClear.java
index 96ce17e..2c97018 100644
--- a/src/com/android/settings/MasterClear.java
+++ b/src/com/android/settings/MasterClear.java
@@ -144,10 +144,10 @@
         public void onClick(View view) {
             final Context context = view.getContext();
             if (Utils.isDemoUser(context)) {
-                final String packageName = Utils.getDemoModePackageName(context);
-                if (!TextUtils.isEmpty(packageName)) {
+                final ComponentName componentName = Utils.getDeviceOwnerComponent(context);
+                if (componentName != null) {
                     final Intent requestFactoryReset = new Intent()
-                            .setPackage(packageName)
+                            .setPackage(componentName.getPackageName())
                             .setAction(Intent.ACTION_FACTORY_RESET);
                     context.startActivity(requestFactoryReset);
                 }
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index cfddf56..2a57577 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -1249,8 +1249,10 @@
         return UserManager.isDeviceInDemoMode(context) && getUserManager(context).isDemoUser();
     }
 
-    public static String getDemoModePackageName(Context context) {
-        return context.getString(com.android.internal.R.string.config_demoModePackage);
+    public static ComponentName getDeviceOwnerComponent(Context context) {
+        final DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(
+                Context.DEVICE_POLICY_SERVICE);
+        return dpm.getDeviceOwnerComponentOnAnyUser();
     }
 
     /**
diff --git a/src/com/android/settings/datausage/AppDataUsage.java b/src/com/android/settings/datausage/AppDataUsage.java
index 67e83ee..36d9d0f 100644
--- a/src/com/android/settings/datausage/AppDataUsage.java
+++ b/src/com/android/settings/datausage/AppDataUsage.java
@@ -32,6 +32,7 @@
 import android.os.Bundle;
 import android.os.RemoteException;
 import android.os.UserHandle;
+import android.support.annotation.VisibleForTesting;
 import android.support.v14.preference.SwitchPreference;
 import android.support.v7.preference.Preference;
 import android.support.v7.preference.PreferenceCategory;
@@ -41,6 +42,7 @@
 import android.util.Log;
 import android.view.View;
 import android.widget.AdapterView;
+
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
 import com.android.settings.applications.AppInfoBase;
@@ -234,6 +236,7 @@
     public boolean onPreferenceChange(Preference preference, Object newValue) {
         if (preference == mRestrictBackground) {
             mDataSaverBackend.setIsBlacklisted(mAppItem.key, mPackageName, !(Boolean) newValue);
+            updatePrefs();
             return true;
         } else if (preference == mUnrestrictedData) {
             mDataSaverBackend.setIsWhitelisted(mAppItem.key, mPackageName, (Boolean) newValue);
@@ -253,7 +256,8 @@
         return super.onPreferenceTreeClick(preference);
     }
 
-    private void updatePrefs() {
+    @VisibleForTesting
+    void updatePrefs() {
         updatePrefs(getAppRestrictBackground(), getUnrestrictData());
     }
 
diff --git a/src/com/android/settings/datausage/DataSaverBackend.java b/src/com/android/settings/datausage/DataSaverBackend.java
index 7c291c6..f37a3c3 100644
--- a/src/com/android/settings/datausage/DataSaverBackend.java
+++ b/src/com/android/settings/datausage/DataSaverBackend.java
@@ -18,6 +18,7 @@
 import android.net.INetworkPolicyListener;
 import android.net.NetworkPolicyManager;
 import android.os.Handler;
+import android.os.Looper;
 import android.os.RemoteException;
 import android.util.SparseIntArray;
 
@@ -38,7 +39,7 @@
     private final Context mContext;
     private final MetricsFeatureProvider mMetricsFeatureProvider;
 
-    private final Handler mHandler = new Handler();
+    private final Handler mHandler = new Handler(Looper.getMainLooper());
     private final NetworkPolicyManager mPolicyManager;
     private final ArrayList<Listener> mListeners = new ArrayList<>();
     private SparseIntArray mUidPolicies = new SparseIntArray();
@@ -194,12 +195,7 @@
 
         @Override
         public void onUidPoliciesChanged(final int uid, final int uidPolicies) {
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    handleUidPoliciesChanged(uid, uidPolicies);
-                }
-            });
+            mHandler.post(() -> handleUidPoliciesChanged(uid, uidPolicies));
         }
 
         @Override
@@ -208,12 +204,7 @@
 
         @Override
         public void onRestrictBackgroundChanged(final boolean isDataSaving) throws RemoteException {
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    handleRestrictBackgroundChanged(isDataSaving);
-                }
-            });
+            mHandler.post(() -> handleRestrictBackgroundChanged(isDataSaving));
         }
     };
 
diff --git a/src/com/android/settings/password/ConfirmDeviceCredentialBaseActivity.java b/src/com/android/settings/password/ConfirmDeviceCredentialBaseActivity.java
index 2b2b38f..d2bd934 100644
--- a/src/com/android/settings/password/ConfirmDeviceCredentialBaseActivity.java
+++ b/src/com/android/settings/password/ConfirmDeviceCredentialBaseActivity.java
@@ -68,7 +68,7 @@
             LinearLayout layout = (LinearLayout) findViewById(R.id.content_parent);
             layout.setFitsSystemWindows(false);
         }
-
+        getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
         mIsKeyguardLocked = savedState == null
                 ? getSystemService(KeyguardManager.class).isKeyguardLocked()
                 : savedState.getBoolean(STATE_IS_KEYGUARD_LOCKED, false);
diff --git a/src/com/android/settings/search/DatabaseResultLoader.java b/src/com/android/settings/search/DatabaseResultLoader.java
index 73b383b..7815a45 100644
--- a/src/com/android/settings/search/DatabaseResultLoader.java
+++ b/src/com/android/settings/search/DatabaseResultLoader.java
@@ -17,6 +17,9 @@
 
 package com.android.settings.search;
 
+import static com.android.settings.search.IndexDatabaseHelper.IndexColumns;
+import static com.android.settings.search.IndexDatabaseHelper.Tables.TABLE_PREFS_INDEX;
+
 import android.content.Context;
 import android.database.Cursor;
 import android.database.sqlite.SQLiteDatabase;
@@ -28,9 +31,6 @@
 import java.util.HashSet;
 import java.util.Set;
 
-import static com.android.settings.search.IndexDatabaseHelper.IndexColumns;
-import static com.android.settings.search.IndexDatabaseHelper.Tables.TABLE_PREFS_INDEX;
-
 /**
  * AsyncTask to retrieve Settings, First party app and any intent based results.
  */
@@ -191,10 +191,12 @@
      * @return A set of the matching results.
      */
     private Set<SearchResult> query(String whereClause, String[] selection, int baseRank) {
-        SQLiteDatabase database = IndexDatabaseHelper.getInstance(mContext).getReadableDatabase();
-        final Cursor resultCursor = database.query(TABLE_PREFS_INDEX, SELECT_COLUMNS, whereClause,
-                selection, null, null, null);
-        return mConverter.convertCursor(mSiteMapManager, resultCursor, baseRank);
+        final SQLiteDatabase database =
+                IndexDatabaseHelper.getInstance(mContext).getReadableDatabase();
+        try (Cursor resultCursor = database.query(TABLE_PREFS_INDEX, SELECT_COLUMNS, whereClause,
+                selection, null, null, null)) {
+            return mConverter.convertCursor(mSiteMapManager, resultCursor, baseRank);
+        }
     }
 
     /**
diff --git a/src/com/android/settings/search/SavedQueryLoader.java b/src/com/android/settings/search/SavedQueryLoader.java
index 87457f5..e8efe85 100644
--- a/src/com/android/settings/search/SavedQueryLoader.java
+++ b/src/com/android/settings/search/SavedQueryLoader.java
@@ -34,7 +34,7 @@
 public class SavedQueryLoader extends AsyncLoader<List<? extends SearchResult>> {
 
     // Max number of proposed suggestions
-    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+    @VisibleForTesting
     static final int MAX_PROPOSED_SUGGESTIONS = 5;
 
     private final SQLiteDatabase mDatabase;
@@ -51,15 +51,17 @@
 
     @Override
     public List<? extends SearchResult> loadInBackground() {
-        Cursor cursor = mDatabase.query(IndexDatabaseHelper.Tables.TABLE_SAVED_QUERIES /* table */,
+        try (final Cursor cursor = mDatabase.query(
+                IndexDatabaseHelper.Tables.TABLE_SAVED_QUERIES /* table */,
                 new String[]{SavedQueriesColumns.QUERY} /* columns */,
                 null /* selection */,
                 null /* selectionArgs */,
                 null /* groupBy */,
                 null /* having */,
                 "rowId DESC" /* orderBy */,
-                String.valueOf(MAX_PROPOSED_SUGGESTIONS) /* limit */);
-        return convertCursorToResult(cursor);
+                String.valueOf(MAX_PROPOSED_SUGGESTIONS) /* limit */)) {
+            return convertCursorToResult(cursor);
+        }
     }
 
     private List<SearchResult> convertCursorToResult(Cursor cursor) {
diff --git a/src/com/android/settings/widget/EntityHeaderController.java b/src/com/android/settings/widget/EntityHeaderController.java
index f2fca7c..70b040d 100644
--- a/src/com/android/settings/widget/EntityHeaderController.java
+++ b/src/com/android/settings/widget/EntityHeaderController.java
@@ -215,6 +215,7 @@
         final LayoutPreference pref = new LayoutPreference(uiContext, done(activity));
         // Makes sure it's the first preference onscreen.
         pref.setOrder(-1000);
+        pref.setSelectable(false);
         pref.setKey(PREF_KEY_APP_HEADER);
         return pref;
     }
diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java
index 7cd1ab3..f0457e6 100644
--- a/src/com/android/settings/wifi/WifiSettings.java
+++ b/src/com/android/settings/wifi/WifiSettings.java
@@ -857,10 +857,11 @@
         }
 
         // Is the previous currently connected SSID different from the new one?
-        if (!((AccessPointPreference)
-                mConnectedAccessPointPreferenceCategory.getPreference(0))
-                        .getAccessPoint().getSsidStr().equals(
-                                connectedAp.getSsidStr())) {
+        AccessPointPreference preference = (AccessPointPreference)
+            (mConnectedAccessPointPreferenceCategory.getPreference(0));
+        // The AccessPoints need to be the same reference to ensure that updates are reflected
+        // in the UI.
+        if (preference.getAccessPoint() != connectedAp) {
             removeConnectedAccessPointPreference();
             addConnectedAccessPointPreference(connectedAp);
             return true;
diff --git a/tests/app/src/com/android/settings/password/ChooseLockGenericTest.java b/tests/app/src/com/android/settings/password/ChooseLockGenericTest.java
index e2bd6ee..40b69a4 100644
--- a/tests/app/src/com/android/settings/password/ChooseLockGenericTest.java
+++ b/tests/app/src/com/android/settings/password/ChooseLockGenericTest.java
@@ -18,9 +18,7 @@
 
 import static android.support.test.InstrumentationRegistry.getInstrumentation;
 import static android.support.test.InstrumentationRegistry.getTargetContext;
-
 import static com.google.common.truth.Truth.assertThat;
-
 import static org.junit.Assert.assertTrue;
 
 import android.app.Activity;
@@ -39,6 +37,7 @@
 import android.support.test.uiautomator.UiObject;
 import android.support.test.uiautomator.UiSelector;
 import android.text.format.DateUtils;
+import android.view.WindowManager;
 
 import com.android.internal.widget.LockPatternUtils;
 
@@ -93,7 +92,9 @@
             // WHEN ChooseLockGeneric is launched with no extras.
             mChooseLockGenericActivityRule.launchActivity(null /* No extras */);
             // THEN ConfirmLockPassword.InternalActivity is shown.
-            assertThat(getCurrentActivity())
+            final Activity activity = getCurrentActivity();
+            assertThat(isSecureWindow(activity)).isTrue();
+            assertThat(activity)
                     .isInstanceOf(ConfirmLockPassword.InternalActivity.class);
         } finally {
             finishAllAppTasks();
@@ -110,7 +111,9 @@
             // WHEN ChooseLockGeneric is launched with extras to by-pass lock password confirmation.
             mChooseLockGenericActivityRule.launchActivity(PHISHING_ATTACK_INTENT);
             // THEN ConfirmLockPassword.InternalActivity is still shown.
-            assertThat(getCurrentActivity())
+            final Activity activity = getCurrentActivity();
+            assertThat(isSecureWindow(activity)).isTrue();
+            assertThat(activity)
                     .isInstanceOf(ConfirmLockPassword.InternalActivity.class);
         } finally {
             finishAllAppTasks();
@@ -217,4 +220,9 @@
         mDevice.pressEnter();
         mDevice.waitForIdle();
     }
+
+    private boolean isSecureWindow(Activity activity) {
+        return (activity.getWindow().getAttributes().flags & WindowManager.LayoutParams.FLAG_SECURE)
+                != 0;
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/MasterClearTest.java b/tests/robotests/src/com/android/settings/MasterClearTest.java
index b501654..21b8e47 100644
--- a/tests/robotests/src/com/android/settings/MasterClearTest.java
+++ b/tests/robotests/src/com/android/settings/MasterClearTest.java
@@ -26,6 +26,7 @@
 
 import android.app.Activity;
 import android.app.Fragment;
+import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Intent;
 import android.os.Bundle;
@@ -37,7 +38,6 @@
 import android.widget.ScrollView;
 
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
-import com.android.settings.testutils.shadow.SettingsShadowResources;
 import com.android.settings.testutils.shadow.ShadowUtils;
 
 import org.junit.Before;
@@ -144,19 +144,19 @@
     }
 
     @Test
-    @Config(shadows = { ShadowUtils.class, SettingsShadowResources.class })
+    @Config(shadows = { ShadowUtils.class })
     public void testInitiateMasterClear_inDemoMode_sendsIntent() {
-        SettingsShadowResources.overrideResource(
-            com.android.internal.R.string.config_demoModePackage, "package");
-
         ShadowUtils.setIsDemoUser(true);
 
+        final ComponentName componentName = ComponentName.unflattenFromString(
+                "com.android.retaildemo/.DeviceAdminReceiver");
+        ShadowUtils.setDeviceOwnerComponent(componentName);
+
         mMasterClear.mInitiateListener.onClick(
                 mContentView.findViewById(R.id.initiate_master_clear));
         final Intent intent = mShadowActivity.getNextStartedActivity();
         assertThat(Intent.ACTION_FACTORY_RESET).isEqualTo(intent.getAction());
-        final String packageName = Utils.getDemoModePackageName(RuntimeEnvironment.application);
-        assertThat(packageName).isEqualTo(intent.getPackage());
+        assertThat(componentName.getPackageName()).isEqualTo(intent.getPackage());
     }
 
     private void initScrollView(int height, int scrollY, int childBottom) {
diff --git a/tests/robotests/src/com/android/settings/datausage/AppDataUsageTest.java b/tests/robotests/src/com/android/settings/datausage/AppDataUsageTest.java
index 637962b..2f2a685 100644
--- a/tests/robotests/src/com/android/settings/datausage/AppDataUsageTest.java
+++ b/tests/robotests/src/com/android/settings/datausage/AppDataUsageTest.java
@@ -17,9 +17,22 @@
 package com.android.settings.datausage;
 
 
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.os.Bundle;
+import android.support.v14.preference.SwitchPreference;
 import android.support.v7.preference.PreferenceManager;
 import android.support.v7.preference.PreferenceScreen;
 import android.util.ArraySet;
@@ -44,17 +57,6 @@
 import org.robolectric.annotation.Config;
 import org.robolectric.util.ReflectionHelpers;
 
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyBoolean;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
 @RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
         shadows = ShadowEntityHeaderController.class)
@@ -128,9 +130,24 @@
 
         mFragment.onViewCreated(new View(RuntimeEnvironment.application), new Bundle());
 
-        verify(mHeaderController)
-                .setHasAppInfoLink(true);
-        verify(mHeaderController)
-                .setUid(fakeUserId);
+        verify(mHeaderController).setHasAppInfoLink(true);
+        verify(mHeaderController).setUid(fakeUserId);
+    }
+
+    @Test
+    public void changePreference_backgroundData_shouldUpdateUI() {
+        mFragment = spy(new AppDataUsage());
+        final AppItem appItem = new AppItem(123456789);
+        final SwitchPreference pref = mock(SwitchPreference.class);
+        final DataSaverBackend dataSaverBackend = mock(DataSaverBackend.class);
+        ReflectionHelpers.setField(mFragment, "mAppItem", appItem);
+        ReflectionHelpers.setField(mFragment, "mRestrictBackground", pref);
+        ReflectionHelpers.setField(mFragment, "mDataSaverBackend", dataSaverBackend);
+
+        doNothing().when(mFragment).updatePrefs();
+
+        mFragment.onPreferenceChange(pref, true /* value */);
+
+        verify(mFragment).updatePrefs();
     }
 }
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowDataSaverBackend.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowDataSaverBackend.java
new file mode 100644
index 0000000..34908ca
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowDataSaverBackend.java
@@ -0,0 +1,21 @@
+package com.android.settings.testutils.shadow;
+
+import com.android.settings.datausage.DataSaverBackend;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+
+@Implements(DataSaverBackend.class)
+public class ShadowDataSaverBackend {
+
+    private static boolean isEnabled = true;
+
+    @Implementation
+    public boolean isDataSaverEnabled() {
+        return isEnabled;
+    }
+
+    @Implementation
+    public void setDataSaverEnabled(boolean enabled) {
+        isEnabled = enabled;
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUtils.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUtils.java
index 82f53a2..f85a874 100644
--- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUtils.java
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUtils.java
@@ -31,6 +31,7 @@
     private static IFingerprintManager sFingerprintManager = null;
     private static boolean sIsUserAMonkey;
     private static boolean sIsDemoUser;
+    private static ComponentName sDeviceOwnerComponentName;
 
     @Implementation
     public static int enforceSameOwner(Context context, int userId) {
@@ -61,22 +62,29 @@
         sIsDemoUser = isDemoUser;
     }
 
-    public static void setIsUserAMonkey(boolean isUserAMonkey) {
-        sIsUserAMonkey = isUserAMonkey;
-    }
-
-
     @Implementation
     public static boolean isDemoUser(Context context) {
         return sIsDemoUser;
     }
 
+    public static void setIsUserAMonkey(boolean isUserAMonkey) {
+        sIsUserAMonkey = isUserAMonkey;
+    }
+
     /**
      * Returns true if Monkey is running.
      */
     @Implementation
     public static boolean isMonkeyRunning() {
         return sIsUserAMonkey;
+    }
 
+    public static void setDeviceOwnerComponent(ComponentName componentName) {
+        sDeviceOwnerComponentName = componentName;
+    }
+
+    @Implementation
+    public static ComponentName getDeviceOwnerComponent(Context context) {
+        return sDeviceOwnerComponentName;
     }
 }