/*
Copyright (c) 2013 The MITRE Corporation, All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this work 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.mitre.svmp.common;
import android.annotation.TargetApi;
import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.*;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.location.LocationProvider;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
import org.mitre.svmp.activities.AppList;
import org.mitre.svmp.client.R;
import org.mitre.svmp.protocol.SVMPProtocol.LocationRequest;
import org.mitre.svmp.protocol.SVMPProtocol.LocationUpdate;
import org.mitre.svmp.protocol.SVMPProtocol.LocationProviderInfo;
import org.mitre.svmp.protocol.SVMPProtocol.LocationProviderEnabled;
import org.mitre.svmp.protocol.SVMPProtocol.LocationProviderStatus;
import org.mitre.svmp.protocol.SVMPProtocol.RotationInfo;
import org.mitre.svmp.protocol.SVMPProtocol.Request;
/**
* @author David Schoenheit, Joe Portner
*/
public class Utility {
// finds the proper screen density to use for icons
public static int getScreenDensity(Context context) {
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
return activityManager.getLauncherLargeIconDensity();
}
public static void createShortcut(Context context, AppInfo appInfo) {
// figure out what screen density we are targeting
int screenDensity = getScreenDensity(context);
// this intent defines the shortcut appearance (name, icon)
Intent shortcutIntent = getShortcutIntent(context, appInfo);
// try to decode the AppInfo's "icon" byte array into an image
Bitmap rawBitmap = appInfo.getBitmap();
if (rawBitmap == null) {
// if decoding was not successful, let's use the default icon instead
BitmapDrawable bitmapDrawable;
if (Constants.API_15)
bitmapDrawable = (BitmapDrawable)getDrawable15(context, R.drawable.ic_launcher, screenDensity);
else
bitmapDrawable = (BitmapDrawable)getDrawable(context, R.drawable.ic_launcher);
rawBitmap = bitmapDrawable.getBitmap(); //drawableToBitmap(bitmapDrawable);
}
// decoding was successful, let's put an image overlay on the bitmap
Bitmap bitmap = Bitmap.createBitmap(rawBitmap.getWidth(), rawBitmap.getHeight(), Bitmap.Config.ARGB_8888);
Paint paint = new Paint();
Canvas canvas = new Canvas(bitmap);
canvas.drawBitmap(rawBitmap, 0, 0, paint);
Drawable badge;
if (Constants.API_15)
badge = getDrawable15(context, R.drawable.svmp_icon_overlay, screenDensity);
else
badge = getDrawable(context, R.drawable.svmp_icon_overlay);
badge.setBounds(new Rect(0,0,badge.getIntrinsicWidth(),badge.getIntrinsicHeight()));
badge.draw(canvas);
shortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON, bitmap);
// send the broadcast to create the shortcut
shortcutIntent.setAction("com.android.launcher.action.INSTALL_SHORTCUT");
context.sendBroadcast(shortcutIntent);
}
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)
private static Drawable getDrawable15(Context context, int resId, int screenDensity) {
return context.getResources().getDrawableForDensity(resId, screenDensity);
}
// if the API is less than 15, just get the drawable without targeting a screen density
private static Drawable getDrawable(Context context, int resId) {
// note: tried using BitmapFactory options to decode drawable to a target screen density, didn't work
return context.getResources().getDrawable(resId);
}
public static void removeShortcut(Context context, AppInfo appInfo) {
// this intent defines the shortcut appearance (name, icon)
Intent shortcutIntent = getShortcutIntent(context, appInfo);
// send the broadcast to remove the shortcut
shortcutIntent.setAction("com.android.launcher.action.UNINSTALL_SHORTCUT");
context.sendBroadcast(shortcutIntent);
}
private static Intent getShortcutIntent(Context context, AppInfo appInfo) {
// this intent defines the shortcut behavior (launch activity, action, extras)
Intent launchIntent = new Intent(context, AppList.class);
launchIntent.setAction(Constants.ACTION_LAUNCH_APP);
launchIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); // when this is started, clear other SVMP activities
launchIntent.putExtra("connectionID", appInfo.getConnectionID());
launchIntent.putExtra("packageName", appInfo.getPackageName());
// this intent defines the shortcut appearance (name, icon)
Intent shortcutIntent = new Intent();
shortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, launchIntent);
shortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, appInfo.getAppName());
shortcutIntent.putExtra("duplicate", false); // Just create once
return shortcutIntent;
}
// transforms a CellNetwork integer to an appropriate string (see TelephonyManager)
public static String cellNetwork(int cellNetwork) {
String network;
switch(cellNetwork) {
// use literals in cases for backwards compatibility (past versions of Android don't have later networks)
case 1:
network = "GPRS";
break;
case 2:
network = "EDGE";
break;
case 3:
network = "UMTS";
break;
case 4:
network = "CDMA";
break;
case 5:
network = "EVDO_0";
break;
case 6:
network = "EVDO_A";
break;
case 7:
network = "1xRTT";
break;
case 8:
network = "HSDPA";
break;
case 9:
network = "HSUPA";
break;
case 10:
network = "HSPA";
break;
case 11:
network = "IDEN";
break;
case 12:
network = "EVDO_B";
break;
case 13:
network = "LTE";
break;
case 14:
network = "EHRPD";
break;
case 15:
network = "HSPAP";
break;
case 0:
default:
network = "UNKNOWN";
break;
}
return network;
}
public static String getPrefString(Context context, int keyId, int defaultValueId) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
String key = context.getString(keyId);
String defaultValue = context.getString(defaultValueId);
return sharedPreferences.getString(key, defaultValue);
}
public static int getPrefInt(Context context, int keyId, int defaultValueId) {
String prefString = getPrefString(context, keyId, defaultValueId);
int value = 0;
try {
value = Integer.parseInt(prefString);
} catch( Exception e ) { /* don't care */ }
return value;
}
public static boolean getPrefBool(Context context, int keyId, int defaultValueId) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
String key = context.getString(keyId);
boolean defaultValue = false;
try {
defaultValue = Boolean.parseBoolean(context.getString(defaultValueId));
} catch( Exception e ) { /* don't care */ }
return sharedPreferences.getBoolean(key, defaultValue);
}
public static Request toRequest_LocationProviderInfo(LocationProvider provider) {
// create a LocationProviderInfo Builder
LocationProviderInfo.Builder lpiBuilder = LocationProviderInfo.newBuilder()
// set required variables
.setProvider(provider.getName())
.setRequiresNetwork(provider.requiresNetwork())
.setRequiresSatellite(provider.requiresSatellite())
.setRequiresCell(provider.requiresCell())
.setHasMonetaryCost(provider.hasMonetaryCost())
.setSupportsAltitude(provider.supportsAltitude())
.setSupportsSpeed(provider.supportsSpeed())
.setSupportsBearing(provider.supportsBearing())
.setPowerRequirement(provider.getPowerRequirement())
.setAccuracy(provider.getAccuracy());
// pack LocationProviderInfo into LocationRequest wrapper
LocationRequest.Builder lrBuilder = LocationRequest.newBuilder()
.setType(LocationRequest.LocationRequestType.PROVIDERINFO)
.setProviderInfo(lpiBuilder);
// build the Request
return toRequest_LocationRequest(lrBuilder);
}
public static Request toRequest_LocationProviderStatus(String s, int i, Bundle bundle) {
// create a LocationProviderStatus Builder
LocationProviderStatus.Builder lpsBuilder = LocationProviderStatus.newBuilder()
// set required variables
.setProvider(s)
.setStatus(i);
// pack LocationProviderStatus into LocationRequest wrapper
LocationRequest.Builder lrBuilder = LocationRequest.newBuilder()
.setType(LocationRequest.LocationRequestType.PROVIDERSTATUS)
.setProviderStatus(lpsBuilder);
// build the Request
return toRequest_LocationRequest(lrBuilder);
}
public static Request toRequest_LocationProviderEnabled(String s, boolean isEnabled) {
// create a LocationProviderEnabled Builder
LocationProviderEnabled.Builder lpeBuilder = LocationProviderEnabled.newBuilder()
// set required variables
.setProvider(s)
.setEnabled(isEnabled);
// pack LocationProviderEnabled into LocationRequest wrapper
LocationRequest.Builder lrBuilder = LocationRequest.newBuilder()
.setType(LocationRequest.LocationRequestType.PROVIDERENABLED)
.setProviderEnabled(lpeBuilder);
// build the Request
return toRequest_LocationRequest(lrBuilder);
}
public static Request toRequest_LocationUpdate(Location location) {
// create a LocationUpdate Builder
LocationUpdate.Builder luBuilder = LocationUpdate.newBuilder()
// set required variables
.setLatitude(location.getLatitude())
.setLongitude(location.getLongitude())
.setTime(location.getTime())
.setProvider(location.getProvider());
// set optional variables
if( location.hasAccuracy() )
luBuilder.setAccuracy(location.getAccuracy());
if( location.hasAltitude() )
luBuilder.setAltitude(location.getAltitude());
if( location.hasBearing() )
luBuilder.setBearing(location.getBearing());
if( location.hasSpeed() )
luBuilder.setSpeed(location.getSpeed());
// pack LocationUpdate into LocationRequest wrapper
LocationRequest.Builder lrBuilder = LocationRequest.newBuilder()
.setType(LocationRequest.LocationRequestType.LOCATIONUPDATE)
.setUpdate(luBuilder);
// build the Request
return toRequest_LocationRequest(lrBuilder);
}
public static Request toRequest_LocationRequest(LocationRequest.Builder lrBuilder) {
// pack LocationRequest into Request wrapper
Request.Builder rBuilder = Request.newBuilder()
.setType(Request.RequestType.LOCATION)
.setLocationRequest(lrBuilder);
// build the Request
return rBuilder.build();
}
public static Request toRequest_RotationInfo(int rotation) {
// create a RotationInfo Builder
RotationInfo.Builder riBuilder = RotationInfo.newBuilder()
// set required variables
.setRotation(rotation);
// pack RotationInfo into Request wrapper
Request.Builder rBuilder = Request.newBuilder()
.setType(Request.RequestType.ROTATION_INFO)
.setRotationInfo(riBuilder);
// build the Request
return rBuilder.build();
}
}