Implementing "Share Page" using ListView

 -Implements custom version of "Share Page"

Change-Id: I073a8adabcca03ea71fdfdf2a438d6820b902350
diff --git a/src/com/android/browser/AppAdapter.java b/src/com/android/browser/AppAdapter.java
new file mode 100644
index 0000000..429ed90
--- /dev/null
+++ b/src/com/android/browser/AppAdapter.java
@@ -0,0 +1,86 @@
+/*
+    * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+    *
+    * Redistribution and use in source and binary forms, with or without
+    * modification, are permitted provided that the following conditions are
+    * met:
+    * * Redistributions of source code must retain the above copyright
+    * notice, this list of conditions and the following disclaimer.
+    * * Redistributions in binary form must reproduce the above
+    * copyright notice, this list of conditions and the following
+    * disclaimer in the documentation and/or other materials provided
+    * with the distribution.
+    * * Neither the name of The Linux Foundation nor the names of its
+    * contributors may be used to endorse or promote products derived
+    * from this software without specific prior written permission.
+    *
+    * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+    * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+    * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+    * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+    * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+    * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+    * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+    * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+    * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+    * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+    * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+    *
+    */
+
+package com.android.browser;
+
+import android.content.Context;
+import android.content.pm.ResolveInfo;
+import android.content.pm.PackageManager;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.TextView;
+import android.widget.ImageView;
+
+import java.util.List;
+
+public class AppAdapter extends ArrayAdapter<ResolveInfo> {
+    private PackageManager pm = null;
+    private Context context = null;
+    private int layoutResourceId = -1;
+
+
+    public AppAdapter (Context context, PackageManager pm, int layoutResourceId, List<ResolveInfo> apps) {
+      super(context, layoutResourceId, apps);
+      this.context = context;
+      this.pm = pm;
+      this.layoutResourceId = layoutResourceId;
+    }
+
+    /*
+    * Overide this method in order to create your own view
+    */
+    @Override
+    public View getView(int position, View convertView, ViewGroup parent) {
+      if (convertView == null) {
+        convertView = newView(parent);
+      }
+
+      bindView(position, convertView);
+      return(convertView);
+    }
+
+    private View newView(ViewGroup parent) {
+      LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService( Context.LAYOUT_INFLATER_SERVICE );
+      return(layoutInflater.inflate(layoutResourceId, parent, false));
+    }
+
+    private void bindView(int position, View row) {
+
+      TextView label = (TextView)row.findViewById(R.id.app_label);
+      label.setText(  getItem(position).loadLabel(pm));
+
+      ImageView icon = (ImageView)row.findViewById(R.id.app_icon);
+      icon.setImageDrawable( getItem(position).loadIcon(pm));
+
+    }
+}
diff --git a/src/com/android/browser/AppItem.java b/src/com/android/browser/AppItem.java
new file mode 100644
index 0000000..331f3e9
--- /dev/null
+++ b/src/com/android/browser/AppItem.java
@@ -0,0 +1,42 @@
+/*
+    * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+    *
+    * Redistribution and use in source and binary forms, with or without
+    * modification, are permitted provided that the following conditions are
+    * met:
+    * * Redistributions of source code must retain the above copyright
+    * notice, this list of conditions and the following disclaimer.
+    * * Redistributions in binary form must reproduce the above
+    * copyright notice, this list of conditions and the following
+    * disclaimer in the documentation and/or other materials provided
+    * with the distribution.
+    * * Neither the name of The Linux Foundation nor the names of its
+    * contributors may be used to endorse or promote products derived
+    * from this software without specific prior written permission.
+    *
+    * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+    * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+    * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+    * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+    * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+    * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+    * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+    * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+    * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+    * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+    * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+    *
+    */
+
+package com.android.browser;
+
+import android.content.pm.ResolveInfo;
+import java.util.List;
+
+class AppItem {
+    public List<ResolveInfo> apps;
+
+    public AppItem(List<ResolveInfo> apps) {
+        this.apps = apps;
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/browser/Controller.java b/src/com/android/browser/Controller.java
index a5151dd..c3be486 100644
--- a/src/com/android/browser/Controller.java
+++ b/src/com/android/browser/Controller.java
@@ -88,6 +88,7 @@
 import org.codeaurora.swe.WebSettings;
 import org.codeaurora.swe.WebView;
 
+import com.android.browser.AppAdapter;
 import com.android.browser.R;
 import com.android.browser.IntentHandler.UrlData;
 import com.android.browser.UI.ComboViews;
@@ -130,8 +131,6 @@
     // Remind switch to data connection if wifi is unavailable
     private static final int NETWORK_SWITCH_TYPE_OK = 1;
 
-    public final static String EXTRA_SHARE_SCREENSHOT = "share_screenshot";
-    public final static String EXTRA_SHARE_FAVICON = "share_favicon";
     // public message ids
     public final static int LOAD_URL = 1001;
     public final static int STOP_LOAD = 1002;
@@ -626,18 +625,11 @@
      */
     static final void sharePage(Context c, String title, String url,
             Bitmap favicon, Bitmap screenshot) {
-        Intent send = new Intent(Intent.ACTION_SEND);
-        send.setType("text/plain");
-        send.putExtra(Intent.EXTRA_TEXT, url);
-        send.putExtra(Intent.EXTRA_SUBJECT, title);
-        send.putExtra(EXTRA_SHARE_FAVICON, favicon);
-        send.putExtra(EXTRA_SHARE_SCREENSHOT, screenshot);
-        try {
-            c.startActivity(Intent.createChooser(send, c.getString(
-                    R.string.choosertitle_sharevia)));
-        } catch(android.content.ActivityNotFoundException ex) {
-            // if no app handles it, do nothing
-        }
+
+        ShareDialog sDialog = new ShareDialog((Activity)c, title, url, favicon, screenshot);
+        final AppAdapter adapter = new AppAdapter(c, c.getPackageManager(),
+                                        R.layout.app_row, sDialog.getApps());
+        sDialog.loadView(adapter);
     }
 
     private void copy(CharSequence text) {
diff --git a/src/com/android/browser/ShareDialog.java b/src/com/android/browser/ShareDialog.java
new file mode 100644
index 0000000..4b649d5
--- /dev/null
+++ b/src/com/android/browser/ShareDialog.java
@@ -0,0 +1,115 @@
+/*
+    * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+    *
+    * Redistribution and use in source and binary forms, with or without
+    * modification, are permitted provided that the following conditions are
+    * met:
+    * * Redistributions of source code must retain the above copyright
+    * notice, this list of conditions and the following disclaimer.
+    * * Redistributions in binary form must reproduce the above
+    * copyright notice, this list of conditions and the following
+    * disclaimer in the documentation and/or other materials provided
+    * with the distribution.
+    * * Neither the name of The Linux Foundation nor the names of its
+    * contributors may be used to endorse or promote products derived
+    * from this software without specific prior written permission.
+    *
+    * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+    * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+    * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+    * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+    * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+    * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+    * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+    * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+    * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+    * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+    * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+    *
+    */
+package com.android.browser;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ResolveInfo;
+import android.content.pm.PackageManager;
+import android.graphics.Bitmap;
+
+import java.util.List;
+import java.util.Collections;
+
+import android.util.Log;
+
+
+public class ShareDialog extends AppItem {
+    private Activity activity = null;
+    public String title = null;
+    public String url = null;
+    public Bitmap favicon = null;
+    public Bitmap screenshot = null;
+    private List<ResolveInfo>apps = null;
+    public final static String EXTRA_SHARE_SCREENSHOT = "share_screenshot";
+    public final static String EXTRA_SHARE_FAVICON = "share_favicon";
+
+
+    public ShareDialog (Activity activity, String title, String url, Bitmap favicon, Bitmap screenshot) {
+        super(null);
+        this.activity = activity;
+        this.apps = getShareableApps();
+        this.title = title;
+        this.url = url;
+        this.favicon = favicon;
+        this.screenshot = screenshot;
+    }
+
+    private List<ResolveInfo> getShareableApps() {
+        Intent shareIntent = new Intent("android.intent.action.SEND");
+        shareIntent.setType("text/plain");
+        PackageManager pm = activity.getPackageManager();
+        List<ResolveInfo> launchables = pm.queryIntentActivities(shareIntent, 0);
+
+        Collections.sort(launchables,
+                     new ResolveInfo.DisplayNameComparator(pm));
+
+        return launchables;
+    }
+
+
+    public List<ResolveInfo> getApps() {
+        return apps;
+    }
+
+    public void loadView(final AppAdapter adapter) {
+        AlertDialog.Builder builderSingle = new AlertDialog.Builder(activity);
+        builderSingle.setIcon(R.mipmap.ic_launcher_browser_swe);
+        builderSingle.setTitle(activity.getString(R.string.choosertitle_sharevia));
+        builderSingle.setAdapter(adapter, new DialogInterface.OnClickListener() {
+            @Override
+            public void onClick(DialogInterface dialog, int position) {
+                dialog.dismiss();
+                ResolveInfo launchable = adapter.getItem(position);
+                ActivityInfo activityInfo = launchable.activityInfo;
+                ComponentName name = new android.content.ComponentName(activityInfo.applicationInfo.packageName,
+                                                     activityInfo.name);
+                Intent i = new Intent(Intent.ACTION_SEND);
+                i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
+                            Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
+                i.putExtra(Intent.EXTRA_TEXT, url);
+                i.putExtra(Intent.EXTRA_SUBJECT, title);
+                i.putExtra(EXTRA_SHARE_FAVICON, favicon);
+                i.putExtra(EXTRA_SHARE_SCREENSHOT, screenshot);
+                i.setType("text/plain");
+                i.setComponent(name);
+                activity.startActivity(i);
+            }
+        });
+
+        builderSingle.show();
+    }
+}
\ No newline at end of file