Files
tubestation/mobile/android/base/util/WebActivityMapper.java

222 lines
6.8 KiB
Java

/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko.util;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.content.Intent;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.Log;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
public final class WebActivityMapper {
private static final String LOGTAG = "Gecko";
private static final Map<String, WebActivityMapping> activityMap = new HashMap<String, WebActivityMapping>();
static {
activityMap.put("dial", new DialMapping());
activityMap.put("open", new OpenMapping());
activityMap.put("pick", new PickMapping());
activityMap.put("send", new SendMapping());
activityMap.put("view", new ViewMapping());
activityMap.put("record", new RecordMapping());
};
private static abstract class WebActivityMapping {
protected JSONObject mData;
public void setData(JSONObject data) {
mData = data;
}
// Cannot return null
public abstract String getAction();
public String getMime() throws JSONException {
return null;
}
public String getUri() throws JSONException {
return null;
}
public void putExtras(Intent intent) throws JSONException {}
}
/**
* Provides useful defaults for mime type and uri.
*/
private static abstract class BaseMapping extends WebActivityMapping {
/**
* If 'type' is present in data object, uses the value as the MIME type.
*/
@Override
public String getMime() throws JSONException {
return mData.optString("type", null);
}
/**
* If 'uri' or 'url' is present in data object, uses the respective value as the Uri.
*/
@Override
public String getUri() throws JSONException {
// Will return uri or url if present.
String uri = mData.optString("uri", null);
return uri != null ? uri : mData.optString("url", null);
}
}
public static Intent getIntentForWebActivity(JSONObject message) throws JSONException {
final String name = message.getString("name").toLowerCase();
final JSONObject data = message.getJSONObject("data");
Log.w(LOGTAG, "Activity is: " + name);
final WebActivityMapping mapping = activityMap.get(name);
if (mapping == null) {
Log.w(LOGTAG, "No mapping found!");
return null;
}
mapping.setData(data);
final Intent intent = new Intent(mapping.getAction());
final String mime = mapping.getMime();
if (!TextUtils.isEmpty(mime)) {
intent.setType(mime);
}
final String uri = mapping.getUri();
if (!TextUtils.isEmpty(uri)) {
intent.setData(Uri.parse(uri));
}
mapping.putExtras(intent);
return intent;
}
private static class DialMapping extends WebActivityMapping {
@Override
public String getAction() {
return Intent.ACTION_DIAL;
}
@Override
public String getUri() throws JSONException {
return "tel:" + mData.getString("number");
}
}
private static class OpenMapping extends BaseMapping {
@Override
public String getAction() {
return Intent.ACTION_VIEW;
}
}
private static class PickMapping extends BaseMapping {
@Override
public String getAction() {
return Intent.ACTION_GET_CONTENT;
}
@Override
public String getMime() throws JSONException {
// bug 1007112 - pick action needs a mimetype to work
String mime = mData.optString("type", null);
return !TextUtils.isEmpty(mime) ? mime : "*/*";
}
}
private static class SendMapping extends BaseMapping {
@Override
public String getAction() {
return Intent.ACTION_SEND;
}
@Override
public void putExtras(Intent intent) throws JSONException {
optPutExtra("text", Intent.EXTRA_TEXT, intent);
optPutExtra("html_text", Intent.EXTRA_HTML_TEXT, intent);
optPutExtra("stream", Intent.EXTRA_STREAM, intent);
}
private void optPutExtra(String key, String extraName, Intent intent) {
final String extraValue = mData.optString(key);
if (!TextUtils.isEmpty(extraValue)) {
intent.putExtra(extraName, extraValue);
}
}
}
private static class ViewMapping extends BaseMapping {
@Override
public String getAction() {
return Intent.ACTION_VIEW;
}
@Override
public String getMime() {
// MozActivity adds a type 'url' here, we don't want to set the MIME to 'url'.
String type = mData.optString("type", null);
if ("url".equals(type) || "uri".equals(type)) {
return null;
} else {
return type;
}
}
}
private static class RecordMapping extends WebActivityMapping {
@Override
public String getAction() {
String type = mData.optString("type", null);
if ("photos".equals(type)) {
return "android.media.action.IMAGE_CAPTURE";
} else if ("videos".equals(type)) {
return "android.media.action.VIDEO_CAPTURE";
}
return null;
}
// Add an extra to specify where to save the picture/video.
@Override
public void putExtras(Intent intent) {
final String action = getAction();
final String dirType = action == "android.media.action.IMAGE_CAPTURE"
? Environment.DIRECTORY_PICTURES
: Environment.DIRECTORY_MOVIES;
final String ext = action == "android.media.action.IMAGE_CAPTURE"
? ".jpg"
: ".mp4";
File destDir = Environment.getExternalStoragePublicDirectory(dirType);
try {
File dest = File.createTempFile(
"capture", /* prefix */
ext, /* suffix */
destDir /* directory */
);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(dest));
} catch(Exception e) {
Log.w(LOGTAG, "Failed to add extra for " + action + " : " + e);
}
}
}
}