package com.aviary.android.feather.receivers; import java.util.Iterator; import java.util.Set; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Resources; import android.net.Uri; import android.os.Bundle; import com.aviary.android.feather.library.content.FeatherIntent; import com.aviary.android.feather.library.log.LoggerFactory; import com.aviary.android.feather.library.log.LoggerFactory.Logger; import com.aviary.android.feather.library.log.LoggerFactory.LoggerType; /** * Main receiver used to listen for new packages installations. When a package, which is recognized as a feather plugin, has been * installed/removed or updated this receiver will broadcast a notification. * * @author alessandro * */ public class FeatherSystemReceiver extends BroadcastReceiver { /** The logger. */ static Logger logger = LoggerFactory.getLogger( "FeatherSystemReceiver", LoggerType.ConsoleLoggerType ); /** * A package in the system has been installed/replaced or removed. Check if the package is a valid feather plugin and send a * broadcast notification of the newly package. A valid feather plugin must have a resource with the follwing integer * identifiers: is_sticker indicates it's a sticker pack plugin is_filter indicates it's a filter pack plugin is_tool indicates * it's a new tool plugin ( not used ) * * @param context * the context * @param intent * the intent */ @Override public void onReceive( Context context, Intent intent ) { final String action = intent.getAction(); if ( null != action ) { logger.info( "onReceive", action ); if ( Intent.ACTION_PACKAGE_ADDED.equals( action ) ) { handlePackageAdded( context, intent ); } else if ( Intent.ACTION_PACKAGE_REMOVED.equals( action ) ) { handlePackageRemoved( context, intent ); } else if ( Intent.ACTION_PACKAGE_REPLACED.equals( action ) ) { handlePackageReplaced( context, intent ); } } } /** * Handle package. * * @param context * the context * @param packageName * the package name * @param intent * the intent */ private void handlePackage( Context context, String packageName, Intent intent ) { Resources res = null; int is_sticker = 0; int is_filter = 0; int is_tool = 0; int is_border = 0; try { res = context.getPackageManager().getResourcesForApplication( packageName ); } catch ( NameNotFoundException e ) { e.printStackTrace(); } if ( null != res ) { int resid = 0; resid = res.getIdentifier( "is_sticker", "integer", packageName ); if ( resid != 0 ) is_sticker = res.getInteger( resid ); resid = res.getIdentifier( "is_filter", "integer", packageName ); if ( resid != 0 ) is_filter = res.getInteger( resid ); resid = res.getIdentifier( "is_tool", "integer", packageName ); if ( resid != 0 ) is_tool = res.getInteger( resid ); resid = res.getIdentifier( "is_border", "integer", packageName ); if ( resid != 0 ) is_border = res.getInteger( resid ); } intent.putExtra( FeatherIntent.PACKAGE_NAME, packageName ); intent.putExtra( FeatherIntent.IS_STICKER, is_sticker ); intent.putExtra( FeatherIntent.IS_FILTER, is_filter ); intent.putExtra( FeatherIntent.IS_TOOL, is_tool ); intent.putExtra( FeatherIntent.IS_BORDER, is_border ); intent.putExtra( FeatherIntent.APPLICATION_CONTEXT, context.getApplicationContext().getPackageName() ); } /** * Handle package replaced. * * @param context * the context * @param intent * the intent */ private void handlePackageReplaced( Context context, Intent intent ) { logger.info( "handlePackageReplaced: " + intent ); Uri data = intent.getData(); String path = data.getSchemeSpecificPart(); if ( null != path ) { if ( path.startsWith( FeatherIntent.PLUGIN_BASE_PACKAGE ) ) { Intent newIntent = new Intent( FeatherIntent.ACTION_PLUGIN_REPLACED ); newIntent.setData( data ); handlePackage( context, path, newIntent ); newIntent.putExtra( FeatherIntent.ACTION, FeatherIntent.ACTION_PLUGIN_REPLACED ); context.sendBroadcast( newIntent ); } } } /** * Handle package removed. * * @param context * the context * @param intent * the intent */ private void handlePackageRemoved( Context context, Intent intent ) { logger.info( "handlePackageRemoved: " + intent ); Uri data = intent.getData(); String path = data.getSchemeSpecificPart(); Bundle extras = intent.getExtras(); boolean is_replacing = isReplacing( extras ); if ( null != path && !is_replacing ) { if ( path.startsWith( FeatherIntent.PLUGIN_BASE_PACKAGE ) ) { Intent newIntent = new Intent( FeatherIntent.ACTION_PLUGIN_REMOVED ); newIntent.setData( data ); handlePackage( context, path, newIntent ); newIntent.putExtra( FeatherIntent.ACTION, FeatherIntent.ACTION_PLUGIN_REMOVED ); context.sendBroadcast( newIntent ); } } } /** * Handle package added. * * @param context * the context * @param intent * the intent */ private void handlePackageAdded( Context context, Intent intent ) { logger.info( "handlePackageAdded: " + intent ); Uri data = intent.getData(); String path = data.getSchemeSpecificPart(); Bundle extras = intent.getExtras(); boolean is_replacing = isReplacing( extras ); if ( null != path && !is_replacing ) { if ( path.startsWith( FeatherIntent.PLUGIN_BASE_PACKAGE ) ) { Intent newIntent = new Intent( FeatherIntent.ACTION_PLUGIN_ADDED ); newIntent.setData( data ); handlePackage( context, path, newIntent ); newIntent.putExtra( FeatherIntent.ACTION, FeatherIntent.ACTION_PLUGIN_ADDED ); context.sendBroadcast( newIntent ); } } } /** * Prints the bundle. * * @param bundle * the bundle */ @SuppressWarnings("unused") private void printBundle( Bundle bundle ) { if ( null != bundle ) { Set<String> set = bundle.keySet(); Iterator<String> iterator = set.iterator(); while ( iterator.hasNext() ) { String key = iterator.next(); Object value = bundle.get( key ); logger.log( " ", key, value ); } } } /** * The operation. * * @param bundle * the bundle * @return true, if is replacing */ private boolean isReplacing( Bundle bundle ) { if ( bundle != null && bundle.containsKey( Intent.EXTRA_REPLACING ) ) return bundle.getBoolean( Intent.EXTRA_REPLACING ); return false; } }