Omnigears/events : Purge uninstalled apps

Change-Id: I69d3c61263ea74a3f95dec8eb9879fadf3186cfa
diff --git a/res/layout/preference_selected_apps_view.xml b/res/layout/preference_selected_apps_view.xml
index aa7c499..05480dd 100644
--- a/res/layout/preference_selected_apps_view.xml
+++ b/res/layout/preference_selected_apps_view.xml
@@ -27,7 +27,7 @@
         android:layout_height="wrap_content"
         android:layout_marginBottom="6dip"
         android:layout_marginEnd="6dip"
-        android:layout_marginStart="15dip"
+        android:layout_marginStart="8dip"
         android:layout_marginTop="6dip"
         android:layout_weight="1">
 
diff --git a/res/xml/event_service_settings.xml b/res/xml/event_service_settings.xml
index 48fe122..3a9a510 100644
--- a/res/xml/event_service_settings.xml
+++ b/res/xml/event_service_settings.xml
@@ -40,7 +40,7 @@
         <org.omnirom.omnigears.preference.AppMultiSelectListPreference
             android:dependency="event_service_enabled"
             android:icon="@drawable/ic_settings_bluetooth"
-            android:key="bt_a2dp_connect_app_list"
+            android:key="bt_a2dp_connect_app_string"
             android:persistent="false"
             android:summary="@string/bt_a2dp_connect_app_list_summary"
             android:title="@string/bt_a2dp_connect_app_list_title" />
@@ -54,7 +54,7 @@
         <org.omnirom.omnigears.preference.AppMultiSelectListPreference
             android:dependency="event_service_enabled"
             android:icon="@drawable/ic_headset_24dp"
-            android:key="headset_connect_app_list"
+            android:key="headset_connect_app_string"
             android:persistent="false"
             android:summary="@string/headset_connect_app_list_summary"
             android:title="@string/headset_connect_app_list_title" />
diff --git a/src/org/omnirom/omnigears/preference/AppMultiSelectListPreference.java b/src/org/omnirom/omnigears/preference/AppMultiSelectListPreference.java
index 62749cd..4d7e5d1 100644
--- a/src/org/omnirom/omnigears/preference/AppMultiSelectListPreference.java
+++ b/src/org/omnirom/omnigears/preference/AppMultiSelectListPreference.java
@@ -39,10 +39,9 @@
 import com.android.settingslib.CustomDialogPreference;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Set;
 
 public class AppMultiSelectListPreference extends CustomDialogPreference {
     private static final String TAG = "AppMultiSelectList";
@@ -50,7 +49,7 @@
 
     private final List<PackageItem> mPackageInfoList = new ArrayList<PackageItem>();
     private AppListAdapter mAdapter;
-    private Set<String> mValues = new HashSet<String>();
+    private List<String> mValues = new ArrayList<String>();
     private PackageManager mPm;
 
     public AppMultiSelectListPreference(Context context) {
@@ -87,12 +86,12 @@
         setNegativeButtonText(android.R.string.cancel);
     }
 
-    public void setValues(Set<String> values) {
+    public void setValues(Collection<String> values) {
         mValues.clear();
         mValues.addAll(values);
     }
 
-    public Set<String> getValues() {
+    public Collection<String> getValues() {
         return mValues;
     }
 
diff --git a/src/org/omnirom/omnigears/preference/ScrollAppsViewPreference.java b/src/org/omnirom/omnigears/preference/ScrollAppsViewPreference.java
index 4d42ecc..7583ebe 100644
--- a/src/org/omnirom/omnigears/preference/ScrollAppsViewPreference.java
+++ b/src/org/omnirom/omnigears/preference/ScrollAppsViewPreference.java
@@ -32,14 +32,15 @@
 
 import com.android.settings.R;
 
-import java.util.HashSet;
-import java.util.Set;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
 
 public class ScrollAppsViewPreference extends Preference {
     private static final String TAG = "ScrollAppsPreference";
 
     private Context mContext;
-    private Set<String> mValues = new HashSet<String>();
+    private List<String> mValues = new ArrayList<String>();
     private PackageManager mPm;
     private LayoutInflater mInflater;
 
@@ -58,7 +59,7 @@
         initPreference(context);
     }
 
-    public void setValues(Set<String> values) {
+    public void setValues(Collection<String> values) {
         mValues.clear();
         mValues.addAll(values);
     }
diff --git a/src/org/omnirom/omnigears/service/EventService.java b/src/org/omnirom/omnigears/service/EventService.java
index 1156cdc..9eba603 100644
--- a/src/org/omnirom/omnigears/service/EventService.java
+++ b/src/org/omnirom/omnigears/service/EventService.java
@@ -44,6 +44,7 @@
 import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.UserHandle;
+import android.text.TextUtils;
 import android.util.Log;
 import android.view.ContextThemeWrapper;
 import android.view.Gravity;
@@ -58,7 +59,8 @@
 
 import org.omnirom.omnigears.R;
 
-import java.util.Set;
+import java.util.ArrayList;
+import java.util.List;
 
 
 public class EventService extends Service {
@@ -77,7 +79,7 @@
 
     private WindowManager mWindowManager;
     private View mFloatingWidget = null;
-    private Set<String> appList = null;
+    private List<String> appList = null;
     private Handler mHandler = new Handler();
     private PackageManager mPm;
     private int chooserPosition;
@@ -118,8 +120,8 @@
                             if (DEBUG) Log.d(TAG, "BluetoothProfile.STATE_CONNECTED = true");
 
                             if (!(disableIfMusicActive && isMusicActive())) {
-                                appList = getPrefs(context).getStringSet(EventServiceSettings.EVENT_A2DP_CONNECT, null);
-                                if (appList != null) {
+                                appList = getAvailableActionList(EventServiceSettings.EVENT_A2DP_CONNECT);
+                                if (appList.size() != 0) {
                                     if (autoRun && appList.size() == 1) {
                                         openApp(appList.iterator().next(), context);
                                     } else {
@@ -148,8 +150,8 @@
                             if (DEBUG) Log.d(TAG, "AudioManager.ACTION_HEADSET_PLUG = true");
 
                             if (!(disableIfMusicActive && isMusicActive())) {
-                                appList = getPrefs(context).getStringSet(EventServiceSettings.EVENT_WIRED_HEADSET_CONNECT, null);
-                                if (appList != null) {
+                                appList = getAvailableActionList(EventServiceSettings.EVENT_WIRED_HEADSET_CONNECT);
+                                if (appList.size() != 0) {
                                     if (autoRun && appList.size() == 1) {
                                         openApp(appList.iterator().next(), context);
                                     } else {
@@ -430,4 +432,21 @@
                     .start();
         }
     }
+
+    // filter out unresolvable (uninstalled) intents
+    private List<String> getAvailableActionList(String key) {
+        String value = getPrefs(this).getString(key, null);
+        List<String> valueList = new ArrayList<String>();
+        if (!TextUtils.isEmpty(value)) {
+            for (String intentUri : value.split(":")){
+                Intent intent = createIntent(intentUri);
+                if (mPm.resolveActivity(intent, 0) != null) {
+                    valueList.add(intentUri);
+                }
+            }
+            if (DEBUG) Log.d(TAG, "getActionList valueList = " + valueList);
+        }
+        return valueList;
+    }
 }
+
diff --git a/src/org/omnirom/omnigears/service/EventServiceSettings.java b/src/org/omnirom/omnigears/service/EventServiceSettings.java
index 6c5ff86..99aafb8 100644
--- a/src/org/omnirom/omnigears/service/EventServiceSettings.java
+++ b/src/org/omnirom/omnigears/service/EventServiceSettings.java
@@ -29,6 +29,7 @@
 import android.support.v7.preference.ListPreference;
 import android.support.v7.preference.Preference;
 import android.support.v7.preference.Preference.OnPreferenceChangeListener;
+import android.text.TextUtils;
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
@@ -40,16 +41,17 @@
 import org.omnirom.omnigears.preference.ScrollAppsViewPreference;
 import org.omnirom.omnigears.preference.SeekBarPreference;
 
+import java.util.Arrays;
 import java.util.ArrayList;
-import java.util.HashSet;
+import java.util.Collection;
 import java.util.List;
 import java.util.Set;
 
 public class EventServiceSettings extends SettingsPreferenceFragment implements OnPreferenceChangeListener, Indexable {
     public static final String EVENTS_PREFERENCES_NAME = "event_service";
 
-    public static final String EVENT_A2DP_CONNECT = "bt_a2dp_connect_app_list";
-    public static final String EVENT_WIRED_HEADSET_CONNECT = "headset_connect_app_list";
+    public static final String EVENT_A2DP_CONNECT = "bt_a2dp_connect_app_string";
+    public static final String EVENT_WIRED_HEADSET_CONNECT = "headset_connect_app_string";
     public static final String EVENT_SERVICE_ENABLED = "event_service_enabled";
     public static final String EVENT_MEDIA_PLAYER_START = "media_player_autostart";
     public static final String EVENT_MUSIC_ACTIVE = "media_player_music_active";
@@ -61,8 +63,8 @@
     public static final String WIRED_EVENTS_THRESHOLD = "wired_events_threshold";
 
     // -- For backward compatibility
-    public static final String OLD_EVENT_A2DP_CONNECT = "bt_a2dp_connect_app";
-    public static final String OLD_EVENT_WIRED_HEADSET_CONNECT = "headset_connect_app";
+    public static final String OLD_EVENT_A2DP_CONNECT = "bt_a2dp_connect_app_list";
+    public static final String OLD_EVENT_WIRED_HEADSET_CONNECT = "headset_connect_app_list";
     // -- End backward compatibility
 
     private AppMultiSelectListPreference mA2DPappSelect;
@@ -95,12 +97,12 @@
         addPreferencesFromResource(R.xml.event_service_settings);
 
         // -- For backward compatibility
-        String old_value = getPrefs().getString(OLD_EVENT_A2DP_CONNECT, null);
-        if (old_value != null) {
+        if (getPrefs().contains(OLD_EVENT_A2DP_CONNECT)) {
+            Set<String> old_value = getPrefs().getStringSet(OLD_EVENT_A2DP_CONNECT, null);
             fixOldPreference(OLD_EVENT_A2DP_CONNECT, EVENT_A2DP_CONNECT, old_value);
         }
-        old_value = getPrefs().getString(OLD_EVENT_WIRED_HEADSET_CONNECT, null);
-        if (old_value != null) {
+        if (getPrefs().contains(OLD_EVENT_WIRED_HEADSET_CONNECT)) {
+            Set<String> old_value = getPrefs().getStringSet(OLD_EVENT_WIRED_HEADSET_CONNECT, null);
             fixOldPreference(OLD_EVENT_WIRED_HEADSET_CONNECT, EVENT_WIRED_HEADSET_CONNECT, old_value);
         }
         // -- End backward compatibility
@@ -139,62 +141,70 @@
         mWiredThresholdTimeout.setOnPreferenceChangeListener(this);
 
         mA2DPappSelect = (AppMultiSelectListPreference) findPreference(EVENT_A2DP_CONNECT);
-        Set<String> value = getPrefs().getStringSet(EVENT_A2DP_CONNECT, null);
-        if (value != null) mA2DPappSelect.setValues(value);
+        String value = getPrefs().getString(EVENT_A2DP_CONNECT, null);
+        List<String> valueList = new ArrayList<String>();
+        if (!TextUtils.isEmpty(value)) {
+            valueList.addAll(Arrays.asList(value.split(":")));
+        }
+        mA2DPappSelect.setValues(valueList);
         mA2DPappSelect.setOnPreferenceChangeListener(this);
 
         mA2DPApps = (ScrollAppsViewPreference) findPreference(A2DP_APP_LIST);
-        if (value == null) {
+        if (TextUtils.isEmpty(value)) {
             mA2DPApps.setVisible(false);
         } else {
             mA2DPApps.setVisible(true);
-            mA2DPApps.setValues(value);
+            mA2DPApps.setValues(valueList);
         }
 
         mWiredHeadsetAppSelect = (AppMultiSelectListPreference) findPreference(EVENT_WIRED_HEADSET_CONNECT);
-        value = getPrefs().getStringSet(EVENT_WIRED_HEADSET_CONNECT, null);
-        if (value != null) mWiredHeadsetAppSelect.setValues(value);
+        value = getPrefs().getString(EVENT_WIRED_HEADSET_CONNECT, null);
+        valueList = new ArrayList<String>();
+        if (!TextUtils.isEmpty(value)) {
+            valueList.addAll(Arrays.asList(value.split(":")));
+        }
+        mWiredHeadsetAppSelect.setValues(valueList);
         mWiredHeadsetAppSelect.setOnPreferenceChangeListener(this);
 
         mHeadsetApps = (ScrollAppsViewPreference) findPreference(HEADSET_APP_LIST);
-        if (value == null) {
+        if (TextUtils.isEmpty(value)) {
             mHeadsetApps.setVisible(false);
         } else {
-            mHeadsetApps.setValues(value);
+            mHeadsetApps.setValues(valueList);
             mHeadsetApps.setVisible(true);
         }
     }
 
-    private void fixOldPreference(String old_event, String new_event, String value) {
-        Set<String> mValues = new HashSet<String>();
-        mValues.add(value);
-        getPrefs().edit().putStringSet(new_event, mValues).commit();
-        getPrefs().edit().putString(old_event, null).commit();
+    private void fixOldPreference(String old_event, String new_event, Set<String> value) {
+        getPrefs().edit().putString(new_event, TextUtils.join(":", value)).commit();
+        getPrefs().edit().remove(old_event).commit();
     }
 
     @Override
     public boolean onPreferenceChange(Preference preference, Object newValue) {
         if (preference == mA2DPappSelect) {
-            Set<String> value = (Set<String>) newValue;
-
-            getPrefs().edit().putStringSet(EVENT_A2DP_CONNECT, value).commit();
+            Collection<String> value = (Collection<String>) newValue;
 
             mA2DPApps.setVisible(false);
-            if (value != null) {
+            if (value != null && !value.isEmpty()) {
+                getPrefs().edit().putString(EVENT_A2DP_CONNECT, TextUtils.join(":", value)).commit();
                 mA2DPApps.setValues(value);
                 mA2DPApps.setVisible(true);
+            } else {
+                getPrefs().edit().putString(EVENT_A2DP_CONNECT, null).commit();
             }
 
             return true;
         } else if (preference == mWiredHeadsetAppSelect) {
-            Set<String> value = (Set<String>) newValue;
-
-            getPrefs().edit().putStringSet(EVENT_WIRED_HEADSET_CONNECT, value).commit();
+            Collection<String> value = (Collection<String>) newValue;
 
             mHeadsetApps.setVisible(false);
-            if (value != null) {
+            if (value != null && !value.isEmpty()) {
+                getPrefs().edit().putString(EVENT_WIRED_HEADSET_CONNECT, TextUtils.join(":", value)).commit();
                 mHeadsetApps.setValues(value);
                 mHeadsetApps.setVisible(true);
+            } else {
+                getPrefs().edit().putString(EVENT_WIRED_HEADSET_CONNECT, null).commit();
             }
 
             return true;
@@ -280,3 +290,4 @@
                 }
             };
 }
+