/*
* 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 org.mobisocial.appmanifest;
import java.io.InputStream;
import java.util.List;
import org.mobisocial.appmanifest.platforms.PlatformReference;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.nfc.NdefMessage;
import android.nfc.NfcAdapter;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.Log;
import android.widget.Toast;
public class AppManifestHandler extends Activity {
public static final String EXTRA_APPLICATION_ARGUMENT = "android.intent.extra.APPLICATION_ARGUMENT";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent inbound = getIntent();
if (inbound == null) {
Toast.makeText(this, "No app manifest found", Toast.LENGTH_SHORT).show();
finish();
return;
}
int bestAndroidIndex = -1;
int bestWebIndex = -1;
byte[] manifestBytes = null;
ApplicationManifest manifest;
// TODO: hack because we have no uri for a tag's payload.
if (inbound.hasExtra("content")) {
manifestBytes = inbound.getByteArrayExtra("content");
} else if ("android.nfc.action.NDEF_DISCOVERED".equals(inbound.getAction())) {
Parcelable[] rawMsgs = inbound.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
manifestBytes = ((NdefMessage)rawMsgs[0]).getRecords()[0].getPayload();
} else {
Uri manifestUri = inbound.getData();
try {
// First get length ;(
InputStream in = getContentResolver().openInputStream(manifestUri);
int read = 0;
int total = 0;
byte[] buffer = new byte[1024];
while ((read = in.read(buffer)) > 0) {
total += read;
}
// Now read bytes.
manifestBytes = new byte[total];
total = 0;
while ((read = in.read(buffer)) > 0) {
System.arraycopy(buffer, 0, manifestBytes, total, read);
total += read;
}
} catch (Exception e) {
Toast.makeText(this, "Error reading app manifest", Toast.LENGTH_SHORT).show();
Log.d("junction","Error reading app manifest", e);
finish();
return;
}
}
manifest = new ApplicationManifest(manifestBytes);
List<PlatformReference> platforms = manifest.getPlatformReferences();
int i = 0;
for (PlatformReference platform : platforms) {
if (platform.getPlatformIdentifier() == ApplicationManifest.PLATFORM_ANDROID_PACKAGE) {
bestAndroidIndex = i;
} else if (platform.getPlatformIdentifier() == ApplicationManifest.PLATFORM_WEB_GET) {
bestWebIndex = i;
}
i++;
}
if (bestAndroidIndex != -1) {
Intent fire = new Intent();
fire.setAction("android.intent.action.MAIN");
fire.addCategory("android.intent.category.LAUNCHER");
PlatformReference android = manifest.getPlatformReferences().get(bestAndroidIndex);
String androidStr = new String(android.getAppReference());
int col = androidStr.indexOf(":");
String pkg = androidStr.substring(0, col);
String arg = androidStr.substring(col+1);
fire.setPackage(pkg);
fire.putExtra(EXTRA_APPLICATION_ARGUMENT, arg);
List<ResolveInfo> resolved = getPackageManager().queryIntentActivities(fire, 0);
if (resolved != null && resolved.size() > 0) {
ActivityInfo info = resolved.get(0).activityInfo;
fire.setComponent(new ComponentName(info.packageName, info.name));
startActivity(fire);
finish();
return;
}
}
if (bestWebIndex != -1) {
PlatformReference android = manifest.getPlatformReferences().get(bestWebIndex);
String webStr = new String(android.getAppReference());
Intent fire = new Intent(Intent.ACTION_VIEW);
fire.setData(Uri.parse(webStr));
startActivity(fire);
finish();
return;
}
Toast.makeText(this, "No usable platform found.", Toast.LENGTH_SHORT).show();
finish();
}
}