Merge "Fix bluetooth device forgetting" into nyc-dev
diff --git a/res/layout-sw600dp/confirm_lock_password.xml b/res/layout-sw600dp/confirm_lock_password.xml
index 7ccf330..8230ed2 100644
--- a/res/layout-sw600dp/confirm_lock_password.xml
+++ b/res/layout-sw600dp/confirm_lock_password.xml
@@ -16,8 +16,7 @@
   -->
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:paddingTop="48dp">
+    android:layout_height="match_parent">
 
     <include layout="@layout/confirm_lock_password_base"
         android:layout_width="match_parent"
diff --git a/res/layout/confirm_lock_password_base.xml b/res/layout/confirm_lock_password_base.xml
index d92f4f1..b104f07 100644
--- a/res/layout/confirm_lock_password_base.xml
+++ b/res/layout/confirm_lock_password_base.xml
@@ -26,7 +26,8 @@
         android:orientation="vertical"
         android:layout_width="@dimen/confirm_credentials_layout_width"
         android:layout_height="match_parent"
-        android:layout_gravity="top|center_horizontal">
+        android:layout_gravity="top|center_horizontal"
+        android:paddingTop="@dimen/confirm_credentials_top_padding">
 
         <TextView
             style="@android:style/TextAppearance.Material.Headline"
diff --git a/res/layout/confirm_lock_pattern_base.xml b/res/layout/confirm_lock_pattern_base.xml
index ed53fae..c188ccf 100644
--- a/res/layout/confirm_lock_pattern_base.xml
+++ b/res/layout/confirm_lock_pattern_base.xml
@@ -26,7 +26,8 @@
         android:orientation="vertical"
         android:layout_width="@dimen/confirm_credentials_layout_width"
         android:layout_height="match_parent"
-        android:layout_gravity="top|center_horizontal">
+        android:layout_gravity="top|center_horizontal"
+        android:paddingTop="@dimen/confirm_credentials_top_padding">
 
         <TextView
             style="@android:style/TextAppearance.Material.Headline"
diff --git a/res/values-sw600dp/dimens.xml b/res/values-sw600dp/dimens.xml
index e3c748a..7fef6f4 100755
--- a/res/values-sw600dp/dimens.xml
+++ b/res/values-sw600dp/dimens.xml
@@ -74,5 +74,6 @@
 
     <dimen name="confirm_credentials_security_method_margin">72dp</dimen>
     <dimen name="confirm_credentials_layout_width">328dp</dimen>
+    <dimen name="confirm_credentials_top_padding">48dp</dimen>
     <dimen name="fab_margin">24dp</dimen>
 </resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index d302d6d..9d4a97c 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -235,6 +235,7 @@
 
     <dimen name="confirm_credentials_security_method_margin">48dp</dimen>
     <dimen name="confirm_credentials_layout_width">@dimen/match_parent</dimen>
+    <dimen name="confirm_credentials_top_padding">0dp</dimen>
     <dimen name="fab_size">56dp</dimen>
     <dimen name="fab_margin">16dp</dimen>
     <dimen name="fab_elevation">12dp</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 09cfa15..5fa5bf5 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -5392,10 +5392,6 @@
     <string name="user_exit_guest_confirm_message">All apps and data in this session will be deleted.</string>
     <!-- Label for button in confirmation dialog when exiting guest session [CHAR LIMIT=35] -->
     <string name="user_exit_guest_dialog_remove">Remove</string>
-    <!-- Message of dialog to user to confirm that he understands that emergency information is shown in emergency dialer [CHAR LIMIT=none] -->
-    <string name="user_emergency_info_consent">Information you enter here can help first responders in an emergency. It is stored on your device only, but anyone can read it from the emergency dialer without unlocking your phone.</string>
-    <!-- Label for button in confirmation dialog when the user clicks on emergency information [CHAR LIMIT=35] -->
-    <string name="emergency_info_continue">Continue</string>
 
     <!-- Title of preference to enable calling[CHAR LIMIT=40] -->
     <string name="user_enable_calling">Turn on phone calls</string>
diff --git a/src/com/android/settings/TrustedCredentialsSettings.java b/src/com/android/settings/TrustedCredentialsSettings.java
index cb2259f..62394de 100644
--- a/src/com/android/settings/TrustedCredentialsSettings.java
+++ b/src/com/android/settings/TrustedCredentialsSettings.java
@@ -18,8 +18,12 @@
 
 import android.app.AlertDialog;
 import android.app.Dialog;
+import android.app.KeyguardManager;
+import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.pm.UserInfo;
 import android.net.http.SslCertificate;
 import android.os.AsyncTask;
@@ -50,8 +54,10 @@
 import android.widget.TabHost;
 import android.widget.TextView;
 
+import com.android.internal.app.UnlaunchableAppActivity;
 import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.internal.util.ParcelableString;
+import com.android.internal.widget.LockPatternUtils;
 
 import java.security.cert.CertificateEncodingException;
 import java.security.cert.X509Certificate;
@@ -65,6 +71,7 @@
     private static final String TAG = "TrustedCredentialsSettings";
 
     private UserManager mUserManager;
+    private KeyguardManager mKeyguardManager;
 
     private static final String USER_ACTION = "com.android.settings.TRUSTED_CREDENTIALS_USER";
 
@@ -173,13 +180,43 @@
     private final SparseArray<KeyChainConnection>
             mKeyChainConnectionByProfileId = new SparseArray<KeyChainConnection>();
 
+    private BroadcastReceiver mWorkProfileChangedReceiver = new BroadcastReceiver() {
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            final String action = intent.getAction();
+            if (Intent.ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED.equals(action) ||
+                    Intent.ACTION_MANAGED_PROFILE_UNLOCKED.equals(action)) {
+                // Reload all alias
+                final ExpandableListView systemView = (ExpandableListView) mTabHost
+                        .findViewById(Tab.SYSTEM.mExpandableList);
+                if (systemView != null) {
+                    ((TrustedCertificateExpandableAdapter) systemView.getExpandableListAdapter())
+                            .load();
+                }
+                final ExpandableListView userView = (ExpandableListView) mTabHost
+                        .findViewById(Tab.USER.mExpandableList);
+                if (userView != null) {
+                    ((TrustedCertificateExpandableAdapter) userView.getExpandableListAdapter())
+                            .load();
+                }
+            }
+        }
+
+    };
+
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         mUserManager = (UserManager) getActivity().getSystemService(Context.USER_SERVICE);
+        mKeyguardManager = (KeyguardManager) getActivity()
+                .getSystemService(Context.KEYGUARD_SERVICE);
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED);
+        filter.addAction(Intent.ACTION_MANAGED_PROFILE_UNLOCKED);
+        getActivity().registerReceiver(mWorkProfileChangedReceiver, filter);
     }
 
-
     @Override public View onCreateView(
             LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
         mTabHost = (TabHost) inflater.inflate(R.layout.trusted_credentials, parent, false);
@@ -195,6 +232,7 @@
     }
     @Override
     public void onDestroy() {
+        getActivity().unregisterReceiver(mWorkProfileChangedReceiver);
         for (AdapterData.AliasLoader aliasLoader : mAliasLoaders.values()) {
             aliasLoader.cancel(true);
         }
@@ -225,6 +263,29 @@
             final TrustedCertificateExpandableAdapter adapter =
                     new TrustedCertificateExpandableAdapter(tab);
             lv.setAdapter(adapter);
+            lv.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
+                @Override
+                public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition,
+                        long id) {
+                    final UserHandle groupUser = adapter.getGroup(groupPosition);
+                    final int groupUserId = groupUser.getIdentifier();
+                    if (mUserManager.isQuietModeEnabled(groupUser)) {
+                        final Intent intent = UnlaunchableAppActivity.createInQuietModeDialogIntent(
+                                groupUserId);
+                        getActivity().startActivity(intent);
+                        return true;
+                    } else if (!mUserManager.isUserUnlocked(groupUser)) {
+                        final LockPatternUtils lockPatternUtils = new LockPatternUtils(
+                                getActivity());
+                        if (lockPatternUtils.isSeparateProfileChallengeEnabled(groupUserId)) {
+                            startWorkChallenge(groupUserId);
+                            return true;
+                        }
+                    }
+                    return false;
+                }
+
+            });
             lv.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
                     @Override
                 public boolean onChildClick(ExpandableListView parent, View v,
@@ -247,6 +308,17 @@
     }
 
     /**
+     * Start work challenge activity. TODO: Move and refactor this method as a util function.
+     */
+    private void startWorkChallenge(int userId) {
+        final Intent newIntent = mKeyguardManager.createConfirmDeviceCredentialIntent(null, null,
+                userId);
+        newIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+                | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+        getActivity().startActivity(newIntent);
+    }
+
+    /**
      * Common interface for adapters of both expandable and non-expandable certificate lists.
      */
     private interface TrustedCertificateAdapterCommons {
@@ -418,6 +490,11 @@
                 mAliasLoaders.put(mTab, this);
             }
 
+            private boolean shouldSkipProfile(UserHandle userHandle) {
+                return mUserManager.isQuietModeEnabled(userHandle)
+                        || !mUserManager.isUserUnlocked(userHandle.getIdentifier());
+            }
+
             @Override protected void onPreExecute() {
                 View content = mTabHost.getTabContentView();
                 mProgressBar = (ProgressBar) content.findViewById(mTab.mProgress);
@@ -440,6 +517,9 @@
                     for (int i = 0; i < n; ++i) {
                         UserHandle profile = profiles.get(i);
                         int profileId = profile.getIdentifier();
+                        if (shouldSkipProfile(profile)) {
+                            continue;
+                        }
                         KeyChainConnection keyChainConnection = KeyChain.bindAsUser(mContext,
                                 profile);
                         // Saving the connection for later use on the certificate dialog.
@@ -455,6 +535,10 @@
                     for (int i = 0; i < n; ++i) {
                         UserHandle profile = profiles.get(i);
                         int profileId = profile.getIdentifier();
+                        if (shouldSkipProfile(profile)) {
+                            certHoldersByProfile.put(profileId, new ArrayList<CertHolder>(0));
+                            continue;
+                        }
                         List<ParcelableString> aliases = aliasesByProfileId.get(profileId);
                         if (isCancelled()) {
                             return new SparseArray<List<CertHolder>>();
diff --git a/src/com/android/settings/location/SettingsInjector.java b/src/com/android/settings/location/SettingsInjector.java
index 77840fa..18697b8 100644
--- a/src/com/android/settings/location/SettingsInjector.java
+++ b/src/com/android/settings/location/SettingsInjector.java
@@ -16,6 +16,7 @@
 
 package com.android.settings.location;
 
+import android.app.ActivityManager;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
@@ -474,6 +475,15 @@
          * preference when the service replies.
          */
         public void startService() {
+            final ActivityManager am = (ActivityManager)
+                    mContext.getSystemService(Context.ACTIVITY_SERVICE);
+            if (!am.isUserRunning(setting.mUserHandle.getIdentifier())) {
+                if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                    Log.v(TAG, "Cannot start service as user "
+                            + setting.mUserHandle.getIdentifier() + " is not running");
+                }
+                return;
+            }
             Handler handler = new Handler() {
                 @Override
                 public void handleMessage(Message msg) {
diff --git a/src/com/android/settings/print/PrintServiceSettingsFragment.java b/src/com/android/settings/print/PrintServiceSettingsFragment.java
index 6d6967b..e54241c 100644
--- a/src/com/android/settings/print/PrintServiceSettingsFragment.java
+++ b/src/com/android/settings/print/PrintServiceSettingsFragment.java
@@ -341,8 +341,12 @@
         mServiceEnabled = service.isEnabled();
 
         if (service.getSettingsActivityName() != null) {
-            Intent settingsIntent = new Intent(Intent.ACTION_MAIN).setComponent(
-                    ComponentName.unflattenFromString(service.getSettingsActivityName()));
+            Intent settingsIntent = new Intent(Intent.ACTION_MAIN);
+
+            settingsIntent.setComponent(
+                    new ComponentName(service.getComponentName().getPackageName(),
+                            service.getSettingsActivityName()));
+
             List<ResolveInfo> resolvedActivities = getPackageManager().queryIntentActivities(
                     settingsIntent, 0);
             if (!resolvedActivities.isEmpty()) {
@@ -356,9 +360,12 @@
         }
 
         if (service.getAddPrintersActivityName() != null) {
-            Intent addPrintersIntent = new Intent(Intent.ACTION_MAIN)
-                    .setComponent(ComponentName.unflattenFromString(
+            Intent addPrintersIntent = new Intent(Intent.ACTION_MAIN);
+
+            addPrintersIntent.setComponent(
+                    new ComponentName(service.getComponentName().getPackageName(),
                             service.getAddPrintersActivityName()));
+
             List<ResolveInfo> resolvedActivities = getPackageManager().queryIntentActivities(
                     addPrintersIntent, 0);
             if (!resolvedActivities.isEmpty()) {
diff --git a/src/com/android/settings/users/UserSettings.java b/src/com/android/settings/users/UserSettings.java
index d29e612..1c0260f 100644
--- a/src/com/android/settings/users/UserSettings.java
+++ b/src/com/android/settings/users/UserSettings.java
@@ -115,7 +115,6 @@
     private static final int DIALOG_NEED_LOCKSCREEN = 7;
     private static final int DIALOG_CONFIRM_EXIT_GUEST = 8;
     private static final int DIALOG_USER_PROFILE_EDITOR = 9;
-    private static final int DIALOG_EMERGENCY_INFO_CONSENT = 10;
 
     private static final int MESSAGE_UPDATE_LIST = 1;
     private static final int MESSAGE_SETUP_USER = 2;
@@ -609,22 +608,6 @@
                         android.os.Process.myUserHandle());
                 return dlg;
             }
-            case DIALOG_EMERGENCY_INFO_CONSENT : {
-                Dialog dlg = new AlertDialog.Builder(context)
-                        .setTitle(R.string.emergency_info_title)
-                        .setMessage(R.string.user_emergency_info_consent)
-                        .setPositiveButton(R.string.emergency_info_continue,
-                                new DialogInterface.OnClickListener() {
-                                    @Override
-                                    public void onClick(DialogInterface dialog, int which) {
-                                        Intent intent = new Intent(ACTION_EDIT_EMERGENCY_INFO);
-                                        startActivity(intent);
-                                    }
-                                })
-                        .setNegativeButton(android.R.string.cancel, null)
-                        .create();
-                return dlg;
-            }
             default:
                 return null;
         }
@@ -966,7 +949,8 @@
                 onAddUserClicked(USER_TYPE_USER);
             }
         } else if (pref == mEmergencyInfoPreference) {
-            showDialog(DIALOG_EMERGENCY_INFO_CONSENT);
+            Intent intent = new Intent(ACTION_EDIT_EMERGENCY_INFO);
+            startActivity(intent);
         }
         return false;
     }