Prevent launcher switching in Settings app.

User won't be able to switch to launchers that do not support
managed profiles.
Additional explanation is shown in text under the name of the
launcher.

Bug:15099904

Change-Id: I12470bf396d41ef47d463ef42835964aacda9719
diff --git a/res/layout/preference_home_app.xml b/res/layout/preference_home_app.xml
index 0ee154e..9415752 100644
--- a/res/layout/preference_home_app.xml
+++ b/res/layout/preference_home_app.xml
@@ -30,6 +30,7 @@
         android:clickable="true"
         android:gravity="center_vertical"
         android:background="?android:attr/selectableItemBackground" >
+
             <RadioButton
                 android:id="@+id/home_radio"
                 android:layout_width="wrap_content"
@@ -40,6 +41,7 @@
                 android:orientation="vertical"
                 android:clickable="false"
                 android:focusable="false" />
+
             <ImageView
                 android:id="@+android:id/icon"
                 android:layout_width="48dp"
@@ -47,17 +49,35 @@
                 android:layout_gravity="center"
                 android:minWidth="48dp"
                 android:scaleType="centerInside"
-                android:layout_marginEnd="@*android:dimen/preference_item_padding_inner"
-                />
-            <TextView
-                android:id="@+android:id/title"
+                android:layout_marginEnd="@*android:dimen/preference_item_padding_inner" />
+
+            <LinearLayout
                 android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:singleLine="true"
+                android:layout_height="match_parent"
                 android:layout_weight="1"
-                android:textAppearance="?android:attr/textAppearanceMedium"
-                android:ellipsize="end" />
+                android:focusable="true"
+                android:clickable="true"
+                android:gravity="center_vertical"
+                android:orientation="vertical">
+
+                    <TextView
+                        android:id="@+android:id/title"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:singleLine="true"
+                        android:textAppearance="?android:attr/textAppearanceMedium"
+                        android:ellipsize="end" />
+
+                    <TextView
+                        android:id="@+android:id/summary"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:textAppearance="?android:attr/textAppearanceSmall" />
+
+            </LinearLayout>
+
     </LinearLayout>
+
     <View
         android:id="@+id/home_divider"
         android:layout_width="2dip"
@@ -65,6 +85,7 @@
         android:layout_marginTop="5dip"
         android:layout_marginBottom="5dip"
         android:background="@android:drawable/divider_horizontal_dark" />
+
     <ImageView
         android:id="@+id/home_app_uninstall"
         android:layout_width="wrap_content"
@@ -77,4 +98,5 @@
         android:clickable="true"
         android:focusable="true"
         android:background="?android:attr/selectableItemBackground" />
+
 </LinearLayout>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 5a87472..c7cf8dd 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1923,6 +1923,10 @@
     <!-- Sound settings screen, the caption of the checkbox for having the notification volume be
          the same as the incoming call volume. -->
     <string name="checkbox_notification_same_as_incoming_call">Use incoming call volume for notifications</string>
+
+    <!-- Home settings screen, text indicating that a launcer does not support work profiles [CHAR LIMIT=100] -->
+    <string name="home_work_profile_not_supported">Doesn\'t support work profiles</string>
+
     <!-- Sound settings screen, setting option title-->
     <string name="notification_sound_dialog_title">Default notification sound</string>
     <!-- Sound settings screen, setting option name -->
diff --git a/src/com/android/settings/HomeSettings.java b/src/com/android/settings/HomeSettings.java
index 845fe1e..817c61a 100644
--- a/src/com/android/settings/HomeSettings.java
+++ b/src/com/android/settings/HomeSettings.java
@@ -32,18 +32,22 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.res.Resources;
+import android.content.pm.UserInfo;
 import android.graphics.ColorFilter;
 import android.graphics.ColorMatrix;
 import android.graphics.ColorMatrixColorFilter;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
+import android.os.UserManager;
 import android.preference.Preference;
 import android.preference.PreferenceGroup;
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.View;
+import android.view.ViewGroup;
 import android.view.View.OnClickListener;
 import android.widget.ImageView;
 import android.widget.RadioButton;
@@ -171,6 +175,7 @@
         mPrefs = new ArrayList<HomeAppPreference>();
         mHomeComponentSet = new ComponentName[homeActivities.size()];
         int prefIndex = 0;
+        boolean hasManagedProfile = hasManagedProfile();
         for (int i = 0; i < homeActivities.size(); i++) {
             final ResolveInfo candidate = homeActivities.get(i);
             final ActivityInfo info = candidate.activityInfo;
@@ -179,11 +184,19 @@
             try {
                 Drawable icon = info.loadIcon(mPm);
                 CharSequence name = info.loadLabel(mPm);
-                HomeAppPreference pref = new HomeAppPreference(context, activityName, prefIndex,
-                        icon, name, this, info);
+                HomeAppPreference pref;
+
+                if (hasManagedProfile && !launcherHasManagedProfilesFeature(candidate)) {
+                    pref = new HomeAppPreference(context, activityName, prefIndex,
+                            icon, name, this, info, false /* not enabled */,
+                            getResources().getString(R.string.home_work_profile_not_supported));
+                } else  {
+                    pref = new HomeAppPreference(context, activityName, prefIndex,
+                            icon, name, this, info, true /* enabled */, null);
+                }
+
                 mPrefs.add(pref);
                 mPrefGroup.addPreference(pref);
-                pref.setEnabled(true);
                 if (activityName.equals(currentDefaultHome)) {
                     mCurrentHome = pref;
                 }
@@ -202,6 +215,31 @@
         }
     }
 
+    private boolean hasManagedProfile() {
+        Context context = getActivity();
+        UserManager userManager = (UserManager) getSystemService(Context.USER_SERVICE);
+        List<UserInfo> profiles = userManager.getProfiles(context.getUserId());
+        for (UserInfo userInfo : profiles) {
+            if (userInfo.isManagedProfile()) return true;
+        }
+        return false;
+    }
+
+    private boolean launcherHasManagedProfilesFeature(ResolveInfo resolveInfo) {
+        try {
+            ApplicationInfo appInfo = getPackageManager().getApplicationInfo(
+                    resolveInfo.activityInfo.packageName, 0 /* default flags */);
+            return versionNumberAtLeastL(appInfo.targetSdkVersion);
+        } catch (PackageManager.NameNotFoundException e) {
+            return false;
+        }
+    }
+
+    private boolean versionNumberAtLeastL(int versionNumber) {
+        // TODO: remove "|| true" once the build code for L is fixed.
+        return versionNumber >= Build.VERSION_CODES.L || true;
+    }
+
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -245,12 +283,14 @@
         String uninstallTarget;
 
         public HomeAppPreference(Context context, ComponentName activity,
-                int i, Drawable icon, CharSequence title,
-                HomeSettings parent, ActivityInfo info) {
+                int i, Drawable icon, CharSequence title, HomeSettings parent, ActivityInfo info,
+                boolean enabled, CharSequence summary) {
             super(context);
             setLayoutResource(R.layout.preference_home_app);
             setIcon(icon);
             setTitle(title);
+            setEnabled(enabled);
+            setSummary(summary);
             activityName = activity;
             fragment = parent;
             index = i;
@@ -305,13 +345,15 @@
                 icon.setEnabled(false);
                 icon.setColorFilter(grayscaleFilter);
             } else {
+                icon.setEnabled(true);
                 icon.setOnClickListener(mDeleteClickListener);
                 icon.setTag(indexObj);
             }
 
             View v = view.findViewById(R.id.home_app_pref);
-            v.setOnClickListener(mHomeClickListener);
             v.setTag(indexObj);
+
+            v.setOnClickListener(mHomeClickListener);
         }
 
         void setChecked(boolean state) {