mobisocial.musubi.objects.WebAppObj.java Source code

Java tutorial

Introduction

Here is the source code for mobisocial.musubi.objects.WebAppObj.java

Source

/*
 * Copyright 2012 The Stanford MobiSocial Laboratory
 *
 * 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.
 */

package mobisocial.musubi.objects;

import java.util.List;

import mobisocial.musubi.App;
import mobisocial.musubi.R;
import mobisocial.musubi.feed.iface.Activator;
import mobisocial.musubi.feed.iface.DbEntryHandler;
import mobisocial.musubi.feed.iface.FeedRenderer;
import mobisocial.musubi.model.MApp;
import mobisocial.musubi.model.helpers.AppManager;
import mobisocial.musubi.provider.MusubiContentProvider;
import mobisocial.musubi.provider.MusubiContentProvider.Provided;
import mobisocial.musubi.service.MusubiService;
import mobisocial.musubi.ui.fragments.FeedListFragment.FeedSummary;
import mobisocial.musubi.ui.widget.DbObjCursorAdapter.DbObjCursor;
import mobisocial.musubi.util.CommonLayouts;
import mobisocial.musubi.util.InstrumentedActivity;
import mobisocial.musubi.webapp.WebAppActivity;
import mobisocial.socialkit.Obj;
import mobisocial.socialkit.musubi.DbObj;
import mobisocial.socialkit.musubi.Musubi;
import mobisocial.socialkit.obj.MemObj;

import org.json.JSONException;
import org.json.JSONObject;

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

public class WebAppObj extends DbEntryHandler implements FeedRenderer, Activator {
    static final String TYPE = "webapp";

    static final String OBJ_URL = "url";

    @Override
    public String getType() {
        return TYPE;
    }

    public static Obj forUri(Uri uri) {
        try {
            JSONObject json = new JSONObject();
            json.put(OBJ_URL, uri.toString());
            return new MemObj(TYPE, json);
        } catch (JSONException e) {
            throw new IllegalStateException("bad json library", e);
        }
    }

    @Override
    public View createView(Context context, ViewGroup parent) {
        LinearLayout frame = new LinearLayout(context);
        frame.setLayoutParams(CommonLayouts.FULL_WIDTH);
        frame.setOrientation(LinearLayout.VERTICAL);

        LinearLayout appBar = new LinearLayout(context);
        appBar.setLayoutParams(CommonLayouts.FULL_WIDTH);
        appBar.setOrientation(LinearLayout.HORIZONTAL);
        frame.addView(appBar);

        Drawable icon = context.getResources().getDrawable(R.drawable.ic_menu_globe);
        ImageView iv = new ImageView(context);
        iv.setImageDrawable(icon);
        iv.setAdjustViewBounds(true);
        iv.setMaxWidth(60);
        iv.setMaxHeight(60);
        iv.setLayoutParams(CommonLayouts.WRAPPED);
        appBar.addView(iv);

        TextView tv = new TextView(context);
        tv.setLayoutParams(CommonLayouts.WRAPPED);
        tv.setGravity(Gravity.CENTER_VERTICAL);
        appBar.addView(tv);

        LinearLayout actionBar = new LinearLayout(context);
        actionBar.setLayoutParams(CommonLayouts.WRAPPED);
        actionBar.setOrientation(LinearLayout.HORIZONTAL);
        frame.addView(actionBar);

        Button b = new Button(context);
        // required for listview long-press
        b.setLayoutParams(CommonLayouts.WRAPPED);
        b.setFocusable(false);
        b.setText("Run");
        b.setOnClickListener(getRunListener());
        actionBar.addView(b);

        b = new Button(context);
        // required for listview long-press
        b.setLayoutParams(CommonLayouts.WRAPPED);
        b.setFocusable(false);
        b.setOnClickListener(getAddListener());
        actionBar.addView(b);

        return frame;
    }

    @Override
    public void activate(Context context, DbObj obj) {
        // we have BUTTONS
    }

    @Override
    public void render(Context context, View view, DbObjCursor obj, boolean allowInteractions) throws Exception {
        LinearLayout frame = (LinearLayout) view;

        TextView tv = (TextView) ((ViewGroup) frame.getChildAt(0)).getChildAt(1);
        tv.setText("Webapp " + getAppName(obj));

        if (allowInteractions) {
            Button b = (Button) ((ViewGroup) frame.getChildAt(1)).getChildAt(0);
            long objId = obj.objId;
            b.setTag(objId);

            b = (Button) ((ViewGroup) ((ViewGroup) view).getChildAt(1)).getChildAt(1);
            b.setTag(objId);
            AppManager am = new AppManager(App.getDatabaseSource(context));
            MApp lookup = am.lookupAppByAppId(getAppId(obj));
            //deleted ones can be readded
            //ensure app may have put it in the table without a url;
            if (lookup == null || lookup.deleted_ == true || lookup.webAppUrl_ == null) {
                b.setText("Add");
                b.setEnabled(true);
            } else {
                b.setText("Added");
                b.setEnabled(false);
            }
        }
    }

    OnClickListener mAddListener;

    private OnClickListener getAddListener() {
        if (mAddListener == null) {
            mAddListener = new OnClickListener() {
                @Override
                public void onClick(View v) {
                    Context context = v.getContext();
                    if (context instanceof InstrumentedActivity) {
                        InstrumentedActivity a = (InstrumentedActivity) context;
                        try {
                            DbObj obj = App.getMusubi(context).objForId((Long) v.getTag());
                            String name = getAppName(obj);
                            Uri uri = Uri.parse(obj.getJson().optString(OBJ_URL));
                            String appId = getAppId(obj);
                            a.showDialog(AddWebAppDialog.newInstance(obj.getLocalId(), appId, name, uri));
                        } catch (Throwable t) {
                            Toast.makeText(context, "Failed to load webapp", Toast.LENGTH_SHORT).show();
                        }
                    }
                }
            };
        }
        return mAddListener;
    }

    OnClickListener mRunListener;

    private OnClickListener getRunListener() {
        if (mRunListener == null) {
            mRunListener = new OnClickListener() {
                @Override
                public void onClick(View v) {
                    Context context = v.getContext();
                    DbObj obj = App.getMusubi(context).objForId((Long) v.getTag());
                    Intent appIntent = new Intent(Intent.ACTION_VIEW);
                    appIntent.setClass(context, WebAppActivity.class);
                    appIntent.putExtra(Musubi.EXTRA_FEED_URI, obj.getContainingFeed().getUri());
                    appIntent.putExtra(WebAppActivity.EXTRA_APP_NAME, getAppName(obj));
                    appIntent.putExtra(WebAppActivity.EXTRA_APP_URI, Uri.parse(obj.getJson().optString(OBJ_URL)));
                    appIntent.putExtra(WebAppActivity.EXTRA_APP_ID, getAppId(obj));
                    context.startActivity(appIntent);
                }
            };
        }
        return mRunListener;
    }

    String getAppName(Obj obj) {
        Uri appUri = Uri.parse(obj.getJson().optString(OBJ_URL));
        String given = appUri.getQueryParameter("n");
        if (given == null) {
            given = appUri.getLastPathSegment();
            if (given == null || given.length() <= 1 || given.startsWith("index")) {
                List<String> segs = appUri.getPathSegments();
                if (segs.size() > 1) {
                    given = segs.get(segs.size() - 2);
                } else {
                    given = appUri.getAuthority();
                }
            }
        }
        return given;
    }

    String getAppId(Obj obj) {
        Uri appUri = Uri.parse(obj.getJson().optString(OBJ_URL));
        return appUri.getAuthority() + "/" + getAppName(obj);
    }

    static class AddWebAppDialog extends DialogFragment {
        public static AddWebAppDialog newInstance(long objId, String appId, String name, Uri uri) {
            Bundle b = new Bundle();
            b.putString("name", name);
            b.putParcelable("uri", uri);
            b.putString("appid", appId);
            b.putLong("objId", objId);
            AddWebAppDialog d = new AddWebAppDialog();
            d.setArguments(b);
            return d;
        }

        public AddWebAppDialog() {
        }

        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) {
            final Uri appUri = getArguments().getParcelable("uri");
            final String name = getArguments().getString("name");
            final String appId = getArguments().getString("appid");
            final long objId = getArguments().getLong("objId");

            return new AlertDialog.Builder(getActivity()).setTitle("Add to app list?")
                    .setMessage("Add " + name + " to your list of applications?")
                    .setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            SQLiteOpenHelper databaseSource = App.getDatabaseSource(getActivity());
                            AppManager am = new AppManager(databaseSource);
                            SQLiteDatabase db = databaseSource.getWritableDatabase();
                            db.beginTransaction();
                            MApp app = null;
                            try {
                                MApp lookup = am.lookupAppByAppId(appId);
                                //could be re-adding
                                //could have had this app discovered p2p
                                if (lookup != null && lookup.deleted_ == false && lookup.webAppUrl_ != null) {
                                    Toast.makeText(getActivity(), "App already installed.", Toast.LENGTH_SHORT)
                                            .show();
                                    return;
                                }

                                app = lookup;
                                if (app == null)
                                    app = new MApp();
                                app.appId_ = appId;
                                app.name_ = name;
                                app.webAppUrl_ = appUri.toString();
                                app.deleted_ = false;

                                if (lookup != null) {
                                    am.updateApp(app);
                                } else {
                                    am.insertApp(app);
                                }
                                db.setTransactionSuccessful();

                            } finally {
                                db.endTransaction();
                            }
                            if (app == null || app.id_ == -1) {
                                Toast.makeText(getActivity(), "Error installing webapp.", Toast.LENGTH_SHORT)
                                        .show();
                            } else {
                                //load the app manifest
                                //TODO: just load this one...
                                getActivity().getContentResolver().notifyChange(MusubiService.UPDATE_APP_MANIFESTS,
                                        null);
                                Toast.makeText(getActivity(), "Installed " + name + " to pin menu.",
                                        Toast.LENGTH_SHORT).show();
                                getActivity().getContentResolver().notifyChange(
                                        MusubiContentProvider.uriForItem(Provided.OBJS_ID, objId), null);
                            }
                        }
                    }).setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            // no harm no foul
                        }
                    }).create();
        }
    }

    @Override
    public void getSummaryText(Context context, TextView view, FeedSummary summary) {
        JSONObject obj = summary.getJson();
        view.setTypeface(null, Typeface.ITALIC);
        view.setText(summary.getSender() + " posted a new web app: " + obj.optString(OBJ_URL));
    }
}