diff options
Diffstat (limited to 'src/com/android/im/app/ContactListActivity.java')
-rw-r--r-- | src/com/android/im/app/ContactListActivity.java | 447 |
1 files changed, 447 insertions, 0 deletions
diff --git a/src/com/android/im/app/ContactListActivity.java b/src/com/android/im/app/ContactListActivity.java new file mode 100644 index 0000000..e0e62fe --- /dev/null +++ b/src/com/android/im/app/ContactListActivity.java @@ -0,0 +1,447 @@ +/* + * Copyright (C) 2007-2008 Esmertec AG. + * Copyright (C) 2007-2008 The Android Open Source Project + * + * 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 com.android.im.app; + +import com.android.im.IImConnection; +import com.android.im.R; +import com.android.im.plugin.BrandingResourceIDs; +import com.android.im.service.ImServiceConstants; + +import android.app.Activity; +import android.content.ContentResolver; +import android.content.ContentUris; +import android.content.Intent; +import android.database.Cursor; +import android.net.Uri; +import android.os.Bundle; +import android.os.Message; +import android.os.RemoteException; +import android.provider.Im; +import android.util.Log; +import android.view.ContextMenu; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.Window; +import android.view.ContextMenu.ContextMenuInfo; +import android.widget.AdapterView; +import android.widget.AdapterView.AdapterContextMenuInfo; +import android.widget.ExpandableListView.ExpandableListContextMenuInfo; + +import java.util.Observable; +import java.util.Observer; + +public class ContactListActivity extends Activity implements View.OnCreateContextMenuListener{ + + private static final int MENU_START_CONVERSATION = Menu.FIRST; + private static final int MENU_VIEW_PROFILE = Menu.FIRST + 1; + private static final int MENU_BLOCK_CONTACT = Menu.FIRST + 2; + private static final int MENU_DELETE_CONTACT = Menu.FIRST + 3; + private static final int MENU_END_CONVERSATION = Menu.FIRST + 4; + + private static final String FILTER_STATE_KEY = "Filtering"; + + ImApp mApp; + + long mProviderId; + long mAccountId; + IImConnection mConn; + ContactListView mContactListView; + ContactListFilterView mFilterView; + SimpleAlertHandler mHandler; + + ContextMenuHandler mContextMenuHandler; + + boolean mIsFiltering; + + Im.ProviderSettings.QueryMap mSettingMap; + boolean mDestroyed; + + @Override + protected void onCreate(Bundle icicle) { + super.onCreate(icicle); + + getWindow().requestFeature(Window.FEATURE_LEFT_ICON); + + LayoutInflater inflate = getLayoutInflater(); + mContactListView = (ContactListView) inflate.inflate( + R.layout.contact_list_view, null); + + setContentView(mContactListView); + + Intent intent = getIntent(); + mAccountId = intent.getLongExtra(ImServiceConstants.EXTRA_INTENT_ACCOUNT_ID, -1); + if (mAccountId == -1) { + finish(); + return; + } + mApp = ImApp.getApplication(this); + + ContentResolver cr = getContentResolver(); + Cursor c = cr.query(ContentUris.withAppendedId(Im.Account.CONTENT_URI, mAccountId), + null, null, null, null); + if (c == null) { + finish(); + return; + } + if (!c.moveToFirst()) { + c.close(); + finish(); + return; + } + + mProviderId = c.getLong(c.getColumnIndexOrThrow(Im.Account.PROVIDER)); + mHandler = new MyHandler(this); + String username = c.getString(c.getColumnIndexOrThrow(Im.Account.USERNAME)); + + BrandingResources brandingRes = mApp.getBrandingResource(mProviderId); + setTitle(brandingRes.getString(BrandingResourceIDs.STRING_BUDDY_LIST_TITLE, username)); + getWindow().setFeatureDrawable(Window.FEATURE_LEFT_ICON, + brandingRes.getDrawable(BrandingResourceIDs.DRAWABLE_LOGO)); + + mSettingMap = new Im.ProviderSettings.QueryMap(getContentResolver(), mProviderId, true, null); + + mApp.callWhenServiceConnected(mHandler, new Runnable(){ + public void run() { + if (!mDestroyed) { + mApp.dismissNotifications(mProviderId); + mConn = mApp.getConnection(mProviderId); + mContactListView.setConnection(mConn); + mContactListView.setHideOfflineContacts(mSettingMap.getHideOfflineContacts()); + } + } + }); + + mContextMenuHandler = new ContextMenuHandler(); + mContactListView.getListView().setOnCreateContextMenuListener(this); + + mSettingMap.addObserver(new Observer() { + public void update(Observable observed, Object updateData) { + if (!mDestroyed) { + mContactListView.setHideOfflineContacts(mSettingMap.getHideOfflineContacts()); + } + } + }); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.contact_list_menu, menu); + + BrandingResources brandingRes = mApp.getBrandingResource(mProviderId); + menu.findItem(R.id.menu_invite_user).setTitle( + brandingRes.getString(BrandingResourceIDs.STRING_MENU_ADD_CONTACT)); + + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.menu_invite_user: + Intent i = new Intent(ContactListActivity.this, AddContactActivity.class); + i.putExtra(ImServiceConstants.EXTRA_INTENT_PROVIDER_ID, mProviderId); + i.putExtra(ImServiceConstants.EXTRA_INTENT_LIST_NAME, + mContactListView.getSelectedContactList()); + startActivity(i); + return true; + + case R.id.menu_blocked_contacts: + Uri.Builder builder = Im.BlockedList.CONTENT_URI.buildUpon(); + ContentUris.appendId(builder, mProviderId); + ContentUris.appendId(builder, mAccountId); + startActivity(new Intent(Intent.ACTION_VIEW, builder.build())); + return true; + + case R.id.menu_view_accounts: + Intent intent = new Intent(this, ChooseAccountActivity.class); + startActivity(intent); + finish(); + return true; + + case R.id.menu_settings: + intent = new Intent(this, SettingActivity.class); + intent.putExtra(ImServiceConstants.EXTRA_INTENT_PROVIDER_ID, mProviderId); + startActivity(intent); + return true; + + case R.id.menu_sign_out: + try { + mConn.logout(); + } catch (RemoteException e) { + } + return true; + } + return super.onOptionsItemSelected(item); + } + + @Override + protected void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + outState.putBoolean(FILTER_STATE_KEY, mIsFiltering); + + } + + @Override + protected void onRestoreInstanceState(Bundle savedInstanceState) { + boolean isFiltering = savedInstanceState.getBoolean(FILTER_STATE_KEY); + if (isFiltering) { + showFilterView(); + } + super.onRestoreInstanceState(savedInstanceState); + } + + @Override + public boolean dispatchKeyEvent(KeyEvent event) { + int keyCode = event.getKeyCode(); + + boolean handled = false; + if (mIsFiltering) { + handled = mFilterView.dispatchKeyEvent(event); + if (!handled && (KeyEvent.KEYCODE_BACK == keyCode) + && (KeyEvent.ACTION_DOWN == event.getAction())) { + showContactListView(); + handled = true; + } + } else { + handled = mContactListView.dispatchKeyEvent(event); + if (!handled && isReadable(keyCode, event) + && (KeyEvent.ACTION_DOWN == event.getAction())) { + showFilterView(); + handled = mFilterView.dispatchKeyEvent(event); + } + } + + if (!handled) { + handled = super.dispatchKeyEvent(event); + } + + return handled; + } + + private static boolean isReadable(int keyCode, KeyEvent event) { + if (KeyEvent.isModifierKey(keyCode) || event.isSystem()) { + return false; + } + + switch (keyCode) { + case KeyEvent.KEYCODE_DPAD_CENTER: + case KeyEvent.KEYCODE_DPAD_DOWN: + case KeyEvent.KEYCODE_DPAD_LEFT: + case KeyEvent.KEYCODE_DPAD_RIGHT: + case KeyEvent.KEYCODE_DPAD_UP: + case KeyEvent.KEYCODE_ENTER: + return false; + } + + return true; + } + + private void showFilterView() { + if (mFilterView == null ) { + mFilterView = (ContactListFilterView)getLayoutInflater().inflate( + R.layout.contact_list_filter_view, null); + mFilterView.getListView().setOnCreateContextMenuListener(this); + } + Uri uri = mSettingMap.getHideOfflineContacts() ? Im.Contacts.CONTENT_URI_ONLINE_CONTACTS_BY + : Im.Contacts.CONTENT_URI_CONTACTS_BY; + uri = ContentUris.withAppendedId(uri, mProviderId); + uri = ContentUris.withAppendedId(uri, mAccountId); + mFilterView.doFilter(uri, null); + + setContentView(mFilterView); + mFilterView.requestFocus(); + mIsFiltering = true; + } + + void showContactListView() { + if (mIsFiltering) { + setContentView(mContactListView); + mContactListView.requestFocus(); + mContactListView.invalidate(); + mIsFiltering = false; + } + } + + @Override + protected void onPause() { + super.onPause(); + mApp.unregisterForConnEvents(mHandler); + } + + @Override + protected void onResume() { + super.onResume(); + mApp.registerForConnEvents(mHandler); + } + + @Override + protected void onDestroy() { + mDestroyed = true; + // set connection to null to unregister listeners. + mContactListView.setConnection(null); + if (mSettingMap != null) { + mSettingMap.close(); + } + super.onDestroy(); + } + + static void log(String msg) { + Log.d(ImApp.LOG_TAG, "<ContactListActivity> " +msg); + } + + @Override + public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { + boolean chatSelected = false; + boolean contactSelected = false; + Cursor contactCursor; + if (mIsFiltering) { + AdapterView.AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo; + mContextMenuHandler.mPosition = info.position; + contactSelected = true; + contactCursor = mFilterView.getContactAtPosition(info.position); + } else { + ExpandableListContextMenuInfo info = (ExpandableListContextMenuInfo) menuInfo; + mContextMenuHandler.mPosition = info.packedPosition; + contactSelected = mContactListView.isContactAtPosition(info.packedPosition); + chatSelected = mContactListView.isConversationAtPosition(info.packedPosition); + contactCursor = mContactListView.getContactAtPosition(info.packedPosition); + } + + boolean allowBlock = true; + if (contactCursor != null) { + //XXX HACK: Yahoo! doesn't allow to block a friend. We can only block a temporary contact. + ProviderDef provider = mApp.getProvider(mProviderId); + if (Im.ProviderNames.YAHOO.equals(provider.mName)) { + int type = contactCursor.getInt(contactCursor.getColumnIndexOrThrow(Im.Contacts.TYPE)); + allowBlock = (type == Im.Contacts.TYPE_TEMPORARY); + } + + int nickNameIndex = contactCursor.getColumnIndexOrThrow(Im.Contacts.NICKNAME); + + menu.setHeaderTitle(contactCursor.getString(nickNameIndex)); + } + + BrandingResources brandingRes = mApp.getBrandingResource(mProviderId); + String menu_end_conversation = brandingRes.getString( + BrandingResourceIDs.STRING_MENU_END_CHAT); + String menu_view_profile = brandingRes.getString( + BrandingResourceIDs.STRING_MENU_VIEW_PROFILE); + String menu_block_contact = brandingRes.getString( + BrandingResourceIDs.STRING_MENU_BLOCK_CONTACT); + String menu_start_conversation = brandingRes.getString( + BrandingResourceIDs.STRING_MENU_START_CHAT); + String menu_delete_contact = brandingRes.getString( + BrandingResourceIDs.STRING_MENU_DELETE_CONTACT); + + if (chatSelected) { + menu.add(0, MENU_END_CONVERSATION, 0, menu_end_conversation) + .setIcon(R.drawable.ic_menu_end_conversation) + .setOnMenuItemClickListener(mContextMenuHandler); + menu.add(0, MENU_VIEW_PROFILE, 0, menu_view_profile) + .setIcon(R.drawable.ic_menu_my_profile) + .setOnMenuItemClickListener(mContextMenuHandler); + if (allowBlock) { + menu.add(0, MENU_BLOCK_CONTACT, 0, menu_block_contact) + .setIcon(R.drawable.ic_menu_block) + .setOnMenuItemClickListener(mContextMenuHandler); + } + } else if (contactSelected) { + menu.add(0, MENU_START_CONVERSATION, 0, menu_start_conversation) + .setIcon(R.drawable.ic_menu_start_conversation) + .setOnMenuItemClickListener(mContextMenuHandler); + menu.add(0, MENU_VIEW_PROFILE, 0, menu_view_profile) + .setIcon(R.drawable.ic_menu_view_profile) + .setOnMenuItemClickListener(mContextMenuHandler); + if (allowBlock) { + menu.add(0, MENU_BLOCK_CONTACT, 0, menu_block_contact) + .setIcon(R.drawable.ic_menu_block) + .setOnMenuItemClickListener(mContextMenuHandler); + } + menu.add(0, MENU_DELETE_CONTACT, 0, menu_delete_contact) + .setIcon(android.R.drawable.ic_menu_delete) + .setOnMenuItemClickListener(mContextMenuHandler); + } + } + + final class ContextMenuHandler implements MenuItem.OnMenuItemClickListener { + long mPosition; + + public boolean onMenuItemClick(MenuItem item) { + Cursor c; + if (mIsFiltering) { + c = mFilterView.getContactAtPosition((int)mPosition); + } else { + c = mContactListView.getContactAtPosition(mPosition); + } + + switch (item.getItemId()) { + case MENU_START_CONVERSATION: + mContactListView.startChat(c); + break; + case MENU_VIEW_PROFILE: + mContactListView.viewContactPresence(c); + break; + case MENU_BLOCK_CONTACT: + mContactListView.blockContact(c); + break; + case MENU_DELETE_CONTACT: + mContactListView.removeContact(c); + break; + case MENU_END_CONVERSATION: + mContactListView.endChat(c); + break; + default: + return false; + } + + if (mIsFiltering) { + showContactListView(); + } + return true; + } + } + + final class MyHandler extends SimpleAlertHandler { + public MyHandler(Activity activity) { + super(activity); + } + + @Override + public void handleMessage(Message msg) { + if (msg.what == ImApp.EVENT_CONNECTION_DISCONNECTED) { + if (Log.isLoggable(ImApp.LOG_TAG, Log.DEBUG)) { + log("Handle event connection disconnected."); + } + promptDisconnectedEvent(msg); + long providerId = ((long)msg.arg1 << 32) | msg.arg2; + if (providerId == mProviderId) { + if (Log.isLoggable(ImApp.LOG_TAG, Log.DEBUG)) { + log("Current connection disconnected, finish"); + } + finish(); + } + return; + } + super.handleMessage(msg); + } + } +} |