OmniGears: add back AppSelectListPreference

Change-Id: I0d3c734e904b5d6918a029b0f1d6fec71a6dfa92
diff --git a/res/drawable/ic_disabled.xml b/res/drawable/ic_disabled.xml
new file mode 100644
index 0000000..1c5152b
--- /dev/null
+++ b/res/drawable/ic_disabled.xml
@@ -0,0 +1,8 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:height="32dp"
+        android:width="32dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24"
+        android:tint="?android:attr/colorAccent" >
+    <path android:fillColor="#fff" android:pathData="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z"/>
+</vector>
diff --git a/res/layout/app_item.xml b/res/layout/app_item.xml
deleted file mode 100644
index 6b3435f..0000000
--- a/res/layout/app_item.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--  Copyright (C) 2016 The OmniROM Project
-
-  This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation, either version 2 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
- -->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:minHeight="?android:attr/listPreferredItemHeight"
-    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
-    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
-    android:paddingTop="8dip"
-    android:paddingBottom="8dip"
-    android:orientation="horizontal" >
-
-    <ImageView
-        android:id="@+id/app_icon"
-        android:layout_width="@android:dimen/app_icon_size"
-        android:layout_height="@android:dimen/app_icon_size"
-        android:layout_marginEnd="8dip"
-        android:layout_gravity="center_vertical"
-        android:scaleType="centerInside"
-        android:contentDescription="@null" />
-
-    <TextView
-        android:id="@+id/app_name"
-        android:layout_width="0dip"
-        android:layout_height="wrap_content"
-        android:layout_weight="1"
-        android:layout_gravity="center_vertical"
-        android:singleLine="true"
-        android:ellipsize="marquee"
-        android:focusable="false"
-        android:textAppearance="?android:attr/textAppearanceListItem"
-        android:textAlignment="viewStart" />
-
-</LinearLayout>
-
diff --git a/res/layout/app_select_item.xml b/res/layout/app_select_item.xml
deleted file mode 100644
index 57a48f9..0000000
--- a/res/layout/app_select_item.xml
+++ /dev/null
@@ -1,58 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--  Copyright (C) 2016 The OmniROM Project
-
-  This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation, either version 2 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
- -->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:minHeight="?android:attr/listPreferredItemHeight"
-    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
-    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
-    android:paddingTop="8dip"
-    android:paddingBottom="8dip"
-    android:orientation="horizontal" >
-
-    <ImageView
-        android:id="@+id/app_icon"
-        android:layout_width="@android:dimen/app_icon_size"
-        android:layout_height="@android:dimen/app_icon_size"
-        android:layout_marginEnd="8dip"
-        android:layout_gravity="center_vertical"
-        android:scaleType="centerInside"
-        android:contentDescription="@null" />
-
-    <TextView
-        android:id="@+id/app_name"
-        android:layout_width="0dip"
-        android:layout_height="wrap_content"
-        android:layout_weight="1"
-        android:layout_gravity="center_vertical"
-        android:singleLine="true"
-        android:ellipsize="marquee"
-        android:focusable="false"
-        android:textAppearance="?android:attr/textAppearanceListItem"
-        android:textAlignment="viewStart" />
-
-    <CheckBox android:id="@android:id/checkbox"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_marginStart="4dip"
-        android:layout_gravity="center_vertical"
-        android:clickable="false"
-        android:focusable="false" />
-
-</LinearLayout>
-
diff --git a/res/layout/applist_preference_icon.xml b/res/layout/applist_preference_icon.xml
index d1972f8..12644d0 100644
--- a/res/layout/applist_preference_icon.xml
+++ b/res/layout/applist_preference_icon.xml
@@ -20,50 +20,30 @@
     android:id="@android:id/widget_frame"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:minHeight="?android:attr/listPreferredItemHeightSmall"
+    android:minHeight="64dp"
     android:gravity="center_vertical"
-    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+    android:paddingStart="6dp"
     android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
     android:background="?android:attr/selectableItemBackground">
 
     <ImageView
         android:id="@+id/icon"
-        android:layout_width="wrap_content"
+        android:layout_width="@android:dimen/app_icon_size"
+        android:layout_height="@android:dimen/app_icon_size"
+        android:layout_gravity="center_vertical"
+        android:layout_marginEnd="8dip"
+        android:scaleType="centerInside" />
+
+    <TextView
+        android:id="@+id/title"
+        android:layout_width="0dip"
         android:layout_height="wrap_content"
-        android:layout_marginEnd="12dip"
-        android:padding="2dp"
-        android:maxWidth="36dip"
-        android:maxHeight="36dip"
-        android:adjustViewBounds="true"
-        android:layout_gravity="center" />
-
-    <RelativeLayout
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_marginStart="2dip"
-        android:layout_marginEnd="6dip"
-        android:layout_marginTop="6dip"
-        android:layout_marginBottom="6dip"
-        android:layout_weight="1">
-
-        <TextView android:id="@android:id/title"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:singleLine="true"
-            android:textAppearance="?android:attr/textAppearanceListItem"
-            android:textColor="?android:attr/textColorPrimary"
-            android:ellipsize="marquee"
-            android:fadingEdge="horizontal" />
-
-        <TextView android:id="@android:id/summary"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_below="@android:id/title"
-            android:layout_alignStart="@android:id/title"
-            android:textAppearance="?android:attr/textAppearanceListItemSecondary"
-            android:textColor="?android:attr/textColorSecondary"
-            android:maxLines="2" />
-
-    </RelativeLayout>
+        android:layout_weight="1"
+        android:layout_gravity="center_vertical"
+        android:ellipsize="end"
+        android:focusable="false"
+        android:singleLine="true"
+        android:textAlignment="viewStart"
+        android:textAppearance="?android:attr/textAppearanceListItem" />
 
 </LinearLayout>
diff --git a/res/layout/preference_app_select.xml b/res/layout/preference_app_select.xml
new file mode 100644
index 0000000..39ebee3
--- /dev/null
+++ b/res/layout/preference_app_select.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2016 The OmniROM Project
+
+  This program is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:minHeight="?android:attr/listPreferredItemHeight"
+    android:gravity="center_vertical"
+    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+    android:background="?android:attr/selectableItemBackground"
+    android:clipToPadding="false"
+    android:orientation="horizontal" >
+
+    <LinearLayout
+        android:id="@+id/icon_frame"
+        style="@style/preference_icon_frame"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:gravity="start|center_vertical"
+        android:orientation="horizontal"
+        android:clipToPadding="false"
+        android:paddingEnd="12dp"
+        android:paddingTop="4dp"
+        android:paddingBottom="4dp">
+        <com.android.internal.widget.PreferenceImageView
+            android:id="@android:id/icon"
+            android:layout_width="48dp"
+            android:layout_height="48dp"
+            android:gravity="center"
+            android:scaleType="centerInside" />
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        android:gravity="center_vertical"
+        android:layout_weight="1" >
+
+        <RelativeLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginEnd="6dip"
+            android:layout_marginTop="10dip"
+            android:layout_marginBottom="6dip" >
+
+            <TextView android:id="@android:id/title"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:singleLine="true"
+                android:textAppearance="?android:attr/textAppearanceListItem"
+                android:ellipsize="marquee" />
+
+            <TextView android:id="@android:id/summary"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_below="@android:id/title"
+                android:layout_alignStart="@android:id/title"
+                android:textAppearance="?android:attr/textAppearanceListItemSecondary"
+                android:textColor="?android:attr/textColorSecondary"
+                android:maxLines="10"
+                android:ellipsize="end" />
+
+        </RelativeLayout>
+    </LinearLayout>
+</LinearLayout>
diff --git a/res/layout/preference_dialog_applist.xml b/res/layout/preference_dialog_applist.xml
new file mode 100644
index 0000000..55ab014
--- /dev/null
+++ b/res/layout/preference_dialog_applist.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The OmniROM 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.
+-->
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="vertical"
+        android:gravity="center_horizontal"
+        android:paddingStart="24dp"
+        android:paddingEnd="24dp" >
+
+     <ListView android:id="@+id/applist"
+               android:layout_width="match_parent"
+               android:layout_height="match_parent"
+               android:divider="@null" />
+
+</LinearLayout>
diff --git a/res/values/custom_strings.xml b/res/values/custom_strings.xml
index 05d3191..bfdf8df 100644
--- a/res/values/custom_strings.xml
+++ b/res/values/custom_strings.xml
@@ -689,4 +689,8 @@
     <string name="fprint_sucess_vib_title">Fingerprint authentication vibration</string>
     <string name="fprint_sucess_vib_summary">Vibrate on successful fingerprint authentication</string>
 
+    <string name="choose_app">Choose app</string>
+    <string name="not_ready_summary">Resolving...</string>
+    <string name="resolve_failed_summary">Resolving app failed</string>
+    <string name="disabled_entry">Disabled</string>
 </resources>
diff --git a/res/xml/preference_app_select.xml b/res/xml/preference_app_select.xml
new file mode 100644
index 0000000..39ebee3
--- /dev/null
+++ b/res/xml/preference_app_select.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2016 The OmniROM Project
+
+  This program is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:minHeight="?android:attr/listPreferredItemHeight"
+    android:gravity="center_vertical"
+    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+    android:background="?android:attr/selectableItemBackground"
+    android:clipToPadding="false"
+    android:orientation="horizontal" >
+
+    <LinearLayout
+        android:id="@+id/icon_frame"
+        style="@style/preference_icon_frame"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:gravity="start|center_vertical"
+        android:orientation="horizontal"
+        android:clipToPadding="false"
+        android:paddingEnd="12dp"
+        android:paddingTop="4dp"
+        android:paddingBottom="4dp">
+        <com.android.internal.widget.PreferenceImageView
+            android:id="@android:id/icon"
+            android:layout_width="48dp"
+            android:layout_height="48dp"
+            android:gravity="center"
+            android:scaleType="centerInside" />
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        android:gravity="center_vertical"
+        android:layout_weight="1" >
+
+        <RelativeLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginEnd="6dip"
+            android:layout_marginTop="10dip"
+            android:layout_marginBottom="6dip" >
+
+            <TextView android:id="@android:id/title"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:singleLine="true"
+                android:textAppearance="?android:attr/textAppearanceListItem"
+                android:ellipsize="marquee" />
+
+            <TextView android:id="@android:id/summary"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_below="@android:id/title"
+                android:layout_alignStart="@android:id/title"
+                android:textAppearance="?android:attr/textAppearanceListItemSecondary"
+                android:textColor="?android:attr/textColorSecondary"
+                android:maxLines="10"
+                android:ellipsize="end" />
+
+        </RelativeLayout>
+    </LinearLayout>
+</LinearLayout>
diff --git a/src/org/omnirom/omnigears/preference/AppSelectListPreference.java b/src/org/omnirom/omnigears/preference/AppSelectListPreference.java
new file mode 100644
index 0000000..8bb838b
--- /dev/null
+++ b/src/org/omnirom/omnigears/preference/AppSelectListPreference.java
@@ -0,0 +1,329 @@
+/*
+* Copyright (C) 2017 The OmniROM Project
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+*/
+package org.omnirom.omnigears.preference;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.os.Message;
+import android.support.v7.preference.PreferenceViewHolder;
+import android.support.v14.preference.PreferenceDialogFragment;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+import com.android.settingslib.CustomDialogPreference;
+import com.android.settings.R;
+
+public class AppSelectListPreference extends CustomDialogPreference {
+
+    private static String TAG = "AppSelectListPreference";
+
+    private AppSelectListAdapter mAdapter;
+    private Drawable mAppIconDrawable;
+    private int mAppIconResourceId;
+    private CharSequence mTitle;
+    private String mValue;
+    private PackageManager mPm;
+
+    public class PackageItem implements Comparable<PackageItem> {
+        public final CharSequence mTitle;
+        public final int mAppIconResourceId;
+        public final ComponentName mComponentName;
+        public final String mValue;
+
+        PackageItem(CharSequence title, int iconResourceId, ComponentName componentName) {
+            mTitle = title;
+            mAppIconResourceId = iconResourceId;
+            mComponentName = componentName;
+            mValue = componentName.flattenToString();
+        }
+
+        PackageItem(CharSequence title, int iconResourceId, String value) {
+            mTitle = title;
+            mAppIconResourceId = iconResourceId;
+            mComponentName = null;
+            mValue = value;
+        }
+
+        @Override
+        public int compareTo(PackageItem another) {
+            return mTitle.toString().toUpperCase().compareTo(another.mTitle.toString().toUpperCase());
+        }
+
+        @Override
+        public int hashCode() {
+            return mValue.hashCode();
+        }
+
+        @Override
+        public boolean equals(Object another) {
+            if (another == null || !(another instanceof PackageItem)) {
+                return false;
+            }
+            return mValue.equals(((PackageItem) another).mValue);
+        }
+    }
+
+    public class AppSelectListAdapter extends BaseAdapter implements Runnable {
+        private LayoutInflater mInflater;
+        private List<PackageItem> mInstalledPackages = new LinkedList<PackageItem>();
+
+        private final Handler mHandler = new Handler() {
+            @Override
+            public void handleMessage(Message msg) {
+                notifyDataSetChanged();
+                updatePreferenceViews();
+            }
+        };
+
+        public AppSelectListAdapter(Context context) {
+            mInflater = LayoutInflater.from(context);
+            reloadList();
+        }
+
+        @Override
+        public int getCount() {
+            return mInstalledPackages.size();
+        }
+
+        @Override
+        public PackageItem getItem(int position) {
+            return mInstalledPackages.get(position);
+        }
+
+        @Override
+        public long getItemId(int position) {
+            return mInstalledPackages.get(position).hashCode();
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            ViewHolder holder;
+            if (convertView != null) {
+                holder = (ViewHolder) convertView.getTag();
+            } else {
+                convertView = mInflater.inflate(R.layout.applist_preference_icon, null, false);
+                holder = new ViewHolder();
+                convertView.setTag(holder);
+                holder.title = (TextView) convertView.findViewById(R.id.title);
+                holder.icon = (ImageView) convertView.findViewById(R.id.icon);
+            }
+
+            PackageItem applicationInfo = getItem(position);
+            holder.title.setText(applicationInfo.mTitle);
+            if (applicationInfo.mAppIconResourceId != 0) {
+                holder.icon.setImageResource(applicationInfo.mAppIconResourceId);
+            } else {
+                Drawable d = resolveAppIcon(applicationInfo);
+                holder.icon.setImageDrawable(d);
+            }
+            return convertView;
+        }
+
+        private void reloadList() {
+            mInstalledPackages.clear();
+            new Thread(this).start();
+        }
+
+        @Override
+        public void run() {
+            final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
+            mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
+            List<ResolveInfo> installedAppsInfo = mPm.queryIntentActivities(mainIntent, 0);
+
+            for (ResolveInfo info : installedAppsInfo) {
+                ActivityInfo activity = info.activityInfo;
+                ApplicationInfo appInfo = activity.applicationInfo;
+                ComponentName componentName = new ComponentName(appInfo.packageName, activity.name);
+                CharSequence label = null;
+                try {
+                    label = activity.loadLabel(mPm);
+                } catch (Exception e) {
+                }
+                if (label != null) {
+                    final PackageItem item = new PackageItem(activity.loadLabel(mPm), 0, componentName);
+                    mInstalledPackages.add(item);
+                }
+            }
+            Collections.sort(mInstalledPackages);
+            mHandler.obtainMessage(0).sendToTarget();
+        }
+
+        private PackageItem resolveApplication(ComponentName componentName) {
+            for (PackageItem item : mInstalledPackages) {
+                if (item.mComponentName != null && item.mComponentName.equals(componentName)) {
+                    return item;
+                }
+            }
+            return null;
+        }
+
+        private class ViewHolder {
+            TextView title;
+            TextView summary;
+            ImageView icon;
+        }
+    }
+
+    public AppSelectListPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        init();
+    }
+
+    public AppSelectListPreference(Context context, int color) {
+        super(context, null);
+        init();
+    }
+
+    private void init() {
+        mPm = getContext().getPackageManager();
+        setDialogLayoutResource(R.layout.preference_dialog_applist);
+        setLayoutResource(R.layout.preference_app_select);
+        setNegativeButtonText(android.R.string.cancel);
+        setPositiveButtonText(null);
+        setDialogTitle(R.string.choose_app);
+        setDialogIcon(null);
+        mAdapter = new AppSelectListAdapter(getContext());
+    }
+
+    @Override
+    protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue) {
+        super.onSetInitialValue(restorePersistedValue, defaultValue);
+        if (mTitle != null) {
+            setSummary(mTitle);
+        } else {
+            setSummary(getContext().getResources().getString(R.string.not_ready_summary));
+        }
+        mAppIconResourceId = R.drawable.ic_disabled;
+        setIcon(mAppIconResourceId);
+    }
+
+    @Override
+    protected void onBindDialogView(View view) {
+        super.onBindDialogView(view);
+
+        final ListView list = (ListView) view.findViewById(R.id.applist);
+        list.setAdapter(mAdapter);
+        list.setOnItemClickListener(new OnItemClickListener() {
+            @Override
+            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+                PackageItem info = (PackageItem) parent.getItemAtPosition(position);
+                mValue = info.mValue;
+                if (shouldPersist()) {
+                    persistString(mValue);
+                }
+                mTitle = info.mTitle;
+                mAppIconDrawable = null;
+                mAppIconResourceId = 0;
+                if (info.mComponentName != null) {
+                    mAppIconDrawable = resolveAppIcon(info);
+                } else {
+                    mAppIconResourceId = info.mAppIconResourceId;
+                }
+
+                updatePreferenceViews();
+                callChangeListener(mValue);
+                getDialog().dismiss();
+            }
+        });
+    }
+
+    private void updatePreferenceViews() {
+        String name = null;
+        if (shouldPersist()) {
+            name = getPersistedString(null);
+        } else {
+            name = mValue;
+        }
+        mAppIconResourceId = R.drawable.ic_disabled;
+
+        if (name != null) {
+            mAppIconDrawable = null;
+            ComponentName componentName = ComponentName.unflattenFromString(name);
+            PackageItem item = mAdapter.resolveApplication(componentName);
+            if (item != null) {
+                mTitle = item.mTitle;
+                mAppIconDrawable = resolveAppIcon(item);
+            } else {
+                mTitle = getContext().getResources().getString(R.string.resolve_failed_summary);
+            }
+        } else {
+            mTitle = getContext().getResources().getString(R.string.disabled_entry);
+            mAppIconResourceId = R.drawable.ic_disabled;
+        }
+
+        setSummary(mTitle);
+        if (mAppIconDrawable != null) {
+            setIcon(mAppIconDrawable);
+        } else {
+            setIcon(mAppIconResourceId);
+        }
+    }
+
+    private Drawable getDefaultActivityIcon() {
+        return getContext().getResources().getDrawable(android.R.drawable.sym_def_app_icon);
+    }
+
+    public String getValue() {
+        return mValue;
+    }
+
+    public void setValue(String value) {
+        mValue = value;
+    }
+
+    private Drawable resolveAppIcon(PackageItem item) {
+        Drawable appIcon = null;
+        try {
+            appIcon = mPm.getActivityIcon(item.mComponentName);
+        } catch (PackageManager.NameNotFoundException e) {
+        }
+        if (appIcon == null) {
+            appIcon = getDefaultActivityIcon();
+        }
+        return appIcon;
+    }
+
+    public static class AppSelectListPreferenceDialogFragment
+            extends CustomDialogPreference.CustomPreferenceDialogFragment {
+        public static CustomDialogPreference.CustomPreferenceDialogFragment
+                newInstance(String key) {
+            return CustomDialogPreference.CustomPreferenceDialogFragment.newInstance(key);
+        }
+    }
+}