Merge "Add setting to disable animations"
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 0418d51..4beaf8f 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -178,7 +178,6 @@
         </activity>
 
         <activity android:name=".Settings$ConnectedDeviceDashboardActivity"
-            android:enabled="false"
             android:taskAffinity="com.android.settings"
             android:label="@string/connected_devices_dashboard_title"
             android:icon="@drawable/ic_devices_other"
@@ -204,6 +203,7 @@
         </activity>
 
         <activity android:name=".Settings$ConnectedDeviceDashboardActivityOld"
+                  android:enabled="false"
                   android:taskAffinity="com.android.settings"
                   android:label="@string/connected_devices_dashboard_title"
                   android:icon="@drawable/ic_devices_other"
diff --git a/src/com/android/settings/UserCredentialsSettings.java b/src/com/android/settings/UserCredentialsSettings.java
index 54e12a8..7d0fca0 100644
--- a/src/com/android/settings/UserCredentialsSettings.java
+++ b/src/com/android/settings/UserCredentialsSettings.java
@@ -37,6 +37,8 @@
 import android.security.KeyChain;
 import android.security.KeyChain.KeyChainConnection;
 import android.security.KeyStore;
+import android.security.keymaster.KeyCharacteristics;
+import android.security.keymaster.KeymasterDefs;
 import android.support.v7.widget.RecyclerView;
 import android.util.Log;
 import android.util.SparseArray;
@@ -48,19 +50,15 @@
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
-import com.android.settings.SettingsPreferenceFragment;
 import com.android.settingslib.RestrictedLockUtils;
 import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
-
+import java.security.UnrecoverableKeyException;
 import java.util.ArrayList;
 import java.util.EnumSet;
 import java.util.List;
 import java.util.SortedMap;
 import java.util.TreeMap;
 
-import static android.view.View.GONE;
-import static android.view.View.VISIBLE;
-
 public class UserCredentialsSettings extends SettingsPreferenceFragment
         implements View.OnClickListener {
     private static final String TAG = "UserCredentialsSettings";
@@ -254,27 +252,57 @@
             return credentials;
         }
 
+        private boolean isAsymmetric(KeyStore keyStore, String alias, int uid)
+            throws UnrecoverableKeyException {
+                KeyCharacteristics keyCharacteristics = new KeyCharacteristics();
+                int errorCode = keyStore.getKeyCharacteristics(alias, null, null, uid,
+                        keyCharacteristics);
+                if (errorCode != KeyStore.NO_ERROR) {
+                    throw (UnrecoverableKeyException)
+                            new UnrecoverableKeyException("Failed to obtain information about key")
+                                    .initCause(KeyStore.getKeyStoreException(errorCode));
+                }
+                Integer keymasterAlgorithm = keyCharacteristics.getEnum(
+                        KeymasterDefs.KM_TAG_ALGORITHM);
+                if (keymasterAlgorithm == null) {
+                    throw new UnrecoverableKeyException("Key algorithm unknown");
+                }
+                return keymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_RSA ||
+                        keymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_EC;
+        }
+
         private SortedMap<String, Credential> getCredentialsForUid(KeyStore keyStore, int uid) {
             final SortedMap<String, Credential> aliasMap = new TreeMap<>();
             for (final Credential.Type type : Credential.Type.values()) {
-                for (final String alias : keyStore.list(type.prefix, uid)) {
-                    if (UserHandle.getAppId(uid) == Process.SYSTEM_UID) {
-                        // Do not show work profile keys in user credentials
-                        if (alias.startsWith(LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT) ||
-                                alias.startsWith(LockPatternUtils.PROFILE_KEY_NAME_DECRYPT)) {
+                for (final String prefix : type.prefix) {
+                    for (final String alias : keyStore.list(prefix, uid)) {
+                        if (UserHandle.getAppId(uid) == Process.SYSTEM_UID) {
+                            // Do not show work profile keys in user credentials
+                            if (alias.startsWith(LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT) ||
+                                    alias.startsWith(LockPatternUtils.PROFILE_KEY_NAME_DECRYPT)) {
+                                continue;
+                            }
+                            // Do not show synthetic password keys in user credential
+                            if (alias.startsWith(LockPatternUtils.SYNTHETIC_PASSWORD_KEY_PREFIX)) {
+                                continue;
+                            }
+                        }
+                        try {
+                            if (type == Credential.Type.USER_KEY &&
+                                    !isAsymmetric(keyStore, prefix + alias, uid)) {
+                                continue;
+                            }
+                        } catch (UnrecoverableKeyException e) {
+                            Log.e(TAG, "Unable to determine algorithm of key: " + prefix + alias, e);
                             continue;
                         }
-                        // Do not show synthetic password keys in user credential
-                        if (alias.startsWith(LockPatternUtils.SYNTHETIC_PASSWORD_KEY_PREFIX)) {
-                            continue;
+                        Credential c = aliasMap.get(alias);
+                        if (c == null) {
+                            c = new Credential(alias, uid);
+                            aliasMap.put(alias, c);
                         }
+                        c.storedTypes.add(type);
                     }
-                    Credential c = aliasMap.get(alias);
-                    if (c == null) {
-                        c = new Credential(alias, uid);
-                        aliasMap.put(alias, c);
-                    }
-                    c.storedTypes.add(type);
                 }
             }
             return aliasMap;
@@ -344,7 +372,7 @@
      */
     private static final SparseArray<Credential.Type> credentialViewTypes = new SparseArray<>();
     static {
-        credentialViewTypes.put(R.id.contents_userkey, Credential.Type.USER_PRIVATE_KEY);
+        credentialViewTypes.put(R.id.contents_userkey, Credential.Type.USER_KEY);
         credentialViewTypes.put(R.id.contents_usercrt, Credential.Type.USER_CERTIFICATE);
         credentialViewTypes.put(R.id.contents_cacrt, Credential.Type.CA_CERTIFICATE);
     }
@@ -380,12 +408,11 @@
         static enum Type {
             CA_CERTIFICATE (Credentials.CA_CERTIFICATE),
             USER_CERTIFICATE (Credentials.USER_CERTIFICATE),
-            USER_PRIVATE_KEY (Credentials.USER_PRIVATE_KEY),
-            USER_SECRET_KEY (Credentials.USER_SECRET_KEY);
+            USER_KEY(Credentials.USER_PRIVATE_KEY, Credentials.USER_SECRET_KEY);
 
-            final String prefix;
+            final String[] prefix;
 
-            Type(String prefix) {
+            Type(String... prefix) {
                 this.prefix = prefix;
             }
         }
@@ -407,8 +434,7 @@
          * <ul>
          *   <li>{@link Credentials.CA_CERTIFICATE}</li>
          *   <li>{@link Credentials.USER_CERTIFICATE}</li>
-         *   <li>{@link Credentials.USER_PRIVATE_KEY}</li>
-         *   <li>{@link Credentials.USER_SECRET_KEY}</li>
+         *   <li>{@link Credentials.USER_KEY}</li>
          * </ul>
          */
         final EnumSet<Type> storedTypes = EnumSet.noneOf(Type.class);
diff --git a/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragment.java b/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragment.java
index a4f6e5c..02b1012 100644
--- a/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragment.java
+++ b/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragment.java
@@ -68,12 +68,6 @@
     }
 
     @Override
-    public String getCategoryKey() {
-        //TODO(b/69926683): remove this method and change DashboardFragmentRegistry directly for P
-        return CategoryKey.CATEGORY_DEVICE;
-    }
-
-    @Override
     protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
         final List<AbstractPreferenceController> controllers = new ArrayList<>();
         final Lifecycle lifecycle = getLifecycle();
diff --git a/src/com/android/settings/dashboard/DashboardFragmentRegistry.java b/src/com/android/settings/dashboard/DashboardFragmentRegistry.java
index af00dc6..e841496 100644
--- a/src/com/android/settings/dashboard/DashboardFragmentRegistry.java
+++ b/src/com/android/settings/dashboard/DashboardFragmentRegistry.java
@@ -23,6 +23,7 @@
 import com.android.settings.accounts.UserAndAccountDashboardFragment;
 import com.android.settings.applications.AppAndNotificationDashboardFragment;
 import com.android.settings.applications.DefaultAppSettings;
+import com.android.settings.connecteddevice.AdvancedConnectedDeviceDashboardFragment;
 import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragmentOld;
 import com.android.settings.development.DevelopmentSettingsDashboardFragment;
 import com.android.settings.deviceinfo.StorageDashboardFragment;
@@ -62,6 +63,8 @@
         //TODO(b/69471219): update ConnectedDeviceDashboardFragment once new feature is done.
         PARENT_TO_CATEGORY_KEY_MAP.put(ConnectedDeviceDashboardFragmentOld.class.getName(),
                 CategoryKey.CATEGORY_DEVICE);
+        PARENT_TO_CATEGORY_KEY_MAP.put(AdvancedConnectedDeviceDashboardFragment.class.getName(),
+                CategoryKey.CATEGORY_DEVICE);
         PARENT_TO_CATEGORY_KEY_MAP.put(AppAndNotificationDashboardFragment.class.getName(),
                 CategoryKey.CATEGORY_APPS);
         PARENT_TO_CATEGORY_KEY_MAP.put(PowerUsageSummary.class.getName(),
diff --git a/src/com/android/settings/tts/TextToSpeechSettings.java b/src/com/android/settings/tts/TextToSpeechSettings.java
index 9092c0d..9bb7958 100644
--- a/src/com/android/settings/tts/TextToSpeechSettings.java
+++ b/src/com/android/settings/tts/TextToSpeechSettings.java
@@ -770,7 +770,11 @@
         if (KEY_TTS_ENGINE_PREFERENCE.equals(p.getKey())) {
             EngineInfo info = mEnginesHelper.getEngineInfo(mCurrentEngine);
             final Intent settingsIntent = mEnginesHelper.getSettingsIntent(info.name);
-            startActivity(settingsIntent);
+            if (settingsIntent != null) {
+                startActivity(settingsIntent);
+            } else {
+                Log.e(TAG, "settingsIntent is null");
+            }
         }
     }
 
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragmentTest.java
index 2767570..37ccb76 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragmentTest.java
@@ -148,6 +148,11 @@
     }
 
     @Test
+    public void testGetCategoryKey_returnCategoryDevice() {
+        assertThat(mFragment.getCategoryKey()).isEqualTo(CategoryKey.CATEGORY_DEVICE);
+    }
+
+    @Test
     public void testNonIndexableKeys_existInXmlLayout() {
         final Context context = RuntimeEnvironment.application;
         when(mManager.hasSystemFeature(PackageManager.FEATURE_NFC)).thenReturn(false);
diff --git a/tests/unit/src/com/android/settings/UserCredentialsTest.java b/tests/unit/src/com/android/settings/UserCredentialsTest.java
index 41ef4de..8a72797 100644
--- a/tests/unit/src/com/android/settings/UserCredentialsTest.java
+++ b/tests/unit/src/com/android/settings/UserCredentialsTest.java
@@ -40,7 +40,7 @@
         Credential c = new Credential(alias, Process.SYSTEM_UID);
 
         c.storedTypes.add(Credential.Type.CA_CERTIFICATE);
-        c.storedTypes.add(Credential.Type.USER_SECRET_KEY);
+        c.storedTypes.add(Credential.Type.USER_KEY);
 
         Parcel p = Parcel.obtain();
         c.writeToParcel(p, /* flags */ 0);