Merge "Fixes ContactDiscoveryDialogFragmentTest" into rvc-dev
diff --git a/src/com/android/settings/biometrics/BiometricEnrollActivity.java b/src/com/android/settings/biometrics/BiometricEnrollActivity.java
index 61c417c..fa01977 100644
--- a/src/com/android/settings/biometrics/BiometricEnrollActivity.java
+++ b/src/com/android/settings/biometrics/BiometricEnrollActivity.java
@@ -16,9 +16,12 @@
package com.android.settings.biometrics;
+import android.app.admin.DevicePolicyManager;
import android.app.settings.SettingsEnums;
import android.content.Intent;
import android.content.pm.PackageManager;
+import android.hardware.biometrics.BiometricManager;
+import android.hardware.biometrics.BiometricManager.Authenticators;
import android.os.Bundle;
import android.os.UserHandle;
import android.provider.Settings;
@@ -30,6 +33,7 @@
import com.android.settings.biometrics.fingerprint.FingerprintEnrollIntroduction;
import com.android.settings.biometrics.fingerprint.SetupFingerprintEnrollIntroduction;
import com.android.settings.core.InstrumentedActivity;
+import com.android.settings.password.ChooseLockGeneric;
import com.android.settings.password.ChooseLockSettingsHelper;
import com.google.android.setupcompat.util.WizardManagerHelper;
@@ -43,6 +47,7 @@
public class BiometricEnrollActivity extends InstrumentedActivity {
private static final String TAG = "BiometricEnrollActivity";
+ private static final int REQUEST_ENROLL = 1;
public static final String EXTRA_SKIP_INTRO = "skip_intro";
@@ -52,14 +57,33 @@
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- Log.d(TAG, "Min strength: " + getIntent()
- .getIntExtra(Settings.EXTRA_BIOMETRIC_MINIMUM_STRENGTH_REQUIRED, 0));
+ // Default behavior is to enroll BIOMETRIC_WEAK or above. See ACTION_BIOMETRIC_ENROLL.
+ final int authenticators = getIntent().getIntExtra(
+ Settings.EXTRA_BIOMETRIC_AUTHENTICATORS_ALLOWED, Authenticators.BIOMETRIC_WEAK);
+ Log.d(TAG, "Authenticators: " + authenticators);
+
+ final BiometricManager bm = getSystemService(BiometricManager.class);
final PackageManager pm = getApplicationContext().getPackageManager();
Intent intent = null;
- // This logic may have to be modified on devices with multiple biometrics.
- if (pm.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
+ final int result = bm.canAuthenticate(authenticators);
+
+ if (result == BiometricManager.BIOMETRIC_SUCCESS
+ || result == BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE) {
+ Log.e(TAG, "Unexpected result: " + result);
+ setResult(RESULT_CANCELED);
+ finish();
+ return;
+ }
+
+ if (authenticators == BiometricManager.Authenticators.DEVICE_CREDENTIAL) {
+ // If only device credential was specified, ask the user to only set that up.
+ intent = new Intent(this, ChooseLockGeneric.class);
+ intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY,
+ DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
+ } else if (pm.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
+ // This logic may have to be modified on devices with multiple biometrics.
// ChooseLockGeneric can request to start fingerprint enroll bypassing the intro screen.
if (getIntent().getBooleanExtra(EXTRA_SKIP_INTRO, false)
&& this instanceof InternalActivity) {
@@ -72,8 +96,6 @@
}
if (intent != null) {
- intent.setFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
-
if (this instanceof InternalActivity) {
// Propagate challenge and user Id from ChooseLockGeneric.
final byte[] token = getIntent()
@@ -85,9 +107,20 @@
intent.putExtra(Intent.EXTRA_USER_ID, userId);
}
- startActivity(intent);
+ startActivityForResult(intent, REQUEST_ENROLL);
+ } else {
+ Log.e(TAG, "Intent was null, finishing with RESULT_CANCELED");
+ setResult(RESULT_CANCELED);
+ finish();
}
- finish();
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (requestCode == REQUEST_ENROLL) {
+ setResult(RESULT_OK);
+ finish();
+ }
}
private Intent getFingerprintFindSensorIntent() {
diff --git a/src/com/android/settings/notification/history/HistoryLoader.java b/src/com/android/settings/notification/history/HistoryLoader.java
index 046b5ef..461bbc1 100644
--- a/src/com/android/settings/notification/history/HistoryLoader.java
+++ b/src/com/android/settings/notification/history/HistoryLoader.java
@@ -22,6 +22,7 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.UserHandle;
+import android.util.Slog;
import com.android.settings.notification.NotificationBackend;
import com.android.settingslib.utils.ThreadUtils;
@@ -33,6 +34,7 @@
import java.util.Map;
public class HistoryLoader {
+ private static final String TAG = "HistoryLoader";
private final Context mContext;
private final NotificationBackend mBackend;
private final PackageManager mPm;
@@ -45,45 +47,48 @@
public void load(OnHistoryLoaderListener listener) {
ThreadUtils.postOnBackgroundThread(() -> {
- Map<String, NotificationHistoryPackage> historicalNotifications = new HashMap<>();
- NotificationHistory history =
- mBackend.getNotificationHistory(mContext.getPackageName());
+ try {
+ Map<String, NotificationHistoryPackage> historicalNotifications = new HashMap<>();
+ NotificationHistory history =
+ mBackend.getNotificationHistory(mContext.getPackageName());
+ while (history.hasNextNotification()) {
+ HistoricalNotification hn = history.getNextNotification();
- while (history.hasNextNotification()) {
- HistoricalNotification hn = history.getNextNotification();
-
- String key = hn.getPackage() + "|" + hn.getUid();
- NotificationHistoryPackage hnsForPackage = historicalNotifications.getOrDefault(
- key,
- new NotificationHistoryPackage(hn.getPackage(), hn.getUid()));
- hnsForPackage.notifications.add(hn);
- historicalNotifications.put(key, hnsForPackage);
- }
- List<NotificationHistoryPackage> packages =
- new ArrayList<>(historicalNotifications.values());
- Collections.sort(packages,
- (o1, o2) -> -1 * Long.compare(o1.getMostRecent(), o2.getMostRecent()));
- for (NotificationHistoryPackage nhp : packages) {
- ApplicationInfo info;
- try {
- info = mPm.getApplicationInfoAsUser(
- nhp.pkgName,
- PackageManager.MATCH_UNINSTALLED_PACKAGES
- | PackageManager.MATCH_DISABLED_COMPONENTS
- | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
- | PackageManager.MATCH_DIRECT_BOOT_AWARE,
- UserHandle.getUserId(nhp.uid));
- if (info != null) {
- nhp.label = String.valueOf(mPm.getApplicationLabel(info));
- nhp.icon = mPm.getUserBadgedIcon(mPm.getApplicationIcon(info),
- UserHandle.of(UserHandle.getUserId(nhp.uid)));
- }
- } catch (PackageManager.NameNotFoundException e) {
- // app is gone, just show package name and generic icon
- nhp.icon = mPm.getDefaultActivityIcon();
+ String key = hn.getPackage() + "|" + hn.getUid();
+ NotificationHistoryPackage hnsForPackage = historicalNotifications.getOrDefault(
+ key,
+ new NotificationHistoryPackage(hn.getPackage(), hn.getUid()));
+ hnsForPackage.notifications.add(hn);
+ historicalNotifications.put(key, hnsForPackage);
}
+ List<NotificationHistoryPackage> packages =
+ new ArrayList<>(historicalNotifications.values());
+ Collections.sort(packages,
+ (o1, o2) -> -1 * Long.compare(o1.getMostRecent(), o2.getMostRecent()));
+ for (NotificationHistoryPackage nhp : packages) {
+ ApplicationInfo info;
+ try {
+ info = mPm.getApplicationInfoAsUser(
+ nhp.pkgName,
+ PackageManager.MATCH_UNINSTALLED_PACKAGES
+ | PackageManager.MATCH_DISABLED_COMPONENTS
+ | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
+ | PackageManager.MATCH_DIRECT_BOOT_AWARE,
+ UserHandle.getUserId(nhp.uid));
+ if (info != null) {
+ nhp.label = String.valueOf(mPm.getApplicationLabel(info));
+ nhp.icon = mPm.getUserBadgedIcon(mPm.getApplicationIcon(info),
+ UserHandle.of(UserHandle.getUserId(nhp.uid)));
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ // app is gone, just show package name and generic icon
+ nhp.icon = mPm.getDefaultActivityIcon();
+ }
+ }
+ ThreadUtils.postOnMainThread(() -> listener.onHistoryLoaded(packages));
+ } catch (Exception e) {
+ Slog.e(TAG, "Error loading history", e);
}
- ThreadUtils.postOnMainThread(() -> listener.onHistoryLoaded(packages));
});
}
diff --git a/src/com/android/settings/wifi/ConnectedWifiEntryPreference.java b/src/com/android/settings/wifi/ConnectedWifiEntryPreference.java
new file mode 100644
index 0000000..f79499a
--- /dev/null
+++ b/src/com/android/settings/wifi/ConnectedWifiEntryPreference.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2020 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.wifi;
+
+import android.content.Context;
+import android.view.View;
+
+import androidx.fragment.app.Fragment;
+import androidx.preference.PreferenceViewHolder;
+
+import com.android.settingslib.R;
+import com.android.settingslib.wifi.LongPressWifiEntryPreference;
+import com.android.wifitrackerlib.WifiEntry;
+
+/**
+ * An AP preference for the currently connected AP.
+ */
+public class ConnectedWifiEntryPreference extends LongPressWifiEntryPreference implements
+ View.OnClickListener {
+
+ private OnGearClickListener mOnGearClickListener;
+
+ public ConnectedWifiEntryPreference(Context context, WifiEntry wifiEntry, Fragment fragment) {
+ super(context, wifiEntry, fragment);
+ setWidgetLayoutResource(R.layout.preference_widget_gear_optional_background);
+ }
+
+ @Override
+ public void refresh() {
+ super.refresh();
+
+ if (getWifiEntry().canSignIn()) {
+ setSummary(R.string.wifi_tap_to_sign_in);
+ }
+ }
+
+ /**
+ * Set gear icon click callback listener.
+ */
+ public void setOnGearClickListener(OnGearClickListener l) {
+ mOnGearClickListener = l;
+ notifyChanged();
+ }
+
+ @Override
+ public void onBindViewHolder(PreferenceViewHolder holder) {
+ super.onBindViewHolder(holder);
+
+ final View gear = holder.findViewById(R.id.settings_button);
+ gear.setOnClickListener(this);
+
+ final boolean canSignIn = getWifiEntry().canSignIn();
+ holder.findViewById(R.id.settings_button_no_background).setVisibility(
+ canSignIn ? View.INVISIBLE : View.VISIBLE);
+ gear.setVisibility(canSignIn ? View.VISIBLE : View.INVISIBLE);
+ holder.findViewById(R.id.two_target_divider).setVisibility(
+ canSignIn ? View.VISIBLE : View.INVISIBLE);
+ }
+
+ @Override
+ public void onClick(View v) {
+ if (v.getId() == R.id.settings_button) {
+ if (mOnGearClickListener != null) {
+ mOnGearClickListener.onGearClick(this);
+ }
+ }
+ }
+
+ /**
+ * Gear Icon click callback interface.
+ */
+ public interface OnGearClickListener {
+ /**
+ * The callback triggered when gear icon is clicked.
+ */
+ void onGearClick(ConnectedWifiEntryPreference p);
+ }
+
+}
diff --git a/src/com/android/settings/wifi/WifiSettings2.java b/src/com/android/settings/wifi/WifiSettings2.java
index f88a4df..5152569 100644
--- a/src/com/android/settings/wifi/WifiSettings2.java
+++ b/src/com/android/settings/wifi/WifiSettings2.java
@@ -711,8 +711,8 @@
mConnectedWifiEntryPreferenceCategory.findPreference(connectedEntry.getKey());
if (connectedPref == null || connectedPref.getWifiEntry() != connectedEntry) {
mConnectedWifiEntryPreferenceCategory.removeAll();
- final LongPressWifiEntryPreference pref =
- createLongPressWifiEntryPreference(connectedEntry);
+ final ConnectedWifiEntryPreference pref =
+ new ConnectedWifiEntryPreference(getPrefContext(), connectedEntry, this);
pref.setKey(connectedEntry.getKey());
pref.refresh();
mConnectedWifiEntryPreferenceCategory.addPreference(pref);
@@ -724,6 +724,9 @@
}
return true;
});
+ pref.setOnGearClickListener(preference -> {
+ launchNetworkDetailsFragment(pref);
+ });
}
} else {
mConnectedWifiEntryPreferenceCategory.removeAll();
diff --git a/tests/robotests/src/com/android/settings/wifi/ConnectedWifiEntryPreferenceTest.java b/tests/robotests/src/com/android/settings/wifi/ConnectedWifiEntryPreferenceTest.java
new file mode 100644
index 0000000..401fdcf
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/wifi/ConnectedWifiEntryPreferenceTest.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2020 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.wifi;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.view.View;
+
+import com.android.settings.R;
+import com.android.wifitrackerlib.WifiEntry;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(RobolectricTestRunner.class)
+public class ConnectedWifiEntryPreferenceTest {
+
+ @Mock
+ private WifiEntry mWifiEntry;
+ @Mock
+ private View mView;
+ @Mock
+ private ConnectedWifiEntryPreference.OnGearClickListener mOnGearClickListener;
+ private Context mContext;
+ private ConnectedWifiEntryPreference mConnectedWifiEntryPreference;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+
+ mContext = RuntimeEnvironment.application;
+ mConnectedWifiEntryPreference = new ConnectedWifiEntryPreference(mContext, mWifiEntry,
+ null /* fragment */);
+ mConnectedWifiEntryPreference.setOnGearClickListener(mOnGearClickListener);
+ }
+
+ @Test
+ public void testOnClick_gearClicked_listenerInvoked() {
+ when(mView.getId()).thenReturn(R.id.settings_button);
+
+ mConnectedWifiEntryPreference.onClick(mView);
+
+ verify(mOnGearClickListener).onGearClick(mConnectedWifiEntryPreference);
+ }
+
+ @Test
+ public void testOnClick_gearNotClicked_listenerNotInvoked() {
+ mConnectedWifiEntryPreference.onClick(mView);
+
+ verify(mOnGearClickListener, never()).onGearClick(mConnectedWifiEntryPreference);
+ }
+
+ @Test
+ public void testWidgetLayoutPreference() {
+ assertThat(mConnectedWifiEntryPreference.getWidgetLayoutResource())
+ .isEqualTo(R.layout.preference_widget_gear_optional_background);
+ }
+}