diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 8c086358247..bb43bbf51c6 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -425,6 +425,17 @@
android:value="com.android.settings.gestures.AssistGestureSettings" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 91f7ebfa776..df98e0e424f 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -889,6 +889,17 @@
All set. Looking good.Done
+
+ Use your face to
+
+ Unlock your device
+
+ Remove face data
+
+ Improve your face data
+
+ Your face can be used to unlock your device and access apps.
+ Learn more
@@ -6641,6 +6652,8 @@
+
+
@@ -6969,6 +6982,7 @@
pay, tap, paymentsbackup, back upgesture
+ face, unlockimei, meid, min, prl version, imei svnetwork, mobile network state, service state, signal strength, mobile network type, roaming, iccidserial number, hardware version
diff --git a/res/xml/security_settings_face.xml b/res/xml/security_settings_face.xml
new file mode 100644
index 00000000000..3dfcfd77413
--- /dev/null
+++ b/res/xml/security_settings_face.xml
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index 99d7d474b0a..4f011c19707 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -31,6 +31,7 @@ public class Settings extends SettingsActivity {
public static class AssistGestureSettingsActivity extends SettingsActivity { /* empty */}
public static class BluetoothSettingsActivity extends SettingsActivity { /* empty */ }
public static class CreateShortcutActivity extends SettingsActivity { /* empty */ }
+ public static class FaceSettingsActivity extends SettingsActivity { /* empty */ }
public static class SimSettingsActivity extends SettingsActivity { /* empty */ }
public static class TetherSettingsActivity extends SettingsActivity { /* empty */ }
public static class WifiTetherSettingsActivity extends SettingsActivity { /* empty */ }
diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index f95a303ead3..0df0e6fa489 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -42,6 +42,16 @@ import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Toolbar;
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
+import androidx.fragment.app.FragmentTransaction;
+import androidx.localbroadcastmanager.content.LocalBroadcastManager;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceFragmentCompat;
+import androidx.preference.PreferenceManager;
+
import com.android.internal.util.ArrayUtils;
import com.android.settings.Settings.WifiSettingsActivity;
import com.android.settings.applications.manageapplications.ManageApplications;
@@ -65,16 +75,6 @@ import com.android.settingslib.utils.ThreadUtils;
import java.util.ArrayList;
import java.util.List;
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-import androidx.fragment.app.Fragment;
-import androidx.fragment.app.FragmentManager;
-import androidx.fragment.app.FragmentTransaction;
-import androidx.localbroadcastmanager.content.LocalBroadcastManager;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceFragmentCompat;
-import androidx.preference.PreferenceManager;
-
public class SettingsActivity extends SettingsBaseActivity
implements PreferenceManager.OnPreferenceTreeClickListener,
diff --git a/src/com/android/settings/accounts/AccountDetailDashboardFragment.java b/src/com/android/settings/accounts/AccountDetailDashboardFragment.java
index 709066aac67..14d2fd3b720 100644
--- a/src/com/android/settings/accounts/AccountDetailDashboardFragment.java
+++ b/src/com/android/settings/accounts/AccountDetailDashboardFragment.java
@@ -126,7 +126,7 @@ public class AccountDetailDashboardFragment extends DashboardFragment {
if (mAccountType == null) {
return false;
}
- final Bundle metadata = tile.metaData;
+ final Bundle metadata = tile.getMetaData();
if (metadata == null) {
return false;
}
diff --git a/src/com/android/settings/biometrics/BiometricEnrollBase.java b/src/com/android/settings/biometrics/BiometricEnrollBase.java
index 298891e569f..130f20f7fe6 100644
--- a/src/com/android/settings/biometrics/BiometricEnrollBase.java
+++ b/src/com/android/settings/biometrics/BiometricEnrollBase.java
@@ -16,6 +16,8 @@
package com.android.settings.biometrics;
+import static android.app.Activity.RESULT_FIRST_USER;
+
import android.annotation.Nullable;
import android.content.Intent;
import android.content.res.Resources;
@@ -39,11 +41,33 @@ import com.android.setupwizardlib.GlifLayout;
*/
public abstract class BiometricEnrollBase extends InstrumentedActivity
implements View.OnClickListener {
- public static final int RESULT_FINISHED = BiometricSettings.RESULT_FINISHED;
- public static final int RESULT_SKIP = BiometricSettings.RESULT_SKIP;
- public static final int RESULT_TIMEOUT = BiometricSettings.RESULT_TIMEOUT;
public static final String EXTRA_KEY_LAUNCHED_CONFIRM = "launched_confirm_lock";
+
+ /**
+ * Used by the choose fingerprint wizard to indicate the wizard is
+ * finished, and each activity in the wizard should finish.
+ *
+ * Previously, each activity in the wizard would finish itself after
+ * starting the next activity. However, this leads to broken 'Back'
+ * behavior. So, now an activity does not finish itself until it gets this
+ * result.
+ */
+ public static final int RESULT_FINISHED = RESULT_FIRST_USER;
+
+ /**
+ * Used by the enrolling screen during setup wizard to skip over setting up fingerprint, which
+ * will be useful if the user accidentally entered this flow.
+ */
+ public static final int RESULT_SKIP = RESULT_FIRST_USER + 1;
+
+ /**
+ * Like {@link #RESULT_FINISHED} except this one indicates enrollment failed because the
+ * device was left idle. This is used to clear the credential token to require the user to
+ * re-enter their pin/pattern/password before continuing.
+ */
+ public static final int RESULT_TIMEOUT = RESULT_FIRST_USER + 2;
+
public static final int CONFIRM_REQUEST = 1;
public static final int ENROLLING = 2;
diff --git a/src/com/android/settings/biometrics/BiometricErrorDialog.java b/src/com/android/settings/biometrics/BiometricErrorDialog.java
index 5c4e891bb13..6e5a221c829 100644
--- a/src/com/android/settings/biometrics/BiometricErrorDialog.java
+++ b/src/com/android/settings/biometrics/BiometricErrorDialog.java
@@ -16,8 +16,8 @@
package com.android.settings.biometrics;
-import static com.android.settings.biometrics.BiometricSettings.RESULT_FINISHED;
-import static com.android.settings.biometrics.BiometricSettings.RESULT_TIMEOUT;
+import static com.android.settings.biometrics.BiometricEnrollBase.RESULT_FINISHED;
+import static com.android.settings.biometrics.BiometricEnrollBase.RESULT_TIMEOUT;
import android.app.Activity;
import android.app.Dialog;
diff --git a/src/com/android/settings/biometrics/BiometricSettings.java b/src/com/android/settings/biometrics/BiometricSettings.java
deleted file mode 100644
index ccb4c5e0807..00000000000
--- a/src/com/android/settings/biometrics/BiometricSettings.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.settings.biometrics;
-
-import com.android.settings.SubSettings;
-
-/**
- * Abstract base class for biometric settings, such as Fingerprint, Face, Iris
- */
-public abstract class BiometricSettings extends SubSettings {
- /**
- * Used by the choose fingerprint wizard to indicate the wizard is
- * finished, and each activity in the wizard should finish.
- *
- * Previously, each activity in the wizard would finish itself after
- * starting the next activity. However, this leads to broken 'Back'
- * behavior. So, now an activity does not finish itself until it gets this
- * result.
- */
- protected static final int RESULT_FINISHED = RESULT_FIRST_USER;
-
- /**
- * Used by the enrolling screen during setup wizard to skip over setting up fingerprint, which
- * will be useful if the user accidentally entered this flow.
- */
- protected static final int RESULT_SKIP = RESULT_FIRST_USER + 1;
-
- /**
- * Like {@link #RESULT_FINISHED} except this one indicates enrollment failed because the
- * device was left idle. This is used to clear the credential token to require the user to
- * re-enter their pin/pattern/password before continuing.
- */
- protected static final int RESULT_TIMEOUT = RESULT_FIRST_USER + 2;
-}
diff --git a/src/com/android/settings/biometrics/face/FaceSettings.java b/src/com/android/settings/biometrics/face/FaceSettings.java
new file mode 100644
index 00000000000..4944c7f6beb
--- /dev/null
+++ b/src/com/android/settings/biometrics/face/FaceSettings.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.biometrics.face;
+
+import static com.android.settings.biometrics.BiometricEnrollBase.CONFIRM_REQUEST;
+
+import android.content.Context;
+import android.hardware.face.FaceManager;
+import android.os.Bundle;
+import android.provider.SearchIndexableResource;
+import android.util.Log;
+
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.R;
+import com.android.settings.Utils;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.password.ChooseLockSettingsHelper;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.search.SearchIndexable;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Settings screen for face authentication.
+ */
+@SearchIndexable
+public class FaceSettings extends DashboardFragment {
+
+ private static final String TAG = "FaceSettings";
+ private static final String KEY_LAUNCHED_CONFIRM = "key_launched_confirm";
+
+ private boolean mLaunchedConfirm;
+
+ public static boolean isAvailable(Context context) {
+ FaceManager manager = Utils.getFaceManagerOrNull(context);
+ return manager != null && manager.isHardwareDetected();
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return MetricsProto.MetricsEvent.FACE;
+ }
+
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.security_settings_face;
+ }
+
+ @Override
+ protected String getLogTag() {
+ return TAG;
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putBoolean(KEY_LAUNCHED_CONFIRM, mLaunchedConfirm);
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ if (savedInstanceState != null) {
+ mLaunchedConfirm = savedInstanceState.getBoolean(KEY_LAUNCHED_CONFIRM, false);
+ }
+
+ if (!mLaunchedConfirm) {
+ ChooseLockSettingsHelper helper = new ChooseLockSettingsHelper(getActivity(), this);
+ if (!helper.launchConfirmationActivity(CONFIRM_REQUEST,
+ getString(R.string.security_settings_face_preference_title))) {
+ Log.e(TAG, "Password not set");
+ finish();
+ }
+ }
+ }
+
+ @Override
+ protected List createPreferenceControllers(Context context) {
+ return buildPreferenceControllers(context, getSettingsLifecycle());
+ }
+
+ private static List buildPreferenceControllers(Context context,
+ Lifecycle lifecycle) {
+ final List controllers = new ArrayList<>();
+ controllers.add(new FaceSettingsVideoPreferenceController(context));
+ controllers.add(new FaceSettingsImprovePreferenceController(context));
+ controllers.add(new FaceSettingsUnlockPreferenceController(context));
+ controllers.add(new FaceSettingsRemoveButtonPreferenceController(context));
+ controllers.add(new FaceSettingsFooterPreferenceController(context));
+ return controllers;
+ }
+
+ public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+ new BaseSearchIndexProvider() {
+ @Override
+ public List getXmlResourcesToIndex(
+ Context context, boolean enabled) {
+ final SearchIndexableResource sir = new SearchIndexableResource(context);
+ sir.xmlResId = R.xml.security_settings_face;
+ return Arrays.asList(sir);
+ }
+
+ @Override
+ public List createPreferenceControllers(
+ Context context) {
+ return buildPreferenceControllers(context, null /* lifecycle */);
+ }
+
+ @Override
+ protected boolean isPageSearchEnabled(Context context) {
+ return isAvailable(context);
+ }
+ };
+
+}
diff --git a/src/com/android/settings/biometrics/face/FaceSettingsFooterPreferenceController.java b/src/com/android/settings/biometrics/face/FaceSettingsFooterPreferenceController.java
new file mode 100644
index 00000000000..855b169538d
--- /dev/null
+++ b/src/com/android/settings/biometrics/face/FaceSettingsFooterPreferenceController.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.settings.biometrics.face;
+
+import android.content.Context;
+import android.content.Intent;
+
+import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.utils.AnnotationSpan;
+import com.android.settingslib.HelpUtils;
+import com.android.settingslib.widget.FooterPreference;
+
+import androidx.preference.Preference;
+
+/**
+ * Footer for face settings showing the help text and help link.
+ */
+public class FaceSettingsFooterPreferenceController extends BasePreferenceController {
+
+ private static final String ANNOTATION_URL = "url";
+
+ public FaceSettingsFooterPreferenceController(Context context, String preferenceKey) {
+ super(context, preferenceKey);
+ }
+
+ public FaceSettingsFooterPreferenceController(Context context) {
+ this(context, FooterPreference.KEY_FOOTER);
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ return AVAILABLE;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+
+ final Intent helpIntent = HelpUtils.getHelpIntent(
+ mContext, mContext.getString(R.string.help_url_face), getClass().getName());
+ final AnnotationSpan.LinkInfo linkInfo =
+ new AnnotationSpan.LinkInfo(mContext, ANNOTATION_URL, helpIntent);
+ preference.setTitle(AnnotationSpan.linkify(
+ mContext.getText(R.string.security_settings_face_settings_footer), linkInfo));
+ }
+}
diff --git a/src/com/android/settings/biometrics/face/FaceSettingsImprovePreferenceController.java b/src/com/android/settings/biometrics/face/FaceSettingsImprovePreferenceController.java
new file mode 100644
index 00000000000..94b14b57b61
--- /dev/null
+++ b/src/com/android/settings/biometrics/face/FaceSettingsImprovePreferenceController.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.settings.biometrics.face;
+
+import android.content.Context;
+
+import com.android.settings.core.BasePreferenceController;
+
+import androidx.preference.Preference;
+
+/**
+ * Preference controller which allows the user to update their enrolled face.
+ */
+public class FaceSettingsImprovePreferenceController extends BasePreferenceController {
+
+ private static final String KEY = "security_settings_face_improve";
+
+ public FaceSettingsImprovePreferenceController(Context context, String preferenceKey) {
+ super(context, preferenceKey);
+ }
+
+ public FaceSettingsImprovePreferenceController(Context context) {
+ this(context, KEY);
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ return AVAILABLE;
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY;
+ }
+
+ @Override
+ public boolean handlePreferenceTreeClick(Preference preference) {
+ return false;
+ }
+}
diff --git a/src/com/android/settings/biometrics/face/FaceSettingsRemoveButtonPreferenceController.java b/src/com/android/settings/biometrics/face/FaceSettingsRemoveButtonPreferenceController.java
new file mode 100644
index 00000000000..b1dcce02c26
--- /dev/null
+++ b/src/com/android/settings/biometrics/face/FaceSettingsRemoveButtonPreferenceController.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.settings.biometrics.face;
+
+import android.content.Context;
+import android.view.View;
+import android.widget.Button;
+
+import com.android.settings.R;
+import com.android.settings.applications.LayoutPreference;
+import com.android.settings.core.BasePreferenceController;
+
+import androidx.preference.Preference;
+
+/**
+ * Controller for the remove button.
+ */
+public class FaceSettingsRemoveButtonPreferenceController extends BasePreferenceController
+ implements View.OnClickListener {
+
+ private static final String KEY = "security_settings_face_delete_faces_container";
+
+ private Button mButton;
+
+ public FaceSettingsRemoveButtonPreferenceController(Context context, String preferenceKey) {
+ super(context, preferenceKey);
+ }
+
+ public FaceSettingsRemoveButtonPreferenceController(Context context) {
+ this(context, KEY);
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+
+ mButton = ((LayoutPreference) preference)
+ .findViewById(R.id.security_settings_face_settings_remove_button);
+ mButton.setOnClickListener(this);
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ return AVAILABLE;
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY;
+ }
+
+ @Override
+ public void onClick(View v) {
+ if (v == mButton) {
+
+ }
+ }
+}
diff --git a/src/com/android/settings/biometrics/face/FaceSettingsUnlockPreferenceController.java b/src/com/android/settings/biometrics/face/FaceSettingsUnlockPreferenceController.java
new file mode 100644
index 00000000000..b483dc6c9c1
--- /dev/null
+++ b/src/com/android/settings/biometrics/face/FaceSettingsUnlockPreferenceController.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.settings.biometrics.face;
+
+import static android.provider.Settings.Secure.FACE_UNLOCK_KEYGUARD_ENABLED;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.os.UserHandle;
+import android.provider.Settings;
+
+import com.android.settings.core.TogglePreferenceController;
+
+import androidx.preference.Preference;
+
+/**
+ * Preference controller for Face settings page controlling the ability to unlock the phone
+ * with face.
+ */
+public class FaceSettingsUnlockPreferenceController extends TogglePreferenceController {
+
+ private static final String KEY = "security_settings_face_unlock";
+
+ private static final int ON = 1;
+ private static final int OFF = 0;
+ private static final int DEFAULT = ON; // face unlock is enabled on keyguard by default
+
+ public FaceSettingsUnlockPreferenceController(Context context, String preferenceKey) {
+ super(context, preferenceKey);
+ }
+
+ public FaceSettingsUnlockPreferenceController(Context context) {
+ this(context, KEY);
+ }
+
+ @Override
+ public boolean isChecked() {
+ if (!FaceSettings.isAvailable(mContext)) {
+ return false;
+ } else if (adminDisabled()) {
+ return false;
+ }
+ return Settings.Secure.getInt(
+ mContext.getContentResolver(), FACE_UNLOCK_KEYGUARD_ENABLED, DEFAULT) == ON;
+ }
+
+ @Override
+ public boolean setChecked(boolean isChecked) {
+ return Settings.Secure.putInt(mContext.getContentResolver(), FACE_UNLOCK_KEYGUARD_ENABLED,
+ isChecked ? ON : OFF);
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ return AVAILABLE;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+ if (!FaceSettings.isAvailable(mContext)) {
+ preference.setEnabled(false);
+ } else if (adminDisabled()) {
+ preference.setEnabled(false);
+ } else {
+ preference.setEnabled(true);
+ }
+ }
+
+ private boolean adminDisabled() {
+ DevicePolicyManager dpm =
+ (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+ return dpm != null &&
+ (dpm.getKeyguardDisabledFeatures(null, UserHandle.myUserId())
+ & DevicePolicyManager.KEYGUARD_DISABLE_FACE)
+ != 0;
+ }
+}
diff --git a/src/com/android/settings/biometrics/face/FaceSettingsVideoPreferenceController.java b/src/com/android/settings/biometrics/face/FaceSettingsVideoPreferenceController.java
new file mode 100644
index 00000000000..6fbb9c4f024
--- /dev/null
+++ b/src/com/android/settings/biometrics/face/FaceSettingsVideoPreferenceController.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.settings.biometrics.face;
+
+import android.content.Context;
+
+import com.android.settings.core.BasePreferenceController;
+
+public class FaceSettingsVideoPreferenceController extends BasePreferenceController {
+
+ private static final String PREF_KEY_VIDEO = "security_settings_face_video";
+
+ public FaceSettingsVideoPreferenceController(Context context,
+ String preferenceKey) {
+ super(context, preferenceKey);
+ }
+
+ public FaceSettingsVideoPreferenceController(Context context) {
+ this(context, PREF_KEY_VIDEO);
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ return AVAILABLE;
+ }
+}
diff --git a/src/com/android/settings/biometrics/face/FaceStatusPreferenceController.java b/src/com/android/settings/biometrics/face/FaceStatusPreferenceController.java
index 96f22e0ab8e..9a146608fb4 100644
--- a/src/com/android/settings/biometrics/face/FaceStatusPreferenceController.java
+++ b/src/com/android/settings/biometrics/face/FaceStatusPreferenceController.java
@@ -20,6 +20,7 @@ import android.content.Context;
import android.hardware.face.FaceManager;
import com.android.settings.R;
+import com.android.settings.Settings;
import com.android.settings.Utils;
import com.android.settings.biometrics.BiometricStatusPreferenceController;
@@ -62,7 +63,7 @@ public class FaceStatusPreferenceController extends BiometricStatusPreferenceCon
@Override
protected String getSettingsClassName() {
- return null;
+ return Settings.FaceSettingsActivity.class.getName();
}
@Override
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java b/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java
index d318fefc544..3309b78f98b 100644
--- a/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java
@@ -40,8 +40,9 @@ import android.widget.Toast;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
+import com.android.settings.SubSettings;
import com.android.settings.Utils;
-import com.android.settings.biometrics.BiometricSettings;
+import com.android.settings.biometrics.BiometricEnrollBase;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import com.android.settings.password.ChooseLockGeneric;
import com.android.settings.password.ChooseLockSettingsHelper;
@@ -66,7 +67,7 @@ import androidx.preference.PreferenceViewHolder;
/**
* Settings screen for fingerprints
*/
-public class FingerprintSettings extends BiometricSettings {
+public class FingerprintSettings extends SubSettings {
private static final String TAG = "FingerprintSettings";
@@ -75,6 +76,10 @@ public class FingerprintSettings extends BiometricSettings {
public static final String ANNOTATION_URL = "url";
public static final String ANNOTATION_ADMIN_DETAILS = "admin_details";
+ private static final int RESULT_FINISHED = BiometricEnrollBase.RESULT_FINISHED;
+ private static final int RESULT_SKIP = BiometricEnrollBase.RESULT_SKIP;
+ private static final int RESULT_TIMEOUT = BiometricEnrollBase.RESULT_TIMEOUT;
+
@Override
public Intent getIntent() {
Intent modIntent = new Intent(super.getIntent());
diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java
index 219c92c5a6f..434697359bb 100644
--- a/src/com/android/settings/core/gateway/SettingsGateway.java
+++ b/src/com/android/settings/core/gateway/SettingsGateway.java
@@ -52,6 +52,7 @@ import com.android.settings.applications.specialaccess.pictureinpicture.PictureI
import com.android.settings.applications.specialaccess.vrlistener.VrListenerSettings;
import com.android.settings.backup.PrivacySettings;
import com.android.settings.backup.ToggleBackupSettingFragment;
+import com.android.settings.biometrics.face.FaceSettings;
import com.android.settings.bluetooth.BluetoothDeviceDetailsFragment;
import com.android.settings.connecteddevice.AdvancedConnectedDeviceDashboardFragment;
import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment;
@@ -187,6 +188,7 @@ public class SettingsGateway {
PowerUsageSummary.class.getName(),
AccountSyncSettings.class.getName(),
AssistGestureSettings.class.getName(),
+ FaceSettings.class.getName(),
SwipeToNotificationSettings.class.getName(),
DoubleTapPowerSettings.class.getName(),
DoubleTapScreenSettings.class.getName(),
diff --git a/src/com/android/settings/dashboard/CategoryManager.java b/src/com/android/settings/dashboard/CategoryManager.java
index 407207226fe..baabe28ffaa 100644
--- a/src/com/android/settings/dashboard/CategoryManager.java
+++ b/src/com/android/settings/dashboard/CategoryManager.java
@@ -153,7 +153,7 @@ public class CategoryManager {
boolean useNewKey = false;
boolean useOldKey = false;
for (Tile tile : tiles) {
- if (CategoryKey.KEY_COMPAT_MAP.containsKey(tile.category)) {
+ if (CategoryKey.KEY_COMPAT_MAP.containsKey(tile.getCategory())) {
useOldKey = true;
} else {
useNewKey = true;
@@ -163,12 +163,13 @@ public class CategoryManager {
// Uses only old key, map them to new keys one by one.
if (useOldKey && !useNewKey) {
for (Tile tile : tiles) {
- final String newCategoryKey = CategoryKey.KEY_COMPAT_MAP.get(tile.category);
- tile.category = newCategoryKey;
+ final String newCategoryKey =
+ CategoryKey.KEY_COMPAT_MAP.get(tile.getCategory());
+ tile.setCategory(newCategoryKey);
// move tile to new category.
DashboardCategory newCategory = categoryByKeyMap.get(newCategoryKey);
if (newCategory == null) {
- newCategory = new DashboardCategory();
+ newCategory = new DashboardCategory(newCategoryKey);
categoryByKeyMap.put(newCategoryKey, newCategory);
}
newCategory.addTile(tile);
@@ -216,15 +217,4 @@ public class CategoryManager {
}
}
}
-
- /**
- * Sort priority value for tiles within a single {@code DashboardCategory}.
- *
- * @see #sortCategories(Context, Map)
- */
- private synchronized void sortCategoriesForExternalTiles(Context context,
- DashboardCategory dashboardCategory) {
- dashboardCategory.sortTiles(context.getPackageName());
-
- }
}
diff --git a/src/com/android/settings/dashboard/DashboardAdapter.java b/src/com/android/settings/dashboard/DashboardAdapter.java
index b278f60530e..fc1a129c1bd 100644
--- a/src/com/android/settings/dashboard/DashboardAdapter.java
+++ b/src/com/android/settings/dashboard/DashboardAdapter.java
@@ -31,6 +31,11 @@ import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
+import androidx.annotation.VisibleForTesting;
+import androidx.recyclerview.widget.DiffUtil;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.R.id;
@@ -51,11 +56,6 @@ import com.android.settingslib.utils.IconCache;
import java.util.List;
-import androidx.annotation.VisibleForTesting;
-import androidx.recyclerview.widget.DiffUtil;
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
-
public class DashboardAdapter extends RecyclerView.Adapter
implements SummaryLoader.SummaryConsumer, SuggestionAdapter.Callback, LifecycleObserver,
OnSaveInstanceState {
@@ -321,8 +321,9 @@ public class DashboardAdapter extends RecyclerView.Adapter tiles = category.getTiles();
if (tiles == null || tiles.isEmpty()) {
- Log.d(TAG, "tile list is empty, skipping category " + category.title);
+ Log.d(TAG, "tile list is empty, skipping category " + category.key);
return null;
}
final List preferences = new ArrayList<>();
@@ -143,7 +143,7 @@ public class DashboardFeatureProviderImpl implements DashboardFeatureProvider {
}
bindSummary(pref, tile);
bindIcon(pref, tile);
- final Bundle metadata = tile.metaData;
+ final Bundle metadata = tile.getMetaData();
String clsName = null;
String action = null;
Integer order = null;
@@ -218,15 +218,15 @@ public class DashboardFeatureProviderImpl implements DashboardFeatureProvider {
private void bindSummary(Preference preference, Tile tile) {
if (tile.summary != null) {
preference.setSummary(tile.summary);
- } else if (tile.metaData != null
- && tile.metaData.containsKey(META_DATA_PREFERENCE_SUMMARY_URI)) {
+ } else if (tile.getMetaData() != null
+ && tile.getMetaData().containsKey(META_DATA_PREFERENCE_SUMMARY_URI)) {
// Set a placeholder summary before starting to fetch real summary, this is necessary
// to avoid preference height change.
preference.setSummary(R.string.summary_placeholder);
ThreadUtils.postOnBackgroundThread(() -> {
final Map providerMap = new ArrayMap<>();
- final String uri = tile.metaData.getString(META_DATA_PREFERENCE_SUMMARY_URI);
+ final String uri = tile.getMetaData().getString(META_DATA_PREFERENCE_SUMMARY_URI);
final String summary = TileUtils.getTextFromUri(
mContext, uri, providerMap, META_DATA_PREFERENCE_SUMMARY);
ThreadUtils.postOnMainThread(() -> preference.setSummary(summary));
@@ -241,8 +241,8 @@ public class DashboardFeatureProviderImpl implements DashboardFeatureProvider {
final Icon tileIcon = tile.getIcon(mContext);
if (tileIcon != null) {
preference.setIcon(tileIcon.loadDrawable(preference.getContext()));
- } else if (tile.metaData != null
- && tile.metaData.containsKey(META_DATA_PREFERENCE_ICON_URI)) {
+ } else if (tile.getMetaData() != null
+ && tile.getMetaData().containsKey(META_DATA_PREFERENCE_ICON_URI)) {
ThreadUtils.postOnBackgroundThread(() -> {
String packageName = null;
if (tile.intent != null) {
@@ -254,7 +254,7 @@ public class DashboardFeatureProviderImpl implements DashboardFeatureProvider {
}
}
final Map providerMap = new ArrayMap<>();
- final String uri = tile.metaData.getString(META_DATA_PREFERENCE_ICON_URI);
+ final String uri = tile.getMetaData().getString(META_DATA_PREFERENCE_ICON_URI);
final Pair iconInfo = TileUtils.getIconFromUri(
mContext, packageName, uri, providerMap);
if (iconInfo == null) {
diff --git a/src/com/android/settings/dashboard/DashboardFragment.java b/src/com/android/settings/dashboard/DashboardFragment.java
index fceec3b91bb..acf885dee0f 100644
--- a/src/com/android/settings/dashboard/DashboardFragment.java
+++ b/src/com/android/settings/dashboard/DashboardFragment.java
@@ -18,6 +18,7 @@ package com.android.settings.dashboard;
import android.app.Activity;
import android.content.Context;
import android.content.res.TypedArray;
+import android.graphics.drawable.Icon;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.ArrayMap;
@@ -40,7 +41,6 @@ import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.drawer.DashboardCategory;
import com.android.settingslib.drawer.Tile;
-import com.android.settingslib.drawer.TileUtils;
import java.util.ArrayList;
import java.util.Collection;
@@ -254,24 +254,6 @@ public abstract class DashboardFragment extends SettingsPreferenceFragment
return true;
}
- @VisibleForTesting
- boolean tintTileIcon(Tile tile) {
- final Context context = getContext();
- if (tile.getIcon(context) == null) {
- return false;
- }
- // First check if the tile has set the icon tintable metadata.
- final Bundle metadata = tile.metaData;
- if (metadata != null
- && metadata.containsKey(TileUtils.META_DATA_PREFERENCE_ICON_TINTABLE)) {
- return metadata.getBoolean(TileUtils.META_DATA_PREFERENCE_ICON_TINTABLE);
- }
- final String pkgName = context.getPackageName();
- // If this drawable is coming from outside Settings, tint it to match the color.
- return pkgName != null && tile.intent != null
- && !pkgName.equals(tile.intent.getComponent().getPackageName());
- }
-
/**
* Displays resource based tiles.
*/
@@ -343,7 +325,7 @@ public abstract class DashboardFragment extends SettingsPreferenceFragment
}
final List tiles = category.getTiles();
if (tiles == null) {
- Log.d(TAG, "tile list is empty, skipping category " + category.title);
+ Log.d(TAG, "tile list is empty, skipping category " + category.key);
return;
}
// Create a list to track which tiles are to be removed.
@@ -356,7 +338,7 @@ public abstract class DashboardFragment extends SettingsPreferenceFragment
final Context context = getContext();
mSummaryLoader = new SummaryLoader(getActivity(), getCategoryKey());
mSummaryLoader.setSummaryConsumer(this);
- final TypedArray a = context.obtainStyledAttributes(new int[] {
+ final TypedArray a = context.obtainStyledAttributes(new int[]{
android.R.attr.colorControlNormal});
final int tintColor = a.getColor(0, context.getColor(android.R.color.white));
a.recycle();
@@ -370,8 +352,11 @@ public abstract class DashboardFragment extends SettingsPreferenceFragment
if (!displayTile(tile)) {
continue;
}
- if (tintTileIcon(tile)) {
- tile.getIcon(context).setTint(tintColor);
+ if (tile.isIconTintable(context)) {
+ final Icon icon = tile.getIcon(context);
+ if (icon != null) {
+ icon.setTint(tintColor);
+ }
}
if (mDashboardTilePrefKeys.contains(key)) {
// Have the key already, will rebind.
diff --git a/src/com/android/settings/dashboard/SummaryLoader.java b/src/com/android/settings/dashboard/SummaryLoader.java
index ffd62464851..d8694f2bac3 100644
--- a/src/com/android/settings/dashboard/SummaryLoader.java
+++ b/src/com/android/settings/dashboard/SummaryLoader.java
@@ -30,6 +30,8 @@ import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Log;
+import androidx.annotation.VisibleForTesting;
+
import com.android.settings.SettingsActivity;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.drawer.DashboardCategory;
@@ -39,8 +41,6 @@ import com.android.settingslib.utils.ThreadUtils;
import java.lang.reflect.Field;
import java.util.List;
-import androidx.annotation.VisibleForTesting;
-
public class SummaryLoader {
private static final boolean DEBUG = DashboardSummary.DEBUG;
private static final String TAG = "SummaryLoader";
@@ -160,7 +160,7 @@ public class SummaryLoader {
// TODO: Load summary indirectly.
return null;
}
- Bundle metaData = getMetaData(tile);
+ final Bundle metaData = tile.getMetaData();
if (metaData == null) {
if (DEBUG) Log.d(TAG, "No metadata specified for " + tile.intent.getComponent());
return null;
@@ -187,10 +187,6 @@ public class SummaryLoader {
return null;
}
- private Bundle getMetaData(Tile tile) {
- return tile.metaData;
- }
-
/**
* Registers a receiver and automatically unregisters it when the activity is stopping.
* This ensures that the receivers are unregistered immediately, since most summary loader
diff --git a/src/com/android/settings/dashboard/profileselector/ProfileSelectDialog.java b/src/com/android/settings/dashboard/profileselector/ProfileSelectDialog.java
new file mode 100644
index 00000000000..e56c58b1903
--- /dev/null
+++ b/src/com/android/settings/dashboard/profileselector/ProfileSelectDialog.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2015 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.dashboard.profileselector;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.app.FragmentManager;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.util.Log;
+
+import com.android.settingslib.drawer.Tile;
+
+import java.util.List;
+
+public class ProfileSelectDialog extends DialogFragment implements OnClickListener {
+
+ private static final String TAG = "ProfileSelectDialog";
+ private static final String ARG_SELECTED_TILE = "selectedTile";
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+ private Tile mSelectedTile;
+
+ public static void show(FragmentManager manager, Tile tile) {
+ ProfileSelectDialog dialog = new ProfileSelectDialog();
+ Bundle args = new Bundle();
+ args.putParcelable(ARG_SELECTED_TILE, tile);
+ dialog.setArguments(args);
+ dialog.show(manager, "select_profile");
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mSelectedTile = getArguments().getParcelable(ARG_SELECTED_TILE);
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ Context context = getActivity();
+ AlertDialog.Builder builder = new AlertDialog.Builder(context);
+ UserAdapter adapter = UserAdapter.createUserAdapter(UserManager.get(context), context,
+ mSelectedTile.userHandle);
+ builder.setTitle(com.android.settingslib.R.string.choose_profile)
+ .setAdapter(adapter, this);
+
+ return builder.create();
+ }
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ UserHandle user = mSelectedTile.userHandle.get(which);
+ // Show menu on top level items.
+ mSelectedTile.intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ getActivity().startActivityAsUser(mSelectedTile.intent, user);
+ }
+
+ public static void updateUserHandlesIfNeeded(Context context, Tile tile) {
+ List userHandles = tile.userHandle;
+ if (tile.userHandle == null || tile.userHandle.size() <= 1) {
+ return;
+ }
+ final UserManager userManager = UserManager.get(context);
+ for (int i = userHandles.size() - 1; i >= 0; i--) {
+ if (userManager.getUserInfo(userHandles.get(i).getIdentifier()) == null) {
+ if (DEBUG) {
+ Log.d(TAG, "Delete the user: " + userHandles.get(i).getIdentifier());
+ }
+ userHandles.remove(i);
+ }
+ }
+ }
+}
diff --git a/src/com/android/settings/dashboard/profileselector/UserAdapter.java b/src/com/android/settings/dashboard/profileselector/UserAdapter.java
new file mode 100644
index 00000000000..46c87a16002
--- /dev/null
+++ b/src/com/android/settings/dashboard/profileselector/UserAdapter.java
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2014 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.dashboard.profileselector;
+
+import android.app.ActivityManager;
+import android.content.Context;
+import android.content.pm.UserInfo;
+import android.database.DataSetObserver;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.ListAdapter;
+import android.widget.SpinnerAdapter;
+import android.widget.TextView;
+
+import com.android.internal.util.UserIcons;
+import com.android.settingslib.R;
+import com.android.settingslib.drawable.UserIconDrawable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Adapter for a spinner that shows a list of users.
+ */
+public class UserAdapter implements SpinnerAdapter, ListAdapter {
+ /** Holder for user details */
+ public static class UserDetails {
+ private final UserHandle mUserHandle;
+ private final String mName;
+ private final Drawable mIcon;
+
+ public UserDetails(UserHandle userHandle, UserManager um, Context context) {
+ mUserHandle = userHandle;
+ UserInfo userInfo = um.getUserInfo(mUserHandle.getIdentifier());
+ Drawable icon;
+ if (userInfo.isManagedProfile()) {
+ mName = context.getString(R.string.managed_user_title);
+ icon = context.getDrawable(
+ com.android.internal.R.drawable.ic_corp_badge);
+ } else {
+ mName = userInfo.name;
+ final int userId = userInfo.id;
+ if (um.getUserIcon(userId) != null) {
+ icon = new BitmapDrawable(context.getResources(), um.getUserIcon(userId));
+ } else {
+ icon = UserIcons.getDefaultUserIcon(
+ context.getResources(), userId, /* light= */ false);
+ }
+ }
+ this.mIcon = encircle(context, icon);
+ }
+
+ private static Drawable encircle(Context context, Drawable icon) {
+ return new UserIconDrawable(UserIconDrawable.getSizeForList(context))
+ .setIconDrawable(icon).bake();
+ }
+ }
+
+ private ArrayList data;
+ private final LayoutInflater mInflater;
+
+ public UserAdapter(Context context, ArrayList users) {
+ if (users == null) {
+ throw new IllegalArgumentException("A list of user details must be provided");
+ }
+ this.data = users;
+ mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ }
+
+ public UserHandle getUserHandle(int position) {
+ if (position < 0 || position >= data.size()) {
+ return null;
+ }
+ return data.get(position).mUserHandle;
+ }
+
+ @Override
+ public View getDropDownView(int position, View convertView, ViewGroup parent) {
+ final View row = convertView != null ? convertView : createUser(parent);
+
+ UserDetails user = data.get(position);
+ ((ImageView) row.findViewById(android.R.id.icon)).setImageDrawable(user.mIcon);
+ ((TextView) row.findViewById(android.R.id.title)).setText(getTitle(user));
+ return row;
+ }
+
+ private int getTitle(UserDetails user) {
+ int userHandle = user.mUserHandle.getIdentifier();
+ if (userHandle == UserHandle.USER_CURRENT
+ || userHandle == ActivityManager.getCurrentUser()) {
+ return R.string.category_personal;
+ } else {
+ return R.string.category_work;
+ }
+ }
+
+ private View createUser(ViewGroup parent) {
+ return mInflater.inflate(R.layout.user_preference, parent, false);
+ }
+
+ @Override
+ public void registerDataSetObserver(DataSetObserver observer) {
+ // We don't support observers
+ }
+
+ @Override
+ public void unregisterDataSetObserver(DataSetObserver observer) {
+ // We don't support observers
+ }
+
+ @Override
+ public int getCount() {
+ return data.size();
+ }
+
+ @Override
+ public UserAdapter.UserDetails getItem(int position) {
+ return data.get(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return data.get(position).mUserHandle.getIdentifier();
+ }
+
+ @Override
+ public boolean hasStableIds() {
+ return false;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ return getDropDownView(position, convertView, parent);
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ return 0;
+ }
+
+ @Override
+ public int getViewTypeCount() {
+ return 1;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return data.isEmpty();
+ }
+
+ @Override
+ public boolean areAllItemsEnabled() {
+ return true;
+ }
+
+ @Override
+ public boolean isEnabled(int position) {
+ return true;
+ }
+
+ /**
+ * Creates a {@link UserAdapter} if there is more than one
+ * profile on the device.
+ *
+ *
The adapter can be used to populate a spinner that switches between the Settings
+ * app on the different profiles.
+ *
+ * @return a {@link UserAdapter} or null if there is only one
+ * profile.
+ */
+ public static UserAdapter createUserSpinnerAdapter(UserManager userManager, Context context) {
+ List userProfiles = userManager.getUserProfiles();
+ if (userProfiles.size() < 2) {
+ return null;
+ }
+
+ UserHandle myUserHandle = new UserHandle(UserHandle.myUserId());
+ // The first option should be the current profile
+ userProfiles.remove(myUserHandle);
+ userProfiles.add(0, myUserHandle);
+
+ return createUserAdapter(userManager, context, userProfiles);
+ }
+
+ public static UserAdapter createUserAdapter(
+ UserManager userManager, Context context, List userProfiles) {
+ ArrayList userDetails = new ArrayList<>(userProfiles.size());
+ final int count = userProfiles.size();
+ for (int i = 0; i < count; i++) {
+ userDetails.add(new UserDetails(userProfiles.get(i), userManager, context));
+ }
+ return new UserAdapter(context, userDetails);
+ }
+}
diff --git a/src/com/android/settings/print/PrintSettingsFragment.java b/src/com/android/settings/print/PrintSettingsFragment.java
index 899acc70942..2f1f63dcb5b 100644
--- a/src/com/android/settings/print/PrintSettingsFragment.java
+++ b/src/com/android/settings/print/PrintSettingsFragment.java
@@ -45,11 +45,16 @@ import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
+import androidx.loader.app.LoaderManager.LoaderCallbacks;
+import androidx.loader.content.AsyncTaskLoader;
+import androidx.loader.content.Loader;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceCategory;
+
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
-import com.android.settings.utils.ProfileSettingsPreferenceFragment;
import com.android.settings.widget.AppPreference;
import com.android.settingslib.search.SearchIndexable;
@@ -57,12 +62,6 @@ import java.text.DateFormat;
import java.util.ArrayList;
import java.util.List;
-import androidx.loader.app.LoaderManager.LoaderCallbacks;
-import androidx.loader.content.AsyncTaskLoader;
-import androidx.loader.content.Loader;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceCategory;
-
/**
* Fragment with the top level print settings.
*/
diff --git a/src/com/android/settings/utils/ProfileSettingsPreferenceFragment.java b/src/com/android/settings/print/ProfileSettingsPreferenceFragment.java
similarity index 92%
rename from src/com/android/settings/utils/ProfileSettingsPreferenceFragment.java
rename to src/com/android/settings/print/ProfileSettingsPreferenceFragment.java
index e1c4d285dbc..b616ccc4323 100644
--- a/src/com/android/settings/utils/ProfileSettingsPreferenceFragment.java
+++ b/src/com/android/settings/print/ProfileSettingsPreferenceFragment.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.settings.utils;
+package com.android.settings.print;
import android.content.Context;
import android.content.Intent;
@@ -27,7 +27,7 @@ import android.widget.Spinner;
import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
-import com.android.settingslib.drawer.UserAdapter;
+import com.android.settings.dashboard.profileselector.UserAdapter;
/**
* Base fragment class for per profile settings.
@@ -46,8 +46,8 @@ public abstract class ProfileSettingsPreferenceFragment extends SettingsPreferen
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView> parent, View view, int position,
- long id) {
- UserHandle selectedUser = profileSpinnerAdapter.getUserHandle(position);
+ long id) {
+ final UserHandle selectedUser = profileSpinnerAdapter.getUserHandle(position);
if (selectedUser.getIdentifier() != UserHandle.myUserId()) {
Intent intent = new Intent(getIntentActionString());
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
diff --git a/src/com/android/settings/search/SettingsSearchIndexablesProvider.java b/src/com/android/settings/search/SettingsSearchIndexablesProvider.java
index 97f724050d4..26d15f5c53a 100644
--- a/src/com/android/settings/search/SettingsSearchIndexablesProvider.java
+++ b/src/com/android/settings/search/SettingsSearchIndexablesProvider.java
@@ -167,8 +167,8 @@ public class SettingsSearchIndexablesProvider extends SearchIndexablesProvider {
// Build parent-child class pairs for all children listed under this key.
for (Tile tile : category.getTiles()) {
String childClass = null;
- if (tile.metaData != null) {
- childClass = tile.metaData.getString(
+ if (tile.getMetaData() != null) {
+ childClass = tile.getMetaData().getString(
SettingsActivity.META_DATA_KEY_FRAGMENT_CLASS);
}
if (childClass == null) {
diff --git a/tests/robotests/src/com/android/settings/accounts/AccountDetailDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/accounts/AccountDetailDashboardFragmentTest.java
index 33ac5b6fabd..88ed112c703 100644
--- a/tests/robotests/src/com/android/settings/accounts/AccountDetailDashboardFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/accounts/AccountDetailDashboardFragmentTest.java
@@ -57,10 +57,13 @@ public class AccountDetailDashboardFragmentTest {
private AccountDetailDashboardFragment mFragment;
private Context mContext;
+ private ActivityInfo mActivityInfo;
@Before
public void setUp() {
mContext = RuntimeEnvironment.application;
+ mActivityInfo = new ActivityInfo();
+ mActivityInfo.metaData = new Bundle();
final Bundle args = new Bundle();
args.putParcelable(METADATA_USER_HANDLE, UserHandle.CURRENT);
@@ -79,32 +82,26 @@ public class AccountDetailDashboardFragmentTest {
@Test
public void refreshDashboardTiles_HasAccountType_shouldDisplay() {
- final Tile tile = new Tile(new ActivityInfo());
- final Bundle metaData = new Bundle();
- metaData.putString(METADATA_CATEGORY, CategoryKey.CATEGORY_ACCOUNT_DETAIL);
- metaData.putString(METADATA_ACCOUNT_TYPE, "com.abc");
- tile.metaData = metaData;
+ final Tile tile = new Tile(mActivityInfo, CategoryKey.CATEGORY_ACCOUNT_DETAIL);
+ mActivityInfo.metaData.putString(METADATA_CATEGORY, CategoryKey.CATEGORY_ACCOUNT_DETAIL);
+ mActivityInfo.metaData.putString(METADATA_ACCOUNT_TYPE, "com.abc");
assertThat(mFragment.displayTile(tile)).isTrue();
}
@Test
public void refreshDashboardTiles_NoAccountType_shouldNotDisplay() {
- final Tile tile = new Tile(new ActivityInfo());
- final Bundle metaData = new Bundle();
- metaData.putString(METADATA_CATEGORY, CategoryKey.CATEGORY_ACCOUNT_DETAIL);
- tile.metaData = metaData;
+ final Tile tile = new Tile(mActivityInfo, CategoryKey.CATEGORY_ACCOUNT_DETAIL);
+ mActivityInfo.metaData.putString(METADATA_CATEGORY, CategoryKey.CATEGORY_ACCOUNT_DETAIL);
assertThat(mFragment.displayTile(tile)).isFalse();
}
@Test
public void refreshDashboardTiles_OtherAccountType_shouldNotDisplay() {
- final Tile tile = new Tile(new ActivityInfo());
- final Bundle metaData = new Bundle();
- metaData.putString(METADATA_CATEGORY, CategoryKey.CATEGORY_ACCOUNT_DETAIL);
- metaData.putString(METADATA_ACCOUNT_TYPE, "com.other");
- tile.metaData = metaData;
+ final Tile tile = new Tile(mActivityInfo, CategoryKey.CATEGORY_ACCOUNT_DETAIL);
+ mActivityInfo.metaData.putString(METADATA_CATEGORY, CategoryKey.CATEGORY_ACCOUNT_DETAIL);
+ mActivityInfo.metaData.putString(METADATA_ACCOUNT_TYPE, "com.other");
assertThat(mFragment.displayTile(tile)).isFalse();
}
@@ -118,12 +115,12 @@ public class AccountDetailDashboardFragmentTest {
when(packageManager.resolveActivity(any(Intent.class), anyInt()))
.thenReturn(mock(ResolveInfo.class));
- final Tile tile = new Tile(new ActivityInfo());
+ final Tile tile = new Tile(mActivityInfo, CategoryKey.CATEGORY_ACCOUNT_DETAIL);
tile.key = "key";
- tile.metaData = new Bundle();
- tile.metaData.putString(METADATA_CATEGORY, CategoryKey.CATEGORY_ACCOUNT);
- tile.metaData.putString(METADATA_ACCOUNT_TYPE, "com.abc");
- tile.metaData.putString("com.android.settings.intent.action", Intent.ACTION_ASSIST);
+ mActivityInfo.metaData.putString(METADATA_CATEGORY, CategoryKey.CATEGORY_ACCOUNT);
+ mActivityInfo.metaData.putString(METADATA_ACCOUNT_TYPE, "com.abc");
+ mActivityInfo.metaData.putString("com.android.settings.intent.action",
+ Intent.ACTION_ASSIST);
tile.intent = new Intent();
tile.userHandle = null;
mFragment.displayTile(tile);
diff --git a/tests/robotests/src/com/android/settings/dashboard/CategoryManagerTest.java b/tests/robotests/src/com/android/settings/dashboard/CategoryManagerTest.java
index 3bb4a654f43..5b658a98ff0 100644
--- a/tests/robotests/src/com/android/settings/dashboard/CategoryManagerTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/CategoryManagerTest.java
@@ -16,6 +16,8 @@
package com.android.settings.dashboard;
+import static com.android.settingslib.drawer.CategoryKey.CATEGORY_HOMEPAGE;
+
import static com.google.common.truth.Truth.assertThat;
import android.content.ComponentName;
@@ -65,11 +67,9 @@ public class CategoryManagerTest {
@Test
public void backwardCompatCleanupForCategory_shouldNotChangeCategoryForNewKeys() {
- final Tile tile1 = new Tile(mActivityInfo);
- final Tile tile2 = new Tile(mActivityInfo);
- tile1.category = CategoryKey.CATEGORY_ACCOUNT;
- tile2.category = CategoryKey.CATEGORY_ACCOUNT;
- final DashboardCategory category = new DashboardCategory();
+ final Tile tile1 = new Tile(mActivityInfo, CategoryKey.CATEGORY_ACCOUNT);
+ final Tile tile2 = new Tile(mActivityInfo, CategoryKey.CATEGORY_ACCOUNT);
+ final DashboardCategory category = new DashboardCategory(CategoryKey.CATEGORY_ACCOUNT);
category.addTile(tile1);
category.addTile(tile2);
mCategoryByKeyMap.put(CategoryKey.CATEGORY_ACCOUNT, category);
@@ -84,14 +84,12 @@ public class CategoryManagerTest {
@Test
public void backwardCompatCleanupForCategory_shouldNotChangeCategoryForMixedKeys() {
- final Tile tile1 = new Tile(mActivityInfo);
- final Tile tile2 = new Tile(mActivityInfo);
+ final Tile tile1 = new Tile(mActivityInfo, CategoryKey.CATEGORY_ACCOUNT);
final String oldCategory = "com.android.settings.category.wireless";
- tile1.category = CategoryKey.CATEGORY_ACCOUNT;
- tile2.category = oldCategory;
- final DashboardCategory category1 = new DashboardCategory();
+ final Tile tile2 = new Tile(mActivityInfo, oldCategory);
+ final DashboardCategory category1 = new DashboardCategory(CategoryKey.CATEGORY_ACCOUNT);
category1.addTile(tile1);
- final DashboardCategory category2 = new DashboardCategory();
+ final DashboardCategory category2 = new DashboardCategory(oldCategory);
category2.addTile(tile2);
mCategoryByKeyMap.put(CategoryKey.CATEGORY_ACCOUNT, category1);
mCategoryByKeyMap.put(oldCategory, category2);
@@ -108,10 +106,10 @@ public class CategoryManagerTest {
@Test
public void backwardCompatCleanupForCategory_shouldChangeCategoryForOldKeys() {
- final Tile tile1 = new Tile(mActivityInfo);
final String oldCategory = "com.android.settings.category.wireless";
- tile1.category = oldCategory;
- final DashboardCategory category1 = new DashboardCategory();
+ final Tile tile1 = new Tile(mActivityInfo, oldCategory);
+ tile1.setCategory(oldCategory);
+ final DashboardCategory category1 = new DashboardCategory(oldCategory);
category1.addTile(tile1);
mCategoryByKeyMap.put(oldCategory, category1);
mTileByComponentCache.put(new Pair<>("PACKAGE", "CLASS1"), tile1);
@@ -131,23 +129,23 @@ public class CategoryManagerTest {
public void sortCategories_singlePackage_shouldReorderBasedOnPriority() {
// Create some fake tiles that are not sorted.
final String testPackage = "com.android.test";
- final DashboardCategory category = new DashboardCategory();
- final Tile tile1 = new Tile(mActivityInfo);
+ final DashboardCategory category = new DashboardCategory(CATEGORY_HOMEPAGE);
+ final Tile tile1 = new Tile(mActivityInfo, category.key);
tile1.intent =
new Intent().setComponent(new ComponentName(testPackage, "class1"));
tile1.priority = 100;
- final Tile tile2 = new Tile(mActivityInfo);
+ final Tile tile2 = new Tile(mActivityInfo, category.key);
tile2.intent =
new Intent().setComponent(new ComponentName(testPackage, "class2"));
tile2.priority = 50;
- final Tile tile3 = new Tile(mActivityInfo);
+ final Tile tile3 = new Tile(mActivityInfo, category.key);
tile3.intent =
new Intent().setComponent(new ComponentName(testPackage, "class3"));
tile3.priority = 200;
category.addTile(tile1);
category.addTile(tile2);
category.addTile(tile3);
- mCategoryByKeyMap.put(CategoryKey.CATEGORY_HOMEPAGE, category);
+ mCategoryByKeyMap.put(CATEGORY_HOMEPAGE, category);
// Sort their priorities
mCategoryManager.sortCategories(ShadowApplication.getInstance().getApplicationContext(),
@@ -164,23 +162,23 @@ public class CategoryManagerTest {
// Create some fake tiles that are not sorted.
final String testPackage1 = "com.android.test1";
final String testPackage2 = "com.android.test2";
- final DashboardCategory category = new DashboardCategory();
- final Tile tile1 = new Tile(mActivityInfo);
+ final DashboardCategory category = new DashboardCategory(CATEGORY_HOMEPAGE);
+ final Tile tile1 = new Tile(mActivityInfo, category.key);
tile1.intent =
new Intent().setComponent(new ComponentName(testPackage2, "class1"));
tile1.priority = 100;
- final Tile tile2 = new Tile(mActivityInfo);
+ final Tile tile2 = new Tile(mActivityInfo, category.key);
tile2.intent =
new Intent().setComponent(new ComponentName(testPackage1, "class2"));
tile2.priority = 100;
- final Tile tile3 = new Tile(mActivityInfo);
+ final Tile tile3 = new Tile(mActivityInfo, category.key);
tile3.intent =
new Intent().setComponent(new ComponentName(testPackage1, "class3"));
tile3.priority = 50;
category.addTile(tile1);
category.addTile(tile2);
category.addTile(tile3);
- mCategoryByKeyMap.put(CategoryKey.CATEGORY_HOMEPAGE, category);
+ mCategoryByKeyMap.put(CATEGORY_HOMEPAGE, category);
// Sort their priorities
mCategoryManager.sortCategories(mContext, mCategoryByKeyMap);
@@ -195,23 +193,23 @@ public class CategoryManagerTest {
public void sortCategories_internalPackageTiles_shouldSkipTileForInternalPackage() {
// Create some fake tiles that are not sorted.
final String testPackage = mContext.getPackageName();
- final DashboardCategory category = new DashboardCategory();
- final Tile tile1 = new Tile(mActivityInfo);
+ final DashboardCategory category = new DashboardCategory(CATEGORY_HOMEPAGE);
+ final Tile tile1 = new Tile(mActivityInfo, category.key);
tile1.intent =
new Intent().setComponent(new ComponentName(testPackage, "class1"));
tile1.priority = 100;
- final Tile tile2 = new Tile(mActivityInfo);
+ final Tile tile2 = new Tile(mActivityInfo, category.key);
tile2.intent =
new Intent().setComponent(new ComponentName(testPackage, "class2"));
tile2.priority = 100;
- final Tile tile3 = new Tile(mActivityInfo);
+ final Tile tile3 = new Tile(mActivityInfo, category.key);
tile3.intent =
new Intent().setComponent(new ComponentName(testPackage, "class3"));
tile3.priority = 50;
category.addTile(tile1);
category.addTile(tile2);
category.addTile(tile3);
- mCategoryByKeyMap.put(CategoryKey.CATEGORY_HOMEPAGE, category);
+ mCategoryByKeyMap.put(CATEGORY_HOMEPAGE, category);
// Sort their priorities
mCategoryManager.sortCategories(mContext, mCategoryByKeyMap);
@@ -227,24 +225,24 @@ public class CategoryManagerTest {
// Inject one external tile among internal tiles.
final String testPackage = mContext.getPackageName();
final String testPackage2 = "com.google.test2";
- final DashboardCategory category = new DashboardCategory();
- final Tile tile1 = new Tile(mActivityInfo);
+ final DashboardCategory category = new DashboardCategory(CATEGORY_HOMEPAGE);
+ final Tile tile1 = new Tile(mActivityInfo, category.key);
tile1.intent = new Intent().setComponent(new ComponentName(testPackage, "class1"));
tile1.priority = 2;
- final Tile tile2 = new Tile(mActivityInfo);
+ final Tile tile2 = new Tile(mActivityInfo, category.key);
tile2.intent = new Intent().setComponent(new ComponentName(testPackage, "class2"));
tile2.priority = 1;
- final Tile tile3 = new Tile(mActivityInfo);
+ final Tile tile3 = new Tile(mActivityInfo, category.key);
tile3.intent = new Intent().setComponent(new ComponentName(testPackage2, "class0"));
tile3.priority = 0;
- final Tile tile4 = new Tile(mActivityInfo);
+ final Tile tile4 = new Tile(mActivityInfo, category.key);
tile4.intent = new Intent().setComponent(new ComponentName(testPackage, "class3"));
tile4.priority = -1;
category.addTile(tile1);
category.addTile(tile2);
category.addTile(tile3);
category.addTile(tile4);
- mCategoryByKeyMap.put(CategoryKey.CATEGORY_HOMEPAGE, category);
+ mCategoryByKeyMap.put(CATEGORY_HOMEPAGE, category);
// Sort their priorities
mCategoryManager.sortCategories(mContext, mCategoryByKeyMap);
@@ -262,20 +260,20 @@ public class CategoryManagerTest {
final String testPackage = mContext.getPackageName();
final String testPackage2 = "com.google.test2";
final String testPackage3 = "com.abcde.test3";
- final DashboardCategory category = new DashboardCategory();
- final Tile tile1 = new Tile(mActivityInfo);
+ final DashboardCategory category = new DashboardCategory(CATEGORY_HOMEPAGE);
+ final Tile tile1 = new Tile(mActivityInfo, category.key);
tile1.intent = new Intent().setComponent(new ComponentName(testPackage2, "class1"));
tile1.priority = 1;
- final Tile tile2 = new Tile(mActivityInfo);
+ final Tile tile2 = new Tile(mActivityInfo, category.key);
tile2.intent = new Intent().setComponent(new ComponentName(testPackage, "class2"));
tile2.priority = 1;
- final Tile tile3 = new Tile(mActivityInfo);
+ final Tile tile3 = new Tile(mActivityInfo, category.key);
tile3.intent = new Intent().setComponent(new ComponentName(testPackage3, "class3"));
tile3.priority = 1;
category.addTile(tile1);
category.addTile(tile2);
category.addTile(tile3);
- mCategoryByKeyMap.put(CategoryKey.CATEGORY_HOMEPAGE, category);
+ mCategoryByKeyMap.put(CATEGORY_HOMEPAGE, category);
// Sort their priorities
mCategoryManager.sortCategories(mContext, mCategoryByKeyMap);
@@ -290,23 +288,23 @@ public class CategoryManagerTest {
public void filterTiles_noDuplicate_noChange() {
// Create some unique tiles
final String testPackage = mContext.getPackageName();
- final DashboardCategory category = new DashboardCategory();
- final Tile tile1 = new Tile(mActivityInfo);
+ final DashboardCategory category = new DashboardCategory(CATEGORY_HOMEPAGE);
+ final Tile tile1 = new Tile(mActivityInfo, category.key);
tile1.intent =
new Intent().setComponent(new ComponentName(testPackage, "class1"));
tile1.priority = 100;
- final Tile tile2 = new Tile(mActivityInfo);
+ final Tile tile2 = new Tile(mActivityInfo, category.key);
tile2.intent =
new Intent().setComponent(new ComponentName(testPackage, "class2"));
tile2.priority = 100;
- final Tile tile3 = new Tile(mActivityInfo);
+ final Tile tile3 = new Tile(mActivityInfo, category.key);
tile3.intent =
new Intent().setComponent(new ComponentName(testPackage, "class3"));
tile3.priority = 50;
category.addTile(tile1);
category.addTile(tile2);
category.addTile(tile3);
- mCategoryByKeyMap.put(CategoryKey.CATEGORY_HOMEPAGE, category);
+ mCategoryByKeyMap.put(CATEGORY_HOMEPAGE, category);
mCategoryManager.filterDuplicateTiles(mCategoryByKeyMap);
@@ -317,23 +315,23 @@ public class CategoryManagerTest {
public void filterTiles_hasDuplicate_shouldOnlyKeepUniqueTiles() {
// Create tiles pointing to same intent.
final String testPackage = mContext.getPackageName();
- final DashboardCategory category = new DashboardCategory();
- final Tile tile1 = new Tile(mActivityInfo);
+ final DashboardCategory category = new DashboardCategory(CATEGORY_HOMEPAGE);
+ final Tile tile1 = new Tile(mActivityInfo, category.key);
tile1.intent =
new Intent().setComponent(new ComponentName(testPackage, "class1"));
tile1.priority = 100;
- final Tile tile2 = new Tile(mActivityInfo);
+ final Tile tile2 = new Tile(mActivityInfo, category.key);
tile2.intent =
new Intent().setComponent(new ComponentName(testPackage, "class1"));
tile2.priority = 100;
- final Tile tile3 = new Tile(mActivityInfo);
+ final Tile tile3 = new Tile(mActivityInfo, category.key);
tile3.intent =
new Intent().setComponent(new ComponentName(testPackage, "class1"));
tile3.priority = 50;
category.addTile(tile1);
category.addTile(tile2);
category.addTile(tile3);
- mCategoryByKeyMap.put(CategoryKey.CATEGORY_HOMEPAGE, category);
+ mCategoryByKeyMap.put(CATEGORY_HOMEPAGE, category);
mCategoryManager.filterDuplicateTiles(mCategoryByKeyMap);
diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java
index c82343325b6..95eba63c35b 100644
--- a/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java
@@ -50,6 +50,7 @@ import com.android.settings.dashboard.suggestions.SuggestionAdapter;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.SettingsShadowResources;
+import com.android.settingslib.drawer.CategoryKey;
import com.android.settingslib.drawer.Tile;
import com.android.settingslib.drawer.TileUtils;
import com.android.settingslib.utils.IconCache;
@@ -91,6 +92,7 @@ public class DashboardAdapterTest {
MockitoAnnotations.initMocks(this);
mFactory = FakeFeatureFactory.setupForTest();
mActivityInfo = new ActivityInfo();
+ mActivityInfo.metaData = new Bundle();
when(mFactory.dashboardFeatureProvider.shouldTintIcon()).thenReturn(true);
when(mContext.getSystemService(Context.WINDOW_SERVICE)).thenReturn(mWindowManager);
@@ -201,7 +203,7 @@ public class DashboardAdapterTest {
final View view = LayoutInflater.from(context).inflate(R.layout.dashboard_tile, null);
final DashboardAdapter.DashboardItemHolder holder =
new DashboardAdapter.DashboardItemHolder(view);
- final Tile tile = spy(new Tile(mActivityInfo));
+ final Tile tile = spy(new Tile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE));
doReturn(Icon.createWithResource(context, R.drawable.ic_settings))
.when(tile).getIcon(context);
final IconCache iconCache = mock(IconCache.class);
@@ -222,7 +224,7 @@ public class DashboardAdapterTest {
final View view = LayoutInflater.from(context).inflate(R.layout.dashboard_tile, null);
final DashboardAdapter.DashboardItemHolder holder =
new DashboardAdapter.DashboardItemHolder(view);
- final Tile tile = spy(new Tile(mActivityInfo));
+ final Tile tile = spy(new Tile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE));
final Icon icon = Icon.createWithResource(context, R.drawable.ic_settings);
doReturn(icon).when(tile).getIcon(context);
@@ -245,9 +247,8 @@ public class DashboardAdapterTest {
final View view = LayoutInflater.from(context).inflate(R.layout.dashboard_tile, null);
final DashboardAdapter.DashboardItemHolder holder =
new DashboardAdapter.DashboardItemHolder(view);
- final Tile tile = spy(new Tile(mActivityInfo));
- tile.metaData = new Bundle();
- tile.metaData.putInt(TileUtils.META_DATA_PREFERENCE_ICON_BACKGROUND_HINT,
+ final Tile tile = spy(new Tile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE));
+ tile.getMetaData().putInt(TileUtils.META_DATA_PREFERENCE_ICON_BACKGROUND_HINT,
R.color.memory_critical);
doReturn(Icon.createWithResource(context, R.drawable.ic_settings))
.when(tile).getIcon(context);
@@ -271,7 +272,7 @@ public class DashboardAdapterTest {
final View view = LayoutInflater.from(context).inflate(R.layout.dashboard_tile, null);
final DashboardAdapter.DashboardItemHolder holder =
new DashboardAdapter.DashboardItemHolder(view);
- final Tile tile = spy(new Tile(mActivityInfo));
+ final Tile tile = spy(new Tile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE));
doReturn(mock(Icon.class)).when(tile).getIcon(context);
when(tile.getIcon(context).getResPackage()).thenReturn("another.package");
diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardDataTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardDataTest.java
index 3d7eb13bdcd..dfa049446b7 100644
--- a/tests/robotests/src/com/android/settings/dashboard/DashboardDataTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/DashboardDataTest.java
@@ -29,9 +29,14 @@ import static org.mockito.Mockito.when;
import android.app.PendingIntent;
import android.service.settings.suggestions.Suggestion;
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.DiffUtil;
+import androidx.recyclerview.widget.ListUpdateCallback;
+
import com.android.settings.dashboard.conditional.AirplaneModeCondition;
import com.android.settings.dashboard.conditional.Condition;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.drawer.CategoryKey;
import com.android.settingslib.drawer.DashboardCategory;
import com.android.settingslib.drawer.Tile;
@@ -46,10 +51,6 @@ import java.util.Collections;
import java.util.List;
import java.util.Objects;
-import androidx.annotation.NonNull;
-import androidx.recyclerview.widget.DiffUtil;
-import androidx.recyclerview.widget.ListUpdateCallback;
-
@RunWith(SettingsRobolectricTestRunner.class)
public class DashboardDataTest {
@@ -72,7 +73,7 @@ public class DashboardDataTest {
public void SetUp() {
MockitoAnnotations.initMocks(this);
- mDashboardCategory = new DashboardCategory();
+ mDashboardCategory = new DashboardCategory(CategoryKey.CATEGORY_HOMEPAGE);
// Build suggestions
final List suggestions = new ArrayList<>();
@@ -95,7 +96,6 @@ public class DashboardDataTest {
// Build category
mTestCategoryTile.title = TEST_CATEGORY_TILE_TITLE;
- mDashboardCategory.title = "test";
mDashboardCategory.addTile(mTestCategoryTile);
@@ -277,14 +277,16 @@ public class DashboardDataTest {
/**
* Test when using the
* {@link com.android.settings.dashboard.DashboardData.ItemsDataDiffCallback}
- * to transfer List from {@paramref baseDashboardData} to {@paramref diffDashboardData}, whether
+ * to transfer List from {@paramref baseDashboardData} to {@paramref diffDashboardData},
+ * whether
* the transform data result is equals to {@paramref testResultData}
*
* The steps are described below:
* 1. Calculate a {@link androidx.recyclerview.widget.DiffUtil.DiffResult} from
* {@paramref baseDashboardData} to {@paramref diffDashboardData}
*
- * 2. Dispatch the {@link androidx.recyclerview.widget.DiffUtil.DiffResult} calculated from step 1
+ * 2. Dispatch the {@link androidx.recyclerview.widget.DiffUtil.DiffResult} calculated from step
+ * 1
* into {@link ListUpdateResult}
*
* 3. Get result data(a.k.a. baseResultData) from {@link ListUpdateResult} and compare it to
diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java
index 963411d37ad..f3601c457a1 100644
--- a/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java
@@ -101,6 +101,7 @@ public class DashboardFeatureProviderImplTest {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
mActivityInfo = new ActivityInfo();
+ mActivityInfo.metaData = new Bundle();
doReturn(mPackageManager).when(mContext).getPackageManager();
when(mPackageManager.resolveActivity(any(Intent.class), anyInt()))
.thenReturn(new ResolveInfo());
@@ -116,13 +117,12 @@ public class DashboardFeatureProviderImplTest {
@Test
public void bindPreference_shouldBindAllData() {
final Preference preference = new Preference(RuntimeEnvironment.application);
- final Tile tile = spy(new Tile(mActivityInfo));
+ final Tile tile = spy(new Tile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE));
tile.title = "title";
tile.summary = "summary";
doReturn(Icon.createWithBitmap(Bitmap.createBitmap(1, 1, Bitmap.Config.RGB_565)))
.when(tile).getIcon(any(Context.class));
- tile.metaData = new Bundle();
- tile.metaData.putString(SettingsActivity.META_DATA_KEY_FRAGMENT_CLASS, "HI");
+ mActivityInfo.metaData.putString(SettingsActivity.META_DATA_KEY_FRAGMENT_CLASS, "HI");
tile.priority = 10;
mImpl.bindPreferenceToTile(mActivity, MetricsProto.MetricsEvent.SETTINGS_GESTURES,
preference, tile, "123", Preference.DEFAULT_ORDER);
@@ -130,16 +130,15 @@ public class DashboardFeatureProviderImplTest {
assertThat(preference.getTitle()).isEqualTo(tile.title);
assertThat(preference.getSummary()).isEqualTo(tile.summary);
assertThat(preference.getIcon()).isNotNull();
- assertThat(preference.getFragment())
- .isEqualTo(tile.metaData.getString(SettingsActivity.META_DATA_KEY_FRAGMENT_CLASS));
+ assertThat(preference.getFragment()).isEqualTo(
+ mActivityInfo.metaData.getString(SettingsActivity.META_DATA_KEY_FRAGMENT_CLASS));
assertThat(preference.getOrder()).isEqualTo(-tile.priority);
}
@Test
public void bindPreference_noFragmentMetadata_shouldBindIntent() {
final Preference preference = new Preference(RuntimeEnvironment.application);
- final Tile tile = new Tile(mActivityInfo);
- tile.metaData = new Bundle();
+ final Tile tile = new Tile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE);
tile.priority = 10;
tile.intent = new Intent();
tile.intent.setComponent(new ComponentName("pkg", "class"));
@@ -155,8 +154,7 @@ public class DashboardFeatureProviderImplTest {
@Test
public void bindPreference_noFragmentMetadata_shouldBindToProfileSelector() {
final Preference preference = new Preference(RuntimeEnvironment.application);
- final Tile tile = new Tile(mActivityInfo);
- tile.metaData = new Bundle();
+ final Tile tile = new Tile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE);
tile.userHandle = new ArrayList<>();
tile.userHandle.add(mock(UserHandle.class));
tile.userHandle.add(mock(UserHandle.class));
@@ -176,8 +174,7 @@ public class DashboardFeatureProviderImplTest {
@Test
public void bindPreference_noFragmentMetadataSingleUser_shouldBindToDirectLaunchIntent() {
final Preference preference = new Preference(RuntimeEnvironment.application);
- final Tile tile = new Tile(mActivityInfo);
- tile.metaData = new Bundle();
+ final Tile tile = new Tile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE);
tile.userHandle = new ArrayList<>();
tile.userHandle.add(mock(UserHandle.class));
tile.intent = new Intent();
@@ -201,8 +198,7 @@ public class DashboardFeatureProviderImplTest {
@Test
public void bindPreference_toInternalSettingActivity_shouldBindToDirectLaunchIntentAndNotLog() {
final Preference preference = new Preference(RuntimeEnvironment.application);
- final Tile tile = new Tile(mActivityInfo);
- tile.metaData = new Bundle();
+ final Tile tile = new Tile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE);
tile.userHandle = new ArrayList<>();
tile.userHandle.add(mock(UserHandle.class));
tile.intent = new Intent();
@@ -237,7 +233,7 @@ public class DashboardFeatureProviderImplTest {
@Test
public void bindPreference_withNullKeyNullPriority_shouldGenerateKeyAndPriority() {
final Preference preference = new Preference(RuntimeEnvironment.application);
- final Tile tile = new Tile(mActivityInfo);
+ final Tile tile = new Tile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE);
tile.intent = new Intent();
tile.intent.setComponent(new ComponentName("pkg", "class"));
mImpl.bindPreferenceToTile(mActivity, MetricsProto.MetricsEvent.VIEW_UNKNOWN,
@@ -250,7 +246,7 @@ public class DashboardFeatureProviderImplTest {
@Test
public void bindPreference_noSummary_shouldSetSummaryToPlaceholder() {
final Preference preference = new Preference(RuntimeEnvironment.application);
- final Tile tile = new Tile(mActivityInfo);
+ final Tile tile = new Tile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE);
tile.intent = new Intent();
tile.intent.setComponent(new ComponentName("pkg", "class"));
mImpl.bindPreferenceToTile(mActivity, MetricsProto.MetricsEvent.VIEW_UNKNOWN,
@@ -263,7 +259,7 @@ public class DashboardFeatureProviderImplTest {
@Test
public void bindPreference_hasSummary_shouldSetSummary() {
final Preference preference = new Preference(RuntimeEnvironment.application);
- final Tile tile = new Tile(mActivityInfo);
+ final Tile tile = new Tile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE);
tile.summary = "test";
tile.intent = new Intent();
tile.intent.setComponent(new ComponentName("pkg", "class"));
@@ -277,11 +273,10 @@ public class DashboardFeatureProviderImplTest {
@Config(shadows = {ShadowTileUtils.class, ShadowThreadUtils.class})
public void bindPreference_hasSummaryUri_shouldLoadSummaryFromContentProvider() {
final Preference preference = new Preference(RuntimeEnvironment.application);
- final Tile tile = new Tile(mActivityInfo);
+ final Tile tile = new Tile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE);
tile.intent = new Intent();
tile.intent.setComponent(new ComponentName("pkg", "class"));
- tile.metaData = new Bundle();
- tile.metaData.putString(TileUtils.META_DATA_PREFERENCE_SUMMARY_URI,
+ mActivityInfo.metaData.putString(TileUtils.META_DATA_PREFERENCE_SUMMARY_URI,
"content://com.android.settings/tile_summary");
mImpl.bindPreferenceToTile(mActivity, MetricsProto.MetricsEvent.VIEW_UNKNOWN,
@@ -293,7 +288,7 @@ public class DashboardFeatureProviderImplTest {
@Test
public void bindPreference_withNullKeyTileKey_shouldUseTileKey() {
final Preference preference = new Preference(RuntimeEnvironment.application);
- final Tile tile = new Tile(mActivityInfo);
+ final Tile tile = new Tile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE);
tile.key = "key";
tile.intent = new Intent();
tile.intent.setComponent(new ComponentName("pkg", "class"));
@@ -307,13 +302,12 @@ public class DashboardFeatureProviderImplTest {
@Config(shadows = {ShadowTileUtils.class, ShadowThreadUtils.class})
public void bindPreference_withIconUri_shouldLoadIconFromContentProvider() {
final Preference preference = new Preference(RuntimeEnvironment.application);
- final Tile tile = new Tile(mActivityInfo);
+ final Tile tile = new Tile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE);
tile.key = "key";
tile.intent = new Intent();
tile.intent.setComponent(
new ComponentName(RuntimeEnvironment.application.getPackageName(), "class"));
- tile.metaData = new Bundle();
- tile.metaData.putString(TileUtils.META_DATA_PREFERENCE_ICON_URI,
+ mActivityInfo.metaData.putString(TileUtils.META_DATA_PREFERENCE_ICON_URI,
"content://com.android.settings/tile_icon");
mImpl.bindIcon(preference, tile);
@@ -324,8 +318,7 @@ public class DashboardFeatureProviderImplTest {
public void bindPreference_withBaseOrder_shouldOffsetPriority() {
final int baseOrder = 100;
final Preference preference = new Preference(RuntimeEnvironment.application);
- final Tile tile = new Tile(mActivityInfo);
- tile.metaData = new Bundle();
+ final Tile tile = new Tile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE);
tile.priority = 10;
mImpl.bindPreferenceToTile(mActivity, MetricsProto.MetricsEvent.VIEW_UNKNOWN,
preference, tile, "123", baseOrder);
@@ -337,9 +330,8 @@ public class DashboardFeatureProviderImplTest {
public void bindPreference_withOrderMetadata_shouldUseOrderInMetadata() {
final Preference preference = new Preference(RuntimeEnvironment.application);
final int testOrder = -30;
- final Tile tile = new Tile(mActivityInfo);
- tile.metaData = new Bundle();
- tile.metaData.putInt(mImpl.META_DATA_KEY_ORDER, testOrder);
+ final Tile tile = new Tile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE);
+ mActivityInfo.metaData.putInt(mImpl.META_DATA_KEY_ORDER, testOrder);
tile.priority = 10;
mImpl.bindPreferenceToTile(mActivity, MetricsProto.MetricsEvent.VIEW_UNKNOWN,
preference, tile, "123", Preference.DEFAULT_ORDER);
@@ -350,9 +342,8 @@ public class DashboardFeatureProviderImplTest {
@Test
public void bindPreference_invalidOrderMetadata_shouldIgnore() {
final Preference preference = new Preference(RuntimeEnvironment.application);
- final Tile tile = new Tile(mActivityInfo);
- tile.metaData = new Bundle();
- tile.metaData.putString(mImpl.META_DATA_KEY_ORDER, "hello");
+ final Tile tile = new Tile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE);
+ mActivityInfo.metaData.putString(mImpl.META_DATA_KEY_ORDER, "hello");
tile.priority = 10;
mImpl.bindPreferenceToTile(mActivity, MetricsProto.MetricsEvent.VIEW_UNKNOWN,
preference, tile, "123", Preference.DEFAULT_ORDER);
@@ -364,12 +355,11 @@ public class DashboardFeatureProviderImplTest {
public void bindPreference_withIntentActionMetadata_shouldSetLaunchAction() {
Activity activity = Robolectric.buildActivity(Activity.class).get();
final Preference preference = new Preference(RuntimeEnvironment.application);
- final Tile tile = new Tile(mActivityInfo);
+ final Tile tile = new Tile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE);
tile.key = "key";
tile.intent = new Intent();
tile.intent.setComponent(new ComponentName("pkg", "class"));
- tile.metaData = new Bundle();
- tile.metaData.putString("com.android.settings.intent.action", "TestAction");
+ mActivityInfo.metaData.putString("com.android.settings.intent.action", "TestAction");
tile.userHandle = null;
mImpl.bindPreferenceToTile(activity, MetricsProto.MetricsEvent.SETTINGS_GESTURES,
preference, tile, "123", Preference.DEFAULT_ORDER);
@@ -390,12 +380,11 @@ public class DashboardFeatureProviderImplTest {
Activity activity = Robolectric.buildActivity(Activity.class).get();
final ShadowApplication application = ShadowApplication.getInstance();
final Preference preference = new Preference(application.getApplicationContext());
- final Tile tile = new Tile(mActivityInfo);
+ final Tile tile = new Tile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE);
tile.key = "key";
tile.intent = new Intent();
tile.intent.setComponent(new ComponentName("pkg", "class"));
- tile.metaData = new Bundle();
- tile.metaData.putString("com.android.settings.intent.action", "TestAction");
+ mActivityInfo.metaData.putString("com.android.settings.intent.action", "TestAction");
tile.userHandle = null;
mImpl.bindPreferenceToTile(activity, MetricsProto.MetricsEvent.SETTINGS_GESTURES,
@@ -425,7 +414,7 @@ public class DashboardFeatureProviderImplTest {
mImpl = new DashboardFeatureProviderImpl(mActivity);
ReflectionHelpers.setField(mImpl, "mCategoryManager", mCategoryManager);
when(mCategoryManager.getTilesByCategory(mActivity, CategoryKey.CATEGORY_HOMEPAGE))
- .thenReturn(new DashboardCategory());
+ .thenReturn(new DashboardCategory(CategoryKey.CATEGORY_HOMEPAGE));
assertThat(mImpl.getPreferencesForCategory(null, null,
MetricsProto.MetricsEvent.SETTINGS_GESTURES, CategoryKey.CATEGORY_HOMEPAGE))
@@ -436,8 +425,8 @@ public class DashboardFeatureProviderImplTest {
public void getPreferences_hasTileForCategory_shouldReturnPrefList() {
mImpl = new DashboardFeatureProviderImpl(mActivity);
ReflectionHelpers.setField(mImpl, "mCategoryManager", mCategoryManager);
- final DashboardCategory category = new DashboardCategory();
- category.addTile(new Tile(mActivityInfo));
+ final DashboardCategory category = new DashboardCategory(CategoryKey.CATEGORY_HOMEPAGE);
+ category.addTile(new Tile(mActivityInfo, category.key));
when(mCategoryManager
.getTilesByCategory(any(Context.class), eq(CategoryKey.CATEGORY_HOMEPAGE)))
.thenReturn(category);
@@ -467,8 +456,7 @@ public class DashboardFeatureProviderImplTest {
@Test
public void openTileIntent_profileSelectionDialog_shouldShow() {
- final Tile tile = new Tile(mActivityInfo);
- tile.metaData = new Bundle();
+ final Tile tile = new Tile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE);
tile.intent = new Intent();
tile.intent.setComponent(new ComponentName("pkg", "class"));
final ArrayList handles = new ArrayList<>();
@@ -484,9 +472,8 @@ public class DashboardFeatureProviderImplTest {
@Test
public void openTileIntent_profileSelectionDialog_explicitMetadataShouldShow() {
- final Tile tile = new Tile(mActivityInfo);
- tile.metaData = new Bundle();
- tile.metaData.putString(META_DATA_KEY_PROFILE, PROFILE_ALL);
+ mActivityInfo.metaData.putString(META_DATA_KEY_PROFILE, PROFILE_ALL);
+ final Tile tile = new Tile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE);
tile.intent = new Intent();
tile.intent.setComponent(new ComponentName("pkg", "class"));
final ArrayList handles = new ArrayList<>();
@@ -502,9 +489,8 @@ public class DashboardFeatureProviderImplTest {
@Test
public void openTileIntent_profileSelectionDialog_shouldNotShow() {
- final Tile tile = new Tile(mActivityInfo);
- tile.metaData = new Bundle();
- tile.metaData.putString(META_DATA_KEY_PROFILE, PROFILE_PRIMARY);
+ mActivityInfo.metaData.putString(META_DATA_KEY_PROFILE, PROFILE_PRIMARY);
+ final Tile tile = new Tile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE);
tile.intent = new Intent();
tile.intent.setComponent(new ComponentName("pkg", "class"));
final ArrayList handles = new ArrayList<>();
diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java
index 8c1b99b6e8e..90bd7db6cca 100644
--- a/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java
@@ -17,9 +17,7 @@ package com.android.settings.dashboard;
import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.nullable;
-import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
@@ -27,11 +25,8 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.content.ComponentName;
import android.content.Context;
-import android.content.Intent;
import android.content.pm.ActivityInfo;
-import android.graphics.drawable.Icon;
import android.os.Bundle;
import androidx.preference.Preference;
@@ -45,7 +40,6 @@ import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin;
import com.android.settingslib.drawer.DashboardCategory;
import com.android.settingslib.drawer.Tile;
-import com.android.settingslib.drawer.TileUtils;
import org.junit.Before;
import org.junit.Test;
@@ -74,8 +68,8 @@ public class DashboardFragmentTest {
mContext = spy(RuntimeEnvironment.application);
mActivityInfo = new ActivityInfo();
mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
- mDashboardCategory = new DashboardCategory();
- mDashboardCategory.addTile(new Tile(mActivityInfo));
+ mDashboardCategory = new DashboardCategory("key");
+ mDashboardCategory.addTile(new Tile(mActivityInfo, mDashboardCategory.key));
mTestFragment = new TestFragment(RuntimeEnvironment.application);
when(mFakeFeatureFactory.dashboardFeatureProvider
.getTilesForCategory(nullable(String.class)))
@@ -181,42 +175,6 @@ public class DashboardFragmentTest {
verify(mockController2).getPreferenceKey();
}
- @Test
- public void tintTileIcon_hasMetadata_shouldReturnIconTintableMetadata() {
- final Tile tile = spy(new Tile(mActivityInfo));
- doReturn(mock(Icon.class)).when(tile).getIcon(any(Context.class));
- final Bundle metaData = new Bundle();
- tile.metaData = metaData;
-
- metaData.putBoolean(TileUtils.META_DATA_PREFERENCE_ICON_TINTABLE, false);
- assertThat(mTestFragment.tintTileIcon(tile)).isFalse();
-
- metaData.putBoolean(TileUtils.META_DATA_PREFERENCE_ICON_TINTABLE, true);
- assertThat(mTestFragment.tintTileIcon(tile)).isTrue();
- }
-
- @Test
- public void tintTileIcon_noIcon_shouldReturnFalse() {
- final Tile tile = new Tile(mActivityInfo);
- tile.metaData = new Bundle();
-
- assertThat(mTestFragment.tintTileIcon(tile)).isFalse();
- }
-
- @Test
- public void tintTileIcon_noMetadata_shouldReturnPackageNameCheck() {
- final Tile tile = spy(new Tile(mActivityInfo));
- doReturn(mock(Icon.class)).when(tile).getIcon(any(Context.class));
- final Intent intent = new Intent();
- tile.intent = intent;
- intent.setComponent(
- new ComponentName(RuntimeEnvironment.application.getPackageName(), "TestClass"));
- assertThat(mTestFragment.tintTileIcon(tile)).isFalse();
-
- intent.setComponent(new ComponentName("OtherPackage", "TestClass"));
- assertThat(mTestFragment.tintTileIcon(tile)).isTrue();
- }
-
public static class TestPreferenceController extends AbstractPreferenceController
implements PreferenceControllerMixin {
diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardItemAnimatorTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardItemAnimatorTest.java
index b1d2031d7b6..543bfdb3a5c 100644
--- a/tests/robotests/src/com/android/settings/dashboard/DashboardItemAnimatorTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/DashboardItemAnimatorTest.java
@@ -25,6 +25,7 @@ import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.drawer.CategoryKey;
import com.android.settingslib.drawer.Tile;
import org.junit.Before;
@@ -42,7 +43,7 @@ public class DashboardItemAnimatorTest {
public void SetUp() {
mDashboardItemAnimator = new DashboardItemAnimator();
mViewHolder = new ViewHolder(new TextView(RuntimeEnvironment.application));
- mViewHolder.itemView.setTag(new Tile(new ActivityInfo()));
+ mViewHolder.itemView.setTag(new Tile(new ActivityInfo(), CategoryKey.CATEGORY_HOMEPAGE));
}
@Test
diff --git a/tests/robotests/src/com/android/settings/dashboard/SummaryLoaderTest.java b/tests/robotests/src/com/android/settings/dashboard/SummaryLoaderTest.java
index 053bc9ce76c..e207cab2c5b 100644
--- a/tests/robotests/src/com/android/settings/dashboard/SummaryLoaderTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/SummaryLoaderTest.java
@@ -53,7 +53,7 @@ public class SummaryLoaderTest {
MockitoAnnotations.initMocks(this);
mFeatureFactory = FakeFeatureFactory.setupForTest();
- mTile = new Tile(new ActivityInfo());
+ mTile = new Tile(new ActivityInfo(), CategoryKey.CATEGORY_HOMEPAGE);
mTile.summary = SUMMARY_1;
mCallbackInvoked = false;
@@ -85,8 +85,8 @@ public class SummaryLoaderTest {
@Test
public void testUpdateSummaryToCache_hasCache_shouldUpdate() {
final String testSummary = "test_summary";
- final DashboardCategory category = new DashboardCategory();
- final Tile tile = new Tile(new ActivityInfo());
+ final DashboardCategory category = new DashboardCategory(CategoryKey.CATEGORY_HOMEPAGE);
+ final Tile tile = new Tile(new ActivityInfo(), category.key);
tile.key = "123";
tile.intent = new Intent();
category.addTile(tile);
diff --git a/tests/robotests/src/com/android/settings/dashboard/profileselector/ProfileSelectDialogTest.java b/tests/robotests/src/com/android/settings/dashboard/profileselector/ProfileSelectDialogTest.java
new file mode 100644
index 00000000000..4c2ef427066
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/dashboard/profileselector/ProfileSelectDialogTest.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2016 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.dashboard.profileselector;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.UserInfo;
+import android.os.UserHandle;
+import android.os.UserManager;
+
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.drawer.CategoryKey;
+import com.android.settingslib.drawer.Tile;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class ProfileSelectDialogTest {
+
+ private static final UserHandle NORMAL_USER = UserHandle.of(1111);
+ private static final UserHandle REMOVED_USER = UserHandle.of(2222);
+
+ @Mock
+ private Context mContext;
+ @Mock
+ private UserManager mUserManager;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
+ final UserInfo userInfo = new UserInfo(
+ NORMAL_USER.getIdentifier(), "test_user", UserInfo.FLAG_RESTRICTED);
+ when(mUserManager.getUserInfo(NORMAL_USER.getIdentifier())).thenReturn(userInfo);
+ }
+
+ @Test
+ public void updateUserHandlesIfNeeded_Normal() {
+ final Tile tile = new Tile(new ActivityInfo(), CategoryKey.CATEGORY_HOMEPAGE);
+ tile.intent = new Intent();
+ tile.userHandle.add(NORMAL_USER);
+
+ ProfileSelectDialog.updateUserHandlesIfNeeded(mContext, tile);
+
+ assertThat(tile.userHandle).hasSize(1);
+ assertThat(tile.userHandle.get(0).getIdentifier()).isEqualTo(NORMAL_USER.getIdentifier());
+ verify(mUserManager, never()).getUserInfo(NORMAL_USER.getIdentifier());
+ }
+
+ @Test
+ public void updateUserHandlesIfNeeded_Remove() {
+ final Tile tile = new Tile(new ActivityInfo(), CategoryKey.CATEGORY_HOMEPAGE);
+ tile.intent = new Intent();
+ tile.userHandle.add(REMOVED_USER);
+ tile.userHandle.add(NORMAL_USER);
+ tile.userHandle.add(REMOVED_USER);
+
+ ProfileSelectDialog.updateUserHandlesIfNeeded(mContext, tile);
+
+ assertThat(tile.userHandle).hasSize(1);
+ assertThat(tile.userHandle.get(0).getIdentifier()).isEqualTo(NORMAL_USER.getIdentifier());
+ verify(mUserManager, times(1)).getUserInfo(NORMAL_USER.getIdentifier());
+ verify(mUserManager, times(2)).getUserInfo(REMOVED_USER.getIdentifier());
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImplTest.java
index ffd25c34c2b..ea1af69e171 100644
--- a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImplTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImplTest.java
@@ -36,6 +36,7 @@ import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.SettingsShadowResources;
import com.android.settings.testutils.shadow.ShadowSecureSettings;
+import com.android.settingslib.drawer.CategoryKey;
import com.android.settingslib.drawer.Tile;
import com.android.settingslib.suggestions.SuggestionControllerMixinCompat;
@@ -144,13 +145,13 @@ public class SuggestionFeatureProviderImplTest {
@Test
public void filterExclusiveSuggestions_shouldOnlyKeepFirst3() {
final List suggestions = new ArrayList<>();
- suggestions.add(new Tile(mActivityInfo));
- suggestions.add(new Tile(mActivityInfo));
- suggestions.add(new Tile(mActivityInfo));
- suggestions.add(new Tile(mActivityInfo));
- suggestions.add(new Tile(mActivityInfo));
- suggestions.add(new Tile(mActivityInfo));
- suggestions.add(new Tile(mActivityInfo));
+ suggestions.add(new Tile(mActivityInfo, CategoryKey.CATEGORY_APPS));
+ suggestions.add(new Tile(mActivityInfo, CategoryKey.CATEGORY_APPS));
+ suggestions.add(new Tile(mActivityInfo, CategoryKey.CATEGORY_APPS));
+ suggestions.add(new Tile(mActivityInfo, CategoryKey.CATEGORY_APPS));
+ suggestions.add(new Tile(mActivityInfo, CategoryKey.CATEGORY_APPS));
+ suggestions.add(new Tile(mActivityInfo, CategoryKey.CATEGORY_APPS));
+ suggestions.add(new Tile(mActivityInfo, CategoryKey.CATEGORY_APPS));
mProvider.filterExclusiveSuggestions(suggestions);
diff --git a/tests/robotests/src/com/android/settings/testutils/SettingsRobolectricTestRunner.java b/tests/robotests/src/com/android/settings/testutils/SettingsRobolectricTestRunner.java
index 98693e3e44a..ad808fcd8db 100644
--- a/tests/robotests/src/com/android/settings/testutils/SettingsRobolectricTestRunner.java
+++ b/tests/robotests/src/com/android/settings/testutils/SettingsRobolectricTestRunner.java
@@ -84,9 +84,9 @@ public class SettingsRobolectricTestRunner extends RobolectricTestRunner {
paths.add(new ResourcePath(null,
Fs.fromURL(new URL("file:frameworks/opt/setupwizard/library/recyclerview/res")), null));
paths.add(new ResourcePath(null,
- Fs.fromURL(new URL("file:frameworks/support/appcompat/res")), null));
+ Fs.fromURL(new URL("file:out/soong/.intermediates/prebuilts/sdk/current/androidx/androidx.appcompat_appcompat-nodeps/android_common/aar/res/")), null));
paths.add(new ResourcePath(null,
- Fs.fromURL(new URL("file:frameworks/support/cardview/res")), null));
+ Fs.fromURL(new URL("file:out/soong/.intermediates/prebuilts/sdk/current/androidx/androidx.cardview_cardview-nodeps/android_common/aar/res")), null));
} catch (MalformedURLException e) {
throw new RuntimeException("SettingsRobolectricTestRunner failure", e);
}