LandingPagepublic class LandingPage extends android.app.ListActivity implements View.OnCreateContextMenuListener
Fields Summary |
---|
private static final String | TAG | private static final boolean | LOCAL_DEBUG | private static final int | ID_SIGN_IN | private static final int | ID_SIGN_OUT | private static final int | ID_EDIT_ACCOUNT | private static final int | ID_REMOVE_ACCOUNT | private static final int | ID_SIGN_OUT_ALL | private static final int | ID_ADD_ACCOUNT | private static final int | ID_VIEW_CONTACT_LIST | private static final int | ID_SETTINGS | private ProviderAdapter | mAdapter | private android.database.Cursor | mProviderCursor | private static final String[] | PROVIDER_PROJECTION | private static final int | PROVIDER_ID_COLUMN | private static final int | PROVIDER_NAME_COLUMN | private static final int | PROVIDER_FULLNAME_COLUMN | private static final int | PROVIDER_CATEGORY_COLUMN | private static final int | ACTIVE_ACCOUNT_ID_COLUMN | private static final int | ACTIVE_ACCOUNT_USERNAME_COLUMN | private static final int | ACTIVE_ACCOUNT_PW_COLUMN | private static final int | ACTIVE_ACCOUNT_LOCKED | private static final int | ACCOUNT_PRESENCE_STATUS | private static final int | ACCOUNT_CONNECTION_STATUS | private static final String | PROVIDER_SELECTION | private HashMap | mProviderToPluginMap | private HashMap | mAccountToPluginMap | private HashMap | mBrandingResources | private BrandingResources | mDefaultBrandingResources | private String[] | mProviderSelectionArgs |
Methods Summary |
---|
private boolean | allAccountsSignedOut()
mProviderCursor.moveToFirst();
do {
if (isSignedIn(mProviderCursor)) {
return false;
}
} while (mProviderCursor.moveToNext()) ;
return true;
| public BrandingResources | getBrandingResource(long providerId)
BrandingResources res = mBrandingResources.get(providerId);
return res == null ? mDefaultBrandingResources : res;
| android.content.Intent | getCreateAccountIntent()
Intent intent = new Intent();
intent.setAction(Intent.ACTION_INSERT);
long providerId = mProviderCursor.getLong(PROVIDER_ID_COLUMN);
intent.setData(ContentUris.withAppendedId(Im.Provider.CONTENT_URI, providerId));
intent.addCategory(getProviderCategory(mProviderCursor));
return intent;
| android.content.Intent | getEditAccountIntent()
Intent intent = new Intent(Intent.ACTION_EDIT,
ContentUris.withAppendedId(Im.Account.CONTENT_URI,
mProviderCursor.getLong(ACTIVE_ACCOUNT_ID_COLUMN)));
intent.addCategory(getProviderCategory(mProviderCursor));
return intent;
| private java.lang.String | getProviderCategory(android.database.Cursor cursor)
return cursor.getString(PROVIDER_CATEGORY_COLUMN);
| private java.util.ArrayList | getSupportedProviders(android.im.IImPlugin plugin)
ArrayList<String> providers = null;
try {
providers = (ArrayList<String>) plugin.getSupportedProviders();
} catch (RemoteException ex) {
Log.e(TAG, "getSupportedProviders caught ", ex);
}
return providers;
| android.content.Intent | getViewContactsIntent()
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Im.Contacts.CONTENT_URI);
intent.addCategory(getProviderCategory(mProviderCursor));
intent.putExtra("accountId", mProviderCursor.getLong(ACTIVE_ACCOUNT_ID_COLUMN));
return intent;
| boolean | isSignedIn(android.database.Cursor cursor)
int connectionStatus = cursor.getInt(ACCOUNT_CONNECTION_STATUS);
return connectionStatus == Im.ConnectionStatus.ONLINE;
| boolean | isSigningIn(android.database.Cursor cursor)
int connectionStatus = cursor.getInt(ACCOUNT_CONNECTION_STATUS);
return connectionStatus == Im.ConnectionStatus.CONNECTING;
| private void | loadBrandingResources()
mProviderCursor.moveToFirst();
do {
long providerId = mProviderCursor.getLong(PROVIDER_ID_COLUMN);
String providerName = mProviderCursor.getString(PROVIDER_NAME_COLUMN);
PluginInfo pluginInfo = mProviderToPluginMap.get(providerName);
if (pluginInfo == null) {
Log.w(TAG, "[LandingPage] loadBrandingResources: no plugin found for " + providerName);
continue;
}
if (!mBrandingResources.containsKey(providerId)) {
BrandingResources res = new BrandingResources(this, pluginInfo, providerName,
mDefaultBrandingResources);
mBrandingResources.put(providerId, res);
}
} while (mProviderCursor.moveToNext()) ;
| private void | loadDefaultBrandingRes()
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.STRING_MENU_CONTACT_LIST,
R.string.menu_view_contact_list);
mDefaultBrandingResources = new BrandingResources(this, resMapping, null /* default res */);
| private boolean | loadPlugins()
mProviderToPluginMap = new HashMap<String, PluginInfo>();
PackageManager pm = getPackageManager();
List<ResolveInfo> plugins = pm.queryIntentServices(
new Intent(ImPluginConsts.PLUGIN_ACTION_NAME),
PackageManager.GET_META_DATA);
for (ResolveInfo info : plugins) {
if (Log.isLoggable(TAG, Log.DEBUG)) log("loadPlugins: found plugin " + info);
ServiceInfo serviceInfo = info.serviceInfo;
if (serviceInfo == null) {
Log.e(TAG, "Ignore bad IM frontdoor plugin: " + info);
continue;
}
IImPlugin plugin = null;
// Load the plug-in directly from the apk instead of binding the service
// and calling through the IPC binder API. It's more effective in this way
// and we can avoid the async behaviors of binding service.
PathClassLoader classLoader = new PathClassLoader(serviceInfo.applicationInfo.sourceDir,
getClassLoader());
try {
if (Log.isLoggable(TAG, Log.DEBUG)) {
log("loadPlugin: load class " + serviceInfo.name);
}
Class cls = classLoader.loadClass(serviceInfo.name);
Object newInstance = cls.newInstance();
Method m;
// call "attach" method, so the plugin will get initialized with the proper context
m = cls.getMethod("attach", Context.class, ActivityThread.class, String.class,
IBinder.class, Application.class, Object.class);
m.invoke(newInstance,
new Object[] {this, null, serviceInfo.name, null, getApplication(),
ActivityManagerNative.getDefault()});
// call "bind" to get the plugin object
m = cls.getMethod("onBind", Intent.class);
plugin = (IImPlugin)m.invoke(newInstance, new Object[]{null});
} catch (ClassNotFoundException e) {
Log.e(TAG, "Failed load the plugin", e);
} catch (IllegalAccessException e) {
Log.e(TAG, "Failed load the plugin", e);
} catch (InstantiationException e) {
Log.e(TAG, "Failed load the plugin", e);
} catch (SecurityException e) {
Log.e(TAG, "Failed load the plugin", e);
} catch (NoSuchMethodException e) {
Log.e(TAG, "Failed load the plugin", e);
} catch (IllegalArgumentException e) {
Log.e(TAG, "Failed load the plugin", e);
} catch (InvocationTargetException e) {
Log.e(TAG, "Failed load the plugin", e);
}
if (plugin != null) {
if (Log.isLoggable(TAG, Log.DEBUG)) log("loadPlugin: plugin " + plugin + " loaded");
ArrayList<String> providers = getSupportedProviders(plugin);
if (providers == null || providers.size() == 0) {
Log.e(TAG, "Ignore bad IM frontdoor plugin: " + info + ". No providers found");
continue;
}
PluginInfo pluginInfo = new PluginInfo(plugin,
serviceInfo.packageName,
serviceInfo.name,
serviceInfo.applicationInfo.sourceDir);
for (String providerName : providers) {
mProviderToPluginMap.put(providerName, pluginInfo);
}
}
}
return mProviderToPluginMap.size() > 0;
| static void | log(java.lang.String msg)
Log.d(TAG, "[LandingPage]" + msg);
| public boolean | onContextItemSelected(android.view.MenuItem item)
AdapterView.AdapterContextMenuInfo info;
try {
info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
} catch (ClassCastException e) {
Log.e(TAG, "bad menuInfo", e);
return false;
}
long providerId = info.id;
Cursor providerCursor = (Cursor) getListAdapter().getItem(info.position);
long accountId = providerCursor.getLong(ACTIVE_ACCOUNT_ID_COLUMN);
switch (item.getItemId()) {
case ID_EDIT_ACCOUNT:
{
startActivity(getEditAccountIntent());
return true;
}
case ID_REMOVE_ACCOUNT:
{
Uri accountUri = ContentUris.withAppendedId(Im.Account.CONTENT_URI, accountId);
getContentResolver().delete(accountUri, null, null);
// Requery the cursor to force refreshing screen
providerCursor.requery();
return true;
}
case ID_VIEW_CONTACT_LIST:
{
Intent intent = getViewContactsIntent();
startActivity(intent);
return true;
}
case ID_ADD_ACCOUNT:
{
startActivity(getCreateAccountIntent());
return true;
}
case ID_SIGN_IN:
{
signIn(accountId);
return true;
}
case ID_SIGN_OUT:
{
// TODO: progress bar
signOut(accountId);
return true;
}
case ID_SETTINGS:
{
Intent intent = new Intent(Intent.ACTION_VIEW, Im.ProviderSettings.CONTENT_URI);
intent.addCategory(getProviderCategory(providerCursor));
intent.putExtra("providerId", providerId);
startActivity(intent);
return true;
}
}
return false;
| protected void | onCreate(android.os.Bundle icicle)
super.onCreate(icicle);
setTitle(R.string.landing_page_title);
if (!loadPlugins()) {
Log.e(TAG, "[onCreate] load plugin failed, no plugin found!");
finish();
return;
}
startPlugins();
// get everything except for Google Talk.
mProviderSelectionArgs[0] = Im.ProviderNames.GTALK;
mProviderCursor = managedQuery(Im.Provider.CONTENT_URI_WITH_ACCOUNT,
PROVIDER_PROJECTION,
PROVIDER_SELECTION /* selection */,
mProviderSelectionArgs /* selection args */,
Im.Provider.DEFAULT_SORT_ORDER);
mAdapter = new ProviderAdapter(this, mProviderCursor);
setListAdapter(mAdapter);
rebuildAccountToPluginMap();
mBrandingResources = new HashMap<Long, BrandingResources>();
loadDefaultBrandingRes();
loadBrandingResources();
registerForContextMenu(getListView());
| public void | onCreateContextMenu(android.view.ContextMenu menu, android.view.View v, android.view.ContextMenu.ContextMenuInfo menuInfo)
AdapterView.AdapterContextMenuInfo info;
try {
info = (AdapterView.AdapterContextMenuInfo) menuInfo;
} catch (ClassCastException e) {
Log.e(TAG, "bad menuInfo", e);
return;
}
Cursor providerCursor = (Cursor) getListAdapter().getItem(info.position);
menu.setHeaderTitle(providerCursor.getString(PROVIDER_FULLNAME_COLUMN));
if (providerCursor.isNull(ACTIVE_ACCOUNT_ID_COLUMN)) {
menu.add(0, ID_ADD_ACCOUNT, 0, R.string.menu_add_account);
return;
}
long providerId = providerCursor.getLong(PROVIDER_ID_COLUMN);
boolean isLoggingIn = isSigningIn(providerCursor);
boolean isLoggedIn = isSignedIn(providerCursor);
if (!isLoggedIn) {
menu.add(0, ID_SIGN_IN, 0, R.string.sign_in).setIcon(com.android.internal.R.drawable.ic_menu_login);
} else {
BrandingResources brandingRes = getBrandingResource(providerId);
menu.add(0, ID_VIEW_CONTACT_LIST, 0,
brandingRes.getString(BrandingResourceIDs.STRING_MENU_CONTACT_LIST));
menu.add(0, ID_SIGN_OUT, 0, R.string.menu_sign_out)
.setIcon(android.R.drawable.ic_menu_close_clear_cancel);
}
boolean isAccountEditible = providerCursor.getInt(ACTIVE_ACCOUNT_LOCKED) == 0;
if (isAccountEditible && !isLoggingIn && !isLoggedIn) {
menu.add(0, ID_EDIT_ACCOUNT, 0, R.string.menu_edit_account)
.setIcon(android.R.drawable.ic_menu_edit);
menu.add(0, ID_REMOVE_ACCOUNT, 0, R.string.menu_remove_account)
.setIcon(android.R.drawable.ic_menu_delete);
}
// always add a settings menu item
menu.add(0, ID_SETTINGS, 0, R.string.menu_settings);
| public boolean | onCreateOptionsMenu(android.view.Menu menu)
menu.add(0, ID_SIGN_OUT_ALL, 0, R.string.menu_sign_out_all)
.setIcon(android.R.drawable.ic_menu_close_clear_cancel);
return true;
| protected void | onListItemClick(android.widget.ListView l, android.view.View v, int position, long id)
Intent intent = null;
mProviderCursor.moveToPosition(position);
if (mProviderCursor.isNull(ACTIVE_ACCOUNT_ID_COLUMN)) {
// add account
intent = getCreateAccountIntent();
} else {
int state = mProviderCursor.getInt(ACCOUNT_CONNECTION_STATUS);
if (state == Im.ConnectionStatus.OFFLINE || state == Im.ConnectionStatus.CONNECTING) {
boolean isAccountEditible = mProviderCursor.getInt(ACTIVE_ACCOUNT_LOCKED) == 0;
if (isAccountEditible && mProviderCursor.isNull(ACTIVE_ACCOUNT_PW_COLUMN)) {
// no password, edit the account
intent = getEditAccountIntent();
} else {
long accountId = mProviderCursor.getLong(ACTIVE_ACCOUNT_ID_COLUMN);
signIn(accountId);
}
} else {
intent = getViewContactsIntent();
}
}
if (intent != null) {
startActivity(intent);
}
| public boolean | onOptionsItemSelected(android.view.MenuItem item)
switch (item.getItemId()) {
case ID_SIGN_OUT_ALL:
signoutAll();
return true;
}
return super.onOptionsItemSelected(item);
| public boolean | onPrepareOptionsMenu(android.view.Menu menu)
super.onPrepareOptionsMenu(menu);
menu.findItem(ID_SIGN_OUT_ALL).setVisible(!allAccountsSignedOut());
return true;
| protected void | onRestart()
super.onRestart();
// refresh the accountToPlugin map after mProviderCursor is requeried
if (!rebuildAccountToPluginMap()) {
Log.w(TAG, "[onRestart] rebuiltAccountToPluginMap failed, reload plugins...");
if (!loadPlugins()) {
Log.e(TAG, "[onRestart] load plugin failed, no plugin found!");
finish();
return;
}
rebuildAccountToPluginMap();
}
startPlugins();
| protected void | onStop()
super.onStop();
stopPlugins();
| private boolean | rebuildAccountToPluginMap()
if (Log.isLoggable(TAG, Log.DEBUG)) {
log("rebuildAccountToPluginMap");
}
if (mAccountToPluginMap != null) {
mAccountToPluginMap.clear();
}
mAccountToPluginMap = new HashMap<Long, PluginInfo>();
mProviderCursor.moveToFirst();
boolean retVal = true;
do {
long accountId = mProviderCursor.getLong(ACTIVE_ACCOUNT_ID_COLUMN);
if (accountId == 0) {
continue;
}
String name = mProviderCursor.getString(PROVIDER_NAME_COLUMN);
PluginInfo pluginInfo = mProviderToPluginMap.get(name);
if (pluginInfo != null) {
if (Log.isLoggable(TAG, Log.DEBUG)) {
log("rebuildAccountToPluginMap: add plugin for acct=" + accountId + ", provider=" + name);
}
mAccountToPluginMap.put(accountId, pluginInfo);
} else {
Log.w(TAG, "[LandingPage] no plugin found for " + name);
retVal = false;
}
} while (mProviderCursor.moveToNext()) ;
return retVal;
| private void | signIn(long accountId)
if (accountId == 0) {
Log.w(TAG, "signIn: account id is 0, bail");
return;
}
boolean isAccountEditible = mProviderCursor.getInt(ACTIVE_ACCOUNT_LOCKED) == 0;
if (isAccountEditible && mProviderCursor.isNull(ACTIVE_ACCOUNT_PW_COLUMN)) {
// no password, edit the account
if (Log.isLoggable(TAG, Log.DEBUG)) log("no pw for account " + accountId);
Intent intent = getEditAccountIntent();
startActivity(intent);
return;
}
PluginInfo pluginInfo = mAccountToPluginMap.get(accountId);
if (pluginInfo == null) {
Log.e(TAG, "signIn: cannot find plugin for account " + accountId);
return;
}
try {
if (Log.isLoggable(TAG, Log.DEBUG)) log("sign in for account " + accountId);
pluginInfo.mPlugin.signIn(accountId);
} catch (RemoteException ex) {
Log.e(TAG, "signIn failed", ex);
}
| private void | signOut(long accountId)
if (accountId == 0) {
Log.w(TAG, "signOut: account id is 0, bail");
return;
}
PluginInfo pluginInfo = mAccountToPluginMap.get(accountId);
if (pluginInfo == null) {
Log.e(TAG, "signOut: cannot find plugin for account " + accountId);
return;
}
try {
if (Log.isLoggable(TAG, Log.DEBUG)) log("sign out for account " + accountId);
pluginInfo.mPlugin.signOut(accountId);
} catch (RemoteException ex) {
Log.e(TAG, "signOut failed", ex);
}
| private void | signoutAll()
do {
long accountId = mProviderCursor.getLong(ACTIVE_ACCOUNT_ID_COLUMN);
signOut(accountId);
} while (mProviderCursor.moveToNext()) ;
| private void | startPlugins()
Iterator<PluginInfo> itor = mProviderToPluginMap.values().iterator();
while (itor.hasNext()) {
PluginInfo pluginInfo = itor.next();
try {
pluginInfo.mPlugin.onStart();
} catch (RemoteException e) {
Log.e(TAG, "Could not start plugin " + pluginInfo.mPackageName, e);
}
}
| private void | stopPlugins()
Iterator<PluginInfo> itor = mProviderToPluginMap.values().iterator();
while (itor.hasNext()) {
PluginInfo pluginInfo = itor.next();
try {
pluginInfo.mPlugin.onStop();
} catch (RemoteException e) {
Log.e(TAG, "Could not stop plugin " + pluginInfo.mPackageName, e);
}
}
|
|