FileDocCategorySizeDatePackage
ImApp.javaAPI DocAndroid 1.5 API27298Wed May 06 22:42:46 BST 2009com.android.im.app

ImApp

public class ImApp extends android.app.Application

Fields Summary
public static final String
LOG_TAG
public static final String
EXTRA_INTENT_SEND_TO_USER
public static final String
EXTRA_INTENT_PASSWORD
public static final String
IMPS_CATEGORY
private static ImApp
sImApp
com.android.im.IRemoteImService
mImService
HashMap
mConnections
MyConnListener
mConnectionListener
HashMap
mProviders
android.os.Broadcaster
mBroadcaster
ArrayList
mQueue
A queue of messages that are waiting to be sent when service is connected.
private boolean
mServiceStarted
A flag indicates that we have called to start the service.
private android.content.Context
mApplicationContext
private android.content.res.Resources
mPrivateResources
private HashMap
mBrandingResources
private BrandingResources
mDefaultBrandingResources
public static final int
EVENT_SERVICE_CONNECTED
public static final int
EVENT_CONNECTION_CREATED
public static final int
EVENT_CONNECTION_LOGGING_IN
public static final int
EVENT_CONNECTION_LOGGED_IN
public static final int
EVENT_CONNECTION_LOGGING_OUT
public static final int
EVENT_CONNECTION_DISCONNECTED
public static final int
EVENT_CONNECTION_SUSPENDED
public static final int
EVENT_USER_PRESENCE_UPDATED
public static final int
EVENT_UPDATE_USER_PRESENCE_ERROR
private static final String[]
PROVIDER_PROJECTION
private static final String[]
ACCOUNT_PROJECTION
private android.content.ServiceConnection
mImServiceConn
private final com.android.im.IConnectionCreationListener
mConnCreationListener
Constructors Summary
public ImApp()

        super();
        mConnections = new HashMap<Long, IImConnection>();
        mApplicationContext = this;
        sImApp = this;
    
Methods Summary
voidbroadcastConnEvent(int what, long providerId, com.android.im.engine.ImErrorInfo error)

        if(Log.isLoggable(LOG_TAG, Log.DEBUG)){
            log("broadcasting connection event " + what + ", provider id " + providerId);
        }
        android.os.Message msg = android.os.Message.obtain(
                null,
                what,
                (int)(providerId >> 32), (int)providerId,
                error);
        mBroadcaster.broadcast(msg);
    
public voidcallWhenServiceConnected(android.os.Handler target, java.lang.Runnable callback)

        Message msg = Message.obtain(target, callback);
        if (serviceConnected()) {
            msg.sendToTarget();
        } else {
            startImServiceIfNeed();
            synchronized (mQueue) {
                mQueue.add(msg);
            }
        }
    
public com.android.im.IImConnectioncreateConnection(long providerId)

        if (mImService == null) {
            // Service hasn't been connected or has died.
            return null;
        }
        IImConnection conn = getConnection(providerId);
        if (conn == null) {
            conn = mImService.createConnection(providerId);
        }
        return conn;
    
public voiddismissChatNotification(long providerId, java.lang.String username)

        if (mImService != null) {
            try {
                mImService.dismissChatNotification(providerId, username);
            } catch (RemoteException e) {
            }
        }
    
public voiddismissNotifications(long providerId)

        if (mImService != null) {
            try {
                mImService.dismissNotifications(providerId);
            } catch (RemoteException e) {
            }
        }
    
private voidfetchActiveConnections()

          try {
            // register the listener before fetch so that we won't miss any connection.
            mImService.addConnectionCreatedListener(mConnCreationListener);
            synchronized (mConnections) {
                for(IBinder binder: (List<IBinder>) mImService.getActiveConnections()) {
                    IImConnection conn = IImConnection.Stub.asInterface(binder);
                    long providerId = conn.getProviderId();
                    if (!mConnections.containsKey(providerId)) {
                        mConnections.put(providerId, conn);
                        conn.registerConnectionListener(mConnectionListener);
                    }
                }
            }
        } catch (RemoteException e) {
            Log.e(LOG_TAG, "fetching active connections", e);
        }
    
public java.util.ListgetActiveConnections()

        synchronized (mConnections) {
            ArrayList<IImConnection> result = new ArrayList<IImConnection>();
            result.addAll(mConnections.values());
            return result;
        }
    
public static com.android.im.app.ImAppgetApplication(android.app.Activity activity)

        // TODO should this be synchronized?
        if (sImApp == null) {
            initialize(activity);
        }

        return sImApp;
    
public BrandingResourcesgetBrandingResource(long providerId)

        ProviderDef provider = getProvider(providerId);
        if (provider == null) {
            return mDefaultBrandingResources;
        }
        BrandingResources res = mBrandingResources.get(provider.mName);
        return res == null ? mDefaultBrandingResources : res;
    
com.android.im.IImConnectiongetConnection(long providerId)

        synchronized (mConnections) {
            return mConnections.get(providerId);
        }
    
public com.android.im.IImConnectiongetConnectionByAccount(long accountId)

        synchronized (mConnections) {
            for (IImConnection conn : mConnections.values()) {
                try {
                    if (conn.getAccountId() == accountId) {
                        return conn;
                    }
                } catch (RemoteException e) {
                    // No server!
                }
            }
            return null;
        }
    
public android.content.ContentResolvergetContentResolver()

        if (mApplicationContext == this) {
            return super.getContentResolver();
        }

        return mApplicationContext.getContentResolver();
    
public ProviderDefgetProvider(long id)

        loadImProviderSettings();
        return mProviders.get(id);
    
public longgetProviderId(java.lang.String name)

        loadImProviderSettings();
        for (ProviderDef provider: mProviders.values()) {
            if(provider.mName.equals(name)) {
                return provider.mId;
            }
        }
        return -1;
    
public java.util.ListgetProviders()

        loadImProviderSettings();
        ArrayList<ProviderDef> result = new ArrayList<ProviderDef>();
        result.addAll(mProviders.values());
        return result;
    
public android.content.res.ResourcesgetResources()

        if (mApplicationContext == this) {
            return super.getResources();
        }

        return mPrivateResources;
    
private static voidinitialize(android.app.Activity activity)
Initialize performs the manual ImApp instantiation and initialization. When the ImApp is started first in the process, the ImApp public constructor should be called, and sImApp initialized. So calling initialize() later should have no effect. However, if another application runs in the same process and is started first, the ImApp application object won't be instantiated, and we need to call initialize() manually to instantiate and initialize it.

        // construct the TalkApp manually and call onCreate().
        sImApp = new ImApp();
        sImApp.mApplicationContext = activity.getApplication();
        sImApp.mPrivateResources = activity.getResources();
        sImApp.onCreate();
    
public static longinsertOrUpdateAccount(android.content.ContentResolver cr, long providerId, java.lang.String userName, java.lang.String pw)

        String selection = Im.Account.PROVIDER + "=? AND " + Im.Account.USERNAME + "=?";
        String[] selectionArgs = {Long.toString(providerId), userName };

        Cursor c = cr.query(Im.Account.CONTENT_URI, ACCOUNT_PROJECTION,
                selection, selectionArgs, null);
        if (c != null && c.moveToFirst()) {
            // Update the password
            c.updateString(c.getColumnIndexOrThrow(Im.Account.PASSWORD), pw);
            c.commitUpdates();

            long id = c.getLong(c.getColumnIndexOrThrow(Im.Account._ID));
            c.close();
            return id;
        } else {
            ContentValues values = new ContentValues(4);
            values.put(Im.Account.PROVIDER, providerId);
            values.put(Im.Account.NAME, userName);
            values.put(Im.Account.USERNAME, userName);
            values.put(Im.Account.PASSWORD, pw);

            Uri result = cr.insert(Im.Account.CONTENT_URI, values);
            return ContentUris.parseId(result);
        }
    
public booleanisBackgroundDataEnabled()

        ConnectivityManager manager =
                (ConnectivityManager) mApplicationContext.getSystemService(CONNECTIVITY_SERVICE);
        return manager.getBackgroundDataSetting();
    
private voidloadDefaultBrandingRes()

        HashMap<Integer, Integer> resMapping = new HashMap<Integer, Integer>();

        resMapping.put(BrandingResourceIDs.DRAWABLE_LOGO, R.drawable.imlogo_s);
        resMapping.put(BrandingResourceIDs.DRAWABLE_PRESENCE_ONLINE,
                android.R.drawable.presence_online);
        resMapping.put(BrandingResourceIDs.DRAWABLE_PRESENCE_AWAY,
                android.R.drawable.presence_away);
        resMapping.put(BrandingResourceIDs.DRAWABLE_PRESENCE_BUSY,
                android.R.drawable.presence_busy);
        resMapping.put(BrandingResourceIDs.DRAWABLE_PRESENCE_INVISIBLE,
                android.R.drawable.presence_invisible);
        resMapping.put(BrandingResourceIDs.DRAWABLE_PRESENCE_OFFLINE,
                android.R.drawable.presence_offline);
        resMapping.put(BrandingResourceIDs.DRAWABLE_READ_CHAT,
                R.drawable.status_chat);
        resMapping.put(BrandingResourceIDs.DRAWABLE_UNREAD_CHAT,
                R.drawable.status_chat_new);
        resMapping.put(BrandingResourceIDs.DRAWABLE_BLOCK,
                R.drawable.ic_im_block);

        resMapping.put(BrandingResourceIDs.STRING_ARRAY_SMILEY_NAMES,
                R.array.default_smiley_names);
        resMapping.put(BrandingResourceIDs.STRING_ARRAY_SMILEY_TEXTS,
                R.array.default_smiley_texts);

        resMapping.put(BrandingResourceIDs.STRING_PRESENCE_AVAILABLE,
                R.string.presence_available);
        resMapping.put(BrandingResourceIDs.STRING_PRESENCE_BUSY,
                R.string.presence_busy);
        resMapping.put(BrandingResourceIDs.STRING_PRESENCE_AWAY,
                R.string.presence_away);
        resMapping.put(BrandingResourceIDs.STRING_PRESENCE_IDLE,
                R.string.presence_idle);
        resMapping.put(BrandingResourceIDs.STRING_PRESENCE_OFFLINE,
                R.string.presence_offline);
        resMapping.put(BrandingResourceIDs.STRING_PRESENCE_INVISIBLE,
                R.string.presence_invisible);
        resMapping.put(BrandingResourceIDs.STRING_LABEL_USERNAME,
                R.string.label_username);
        resMapping.put(BrandingResourceIDs.STRING_ONGOING_CONVERSATION,
                R.string.ongoing_conversation);
        resMapping.put(BrandingResourceIDs.STRING_ADD_CONTACT_TITLE,
                R.string.add_contact_title);
        resMapping.put(BrandingResourceIDs.STRING_LABEL_INPUT_CONTACT,
                R.string.input_contact_label);
        resMapping.put(BrandingResourceIDs.STRING_BUTTON_ADD_CONTACT,
                R.string.invite_label);
        resMapping.put(BrandingResourceIDs.STRING_CONTACT_INFO_TITLE,
                R.string.contact_profile_title);

        resMapping.put(BrandingResourceIDs.STRING_MENU_ADD_CONTACT,
                R.string.menu_add_contact);
        resMapping.put(BrandingResourceIDs.STRING_MENU_BLOCK_CONTACT,
                R.string.menu_block_contact);
        resMapping.put(BrandingResourceIDs.STRING_MENU_CONTACT_LIST,
                R.string.menu_view_contact_list);
        resMapping.put(BrandingResourceIDs.STRING_MENU_DELETE_CONTACT,
                R.string.menu_remove_contact);
        resMapping.put(BrandingResourceIDs.STRING_MENU_END_CHAT,
                R.string.menu_end_conversation);
        resMapping.put(BrandingResourceIDs.STRING_MENU_INSERT_SMILEY,
                R.string.menu_insert_smiley);
        resMapping.put(BrandingResourceIDs.STRING_MENU_START_CHAT,
                R.string.menu_start_chat);
        resMapping.put(BrandingResourceIDs.STRING_MENU_VIEW_PROFILE,
                R.string.menu_view_profile);
        resMapping.put(BrandingResourceIDs.STRING_MENU_SWITCH_CHATS,
                R.string.menu_switch_chats);

        resMapping.put(BrandingResourceIDs.STRING_TOAST_CHECK_AUTO_SIGN_IN,
                R.string.check_auto_sign_in);
        resMapping.put(BrandingResourceIDs.STRING_LABEL_SIGN_UP,
                R.string.sign_up);

        mDefaultBrandingResources = new BrandingResources(this, resMapping,
                null /* default res */);
    
private voidloadImProviderSettings()

        if (mProviders != null) {
            return;
        }
        
        mProviders = new HashMap<Long, ProviderDef>();
        ContentResolver cr = getContentResolver();

        String selectionArgs[] = new String[1];
        selectionArgs[0] = ImApp.IMPS_CATEGORY;

        Cursor c = cr.query(Im.Provider.CONTENT_URI, PROVIDER_PROJECTION,
                Im.Provider.CATEGORY+"=?", selectionArgs, null);
        if (c == null) {
            return;
        }

        try {
            while (c.moveToNext()) {
                long id = c.getLong(0);
                String providerName = c.getString(1);
                String fullName = c.getString(2);
                String signUpUrl = c.getString(3);

                mProviders.put(id, new ProviderDef(id, providerName, fullName, signUpUrl));
            }
        } finally {
            c.close();
        }
    
private voidloadThirdPartyResources()

        PackageManager pm = getPackageManager();
        List<ResolveInfo> plugins = pm.queryIntentServices(
                new Intent(ImPluginConstants.PLUGIN_ACTION_NAME), PackageManager.GET_META_DATA);
        for (ResolveInfo info : plugins) {
            Log.d(LOG_TAG, "Found plugin " + info);

            ServiceInfo serviceInfo = info.serviceInfo;
            if (serviceInfo == null) {
                Log.e(LOG_TAG, "Ignore bad IM plugin: " + info);
                continue;
            }
            String providerName = null;
            String providerFullName = null;
            Bundle metaData = serviceInfo.metaData;
            if (metaData != null) {
                providerName = metaData.getString(
                        ImPluginConstants.METADATA_PROVIDER_NAME);
                providerFullName = metaData.getString(
                        ImPluginConstants.METADATA_PROVIDER_FULL_NAME);
            }
            if (TextUtils.isEmpty(providerName)
                    || TextUtils.isEmpty(providerFullName)) {
                Log.e(LOG_TAG, "Ignore bad IM plugin: " + info
                        + ". Lack of required meta data");
                continue;
            }

            ImPluginInfo pluginInfo = new ImPluginInfo(providerName,
                    serviceInfo.packageName, serviceInfo.name,
                    serviceInfo.applicationInfo.sourceDir);

            BrandingResources res = new BrandingResources(this, pluginInfo,
                    mDefaultBrandingResources);
            mBrandingResources.put(providerName, res);
        }
    
static final voidlog(java.lang.String log)


         
        Log.d(LOG_TAG, log);
    
public voidonCreate()

        super.onCreate();
        mBroadcaster = new Broadcaster();
        loadDefaultBrandingRes();
        mBrandingResources = new HashMap<String, BrandingResources>();
        loadThirdPartyResources();
    
public voidonTerminate()

        stopImServiceIfInactive();
        if (mImService != null) {
            try {
                mImService.removeConnectionCreatedListener(mConnCreationListener);
            } catch (RemoteException e) {
                Log.w(LOG_TAG, "failed to remove ConnectionCreatedListener");
            }
        }

        super.onTerminate();
    
public voidregisterForBroadcastEvent(int what, android.os.Handler target)

        mBroadcaster.request(what, target, what);
    
public voidregisterForConnEvents(android.os.Handler handler)

        mBroadcaster.request(EVENT_CONNECTION_CREATED, handler,
                EVENT_CONNECTION_CREATED);
        mBroadcaster.request(EVENT_CONNECTION_LOGGING_IN, handler,
                EVENT_CONNECTION_LOGGING_IN);
        mBroadcaster.request(EVENT_CONNECTION_LOGGED_IN, handler,
                EVENT_CONNECTION_LOGGED_IN);
        mBroadcaster.request(EVENT_CONNECTION_LOGGING_OUT, handler,
                EVENT_CONNECTION_LOGGING_OUT);
        mBroadcaster.request(EVENT_CONNECTION_SUSPENDED, handler,
                EVENT_CONNECTION_SUSPENDED);
        mBroadcaster.request(EVENT_CONNECTION_DISCONNECTED, handler,
                EVENT_CONNECTION_DISCONNECTED);
        mBroadcaster.request(EVENT_USER_PRESENCE_UPDATED, handler,
                EVENT_USER_PRESENCE_UPDATED);
        mBroadcaster.request(EVENT_UPDATE_USER_PRESENCE_ERROR, handler,
                EVENT_UPDATE_USER_PRESENCE_ERROR);
    
public voidremovePendingCall(android.os.Handler target)

        synchronized (mQueue) {
           Iterator<Message> iter = mQueue.iterator();
           while (iter.hasNext()) {
               Message msg = iter.next();
               if (msg.getTarget() == target) {
                   iter.remove();
               }
           }
       }
   
public booleanserviceConnected()


       
        return mImService != null;
    
public synchronized voidstartImServiceIfNeed()

        if(!mServiceStarted) {
            if(Log.isLoggable(LOG_TAG, Log.DEBUG)) log("start ImService");

            Intent serviceIntent = new Intent();
            serviceIntent.setComponent(ImServiceConstants.IM_SERVICE_COMPONENT);
            mApplicationContext.startService(serviceIntent);
            mApplicationContext.bindService(serviceIntent, mImServiceConn, Context.BIND_AUTO_CREATE);
            mServiceStarted = true;

            mConnectionListener = new MyConnListener(new Handler());
        }
    
public synchronized voidstopImServiceIfInactive()

        boolean hasActiveConnection = true;
        synchronized (mConnections) {
            hasActiveConnection = !mConnections.isEmpty();
        }

        if (!hasActiveConnection && mServiceStarted) {
            if (Log.isLoggable(LOG_TAG, Log.DEBUG))
                log("stop ImService because there's no active connections");

            if(mImService != null) {
                mApplicationContext.unbindService(mImServiceConn);
                mImService = null;
            }
            Intent intent = new Intent();
            intent.setComponent(ImServiceConstants.IM_SERVICE_COMPONENT);
            mApplicationContext.stopService(intent);
            mServiceStarted = false;
        }
    
public voidunregisterForBroadcastEvent(int what, android.os.Handler target)

        mBroadcaster.cancelRequest(what, target, what);
    
public voidunregisterForConnEvents(android.os.Handler handler)

        mBroadcaster.cancelRequest(EVENT_CONNECTION_CREATED, handler,
                EVENT_CONNECTION_CREATED);
        mBroadcaster.cancelRequest(EVENT_CONNECTION_LOGGING_IN, handler,
                EVENT_CONNECTION_LOGGING_IN);
        mBroadcaster.cancelRequest(EVENT_CONNECTION_LOGGED_IN, handler,
                EVENT_CONNECTION_LOGGED_IN);
        mBroadcaster.cancelRequest(EVENT_CONNECTION_LOGGING_OUT, handler,
                EVENT_CONNECTION_LOGGING_OUT);
        mBroadcaster.cancelRequest(EVENT_CONNECTION_SUSPENDED, handler,
                EVENT_CONNECTION_SUSPENDED);
        mBroadcaster.cancelRequest(EVENT_CONNECTION_DISCONNECTED, handler,
                EVENT_CONNECTION_DISCONNECTED);
        mBroadcaster.cancelRequest(EVENT_USER_PRESENCE_UPDATED, handler,
                EVENT_USER_PRESENCE_UPDATED);
        mBroadcaster.cancelRequest(EVENT_UPDATE_USER_PRESENCE_ERROR, handler,
                EVENT_UPDATE_USER_PRESENCE_ERROR);