# HG changeset patch # User Nikita Kozlov # Date 1257526849 -3600 # Node ID dd9ad5fec728f63c099b920fa2ed0d2e4280e50c # Parent b64155c6d0f3f239dd602510e08930842402e2c0# Parent 56af5554a081ec0418928ca5f2b65de4fa204e56 merge diff -r b64155c6d0f3 -r dd9ad5fec728 res/layout/chat.xml --- a/res/layout/chat.xml Fri Nov 06 18:00:19 2009 +0100 +++ b/res/layout/chat.xml Fri Nov 06 18:00:49 2009 +0100 @@ -1,42 +1,34 @@ - - - - - + + + - + android:paddingLeft="15sp"> + + + - - - - - - + + + + + diff -r b64155c6d0f3 -r dd9ad5fec728 src/com/beem/project/beem/BeemService.java diff -r b64155c6d0f3 -r dd9ad5fec728 src/com/beem/project/beem/service/Contact.java --- a/src/com/beem/project/beem/service/Contact.java Fri Nov 06 18:00:19 2009 +0100 +++ b/src/com/beem/project/beem/service/Contact.java Fri Nov 06 18:00:49 2009 +0100 @@ -6,12 +6,15 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; + import org.jivesoftware.smack.RosterGroup; import org.jivesoftware.smack.packet.Presence; import org.jivesoftware.smack.util.StringUtils; + import android.net.Uri; import android.os.Parcel; import android.os.Parcelable; + import com.beem.project.beem.utils.Status; /** diff -r b64155c6d0f3 -r dd9ad5fec728 src/com/beem/project/beem/ui/Chat.java --- a/src/com/beem/project/beem/ui/Chat.java Fri Nov 06 18:00:19 2009 +0100 +++ b/src/com/beem/project/beem/ui/Chat.java Fri Nov 06 18:00:49 2009 +0100 @@ -1,30 +1,50 @@ package com.beem.project.beem.ui; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; + +import org.jivesoftware.smack.util.StringUtils; +import org.jivesoftware.smackx.ChatState; import android.app.Activity; import android.content.ComponentName; +import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.ServiceConnection; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.RemoteException; +import android.text.util.Linkify; import android.util.Log; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; import android.widget.EditText; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.ListView; import android.widget.TextView; +import com.beem.project.beem.BeemService; import com.beem.project.beem.R; import com.beem.project.beem.service.Contact; import com.beem.project.beem.service.Message; import com.beem.project.beem.service.PresenceAdapter; import com.beem.project.beem.service.aidl.IBeemRosterListener; import com.beem.project.beem.service.aidl.IChat; +import com.beem.project.beem.service.aidl.IChatManager; +import com.beem.project.beem.service.aidl.IChatManagerListener; import com.beem.project.beem.service.aidl.IMessageListener; import com.beem.project.beem.service.aidl.IRoster; import com.beem.project.beem.service.aidl.IXmppFacade; import com.beem.project.beem.utils.BeemBroadcastReceiver; +import com.beem.project.beem.utils.Status; public class Chat extends Activity { @@ -34,17 +54,28 @@ SERVICE_INTENT.setComponent(new ComponentName("com.beem.project.beem", "com.beem.project.beem.BeemService")); } - private Handler _handler = new Handler(); + private Handler mHandler = new Handler(); - private IRoster _roster; - private Contact _contact; + private IRoster mRoster; + private Contact mContact; - private TextView _contactNameTextView; - private TextView _contactStatusMsgTextView; - private EditText _input; + private TextView mContactNameTextView; + private TextView mContactStatusMsgTextView; + private ImageView mContactStatusIcon; + private ListView mMessagesListView; + private EditText mInputField; + private Map mStatusIconsMap = new HashMap(); + + private List mListMessages = new ArrayList(); - private final ServiceConnection _conn = new BeemServiceConnection(); - private BeemBroadcastReceiver _broadcastReceiver; + private IChat mChat; + private IChatManager mChatManager; + private IChatManagerListener mChatManagerListener; + private IMessageListener mMessageListener; + private MessagesListAdapter mMessagesListAdapter; + + private final ServiceConnection mConn = new BeemServiceConnection(); + private BeemBroadcastReceiver mBroadcastReceiver; /** @@ -60,13 +91,30 @@ protected void onCreate(Bundle savedBundle) { super.onCreate(savedBundle); - _contactNameTextView = (TextView) findViewById(R.id.chat_contact_name); - _contactStatusMsgTextView = (TextView) findViewById(R.id.chat_contact_status_msg); - + Log.v(TAG, "BEGIN onCreate."); setContentView(R.layout.chat); + mMessagesListAdapter = new MessagesListAdapter(this); - _broadcastReceiver = new BeemBroadcastReceiver(_conn); - this.registerReceiver(_broadcastReceiver, new IntentFilter(BeemBroadcastReceiver.BEEM_CONNECTION_CLOSED)); + mHandler = new Handler(); + + // Listeners + mMessageListener = new OnMessageListener(); + mChatManagerListener = new OnChatManagerListener(); + + mBroadcastReceiver = new BeemBroadcastReceiver(mConn); + this.registerReceiver(mBroadcastReceiver, new IntentFilter(BeemBroadcastReceiver.BEEM_CONNECTION_CLOSED)); + + // UI + mContactNameTextView = (TextView) findViewById(R.id.chat_contact_name); + mContactStatusMsgTextView = (TextView) findViewById(R.id.chat_contact_status_msg); + mContactStatusIcon = (ImageView) findViewById(R.id.chat_contact_status_icon); + mMessagesListView = (ListView) findViewById(R.id.chat_messages); + mMessagesListView.setAdapter(mMessagesListAdapter); + mInputField = (EditText) findViewById(R.id.chat_input); + + prepareIconsStatus(); + + Log.v(TAG, "END onCreate."); } /** @@ -74,7 +122,17 @@ */ protected void onDestroy() { super.onDestroy(); - this.unregisterReceiver(_broadcastReceiver); + + Log.v(TAG, "BEGIN onDestroy."); + this.unregisterReceiver(mBroadcastReceiver); + if (mChatManager != null) { + try { + mChatManager.removeChatCreationListener(mChatManagerListener); + } catch (RemoteException e) { + Log.e(TAG, e.getMessage()); + } + } + Log.v(TAG, "END onDestroy."); } /** @@ -82,6 +140,10 @@ */ protected void onStart() { super.onStart(); + + Log.v(TAG, "BEGIN onStart."); + bindService(new Intent(this, BeemService.class), mConn, BIND_AUTO_CREATE); + Log.v(TAG, "END onStart."); } /** @@ -89,12 +151,45 @@ */ protected void onStop() { super.onStop(); + + Log.v(TAG, "BEGIN onStop."); + if (mChat != null) { + try { + mChat.setOpen(false); + } catch (RemoteException e) { + Log.e(TAG, e.getMessage()); + } + } + if (mBroadcastReceiver.isBinded()) { + unbindService(mConn); + } + Log.v(TAG, "END onStop."); } + /** + * {@inheritDoc}. + */ + protected void onResume() { + super.onResume(); + } + + /** + * {@inheritDoc}. + */ + protected void onPause() { + super.onPause(); + } + + /** + * {@inheritDoc}. + */ protected void onNewIntent(Intent intent) { super.onNewIntent(intent); - _contact = new Contact(intent.getData()); + Log.v(TAG, "BEGIN onNewIntent."); + mContact = new Contact(intent.getData()); + updateContactInformations(); + Log.v(TAG, "END onNewIntent."); } /** @@ -104,23 +199,43 @@ */ private final class BeemServiceConnection implements ServiceConnection { - private IXmppFacade _xmppFacade; + private IXmppFacade mXmppFacade; + private final BeemRosterListener mBeemRosterListener = new BeemRosterListener(); @Override public void onServiceConnected(ComponentName name, IBinder service) { - _xmppFacade = IXmppFacade.Stub.asInterface(service); - _broadcastReceiver.setBinded(true); + Log.v(TAG, "BEGIN onServiceConnected."); + mXmppFacade = IXmppFacade.Stub.asInterface(service); + mBroadcastReceiver.setBinded(true); try { - _roster = _xmppFacade.getRoster(); + mChatManager = mXmppFacade.getChatManager(); + + mRoster = mXmppFacade.getRoster(); + mRoster.addRosterListener(mBeemRosterListener); + + mChat = mChatManager.createChat((mContact = new Contact(getIntent().getData())), mMessageListener); + mChat.setOpen(true); + mChatManager.deleteChatNotification(mChat); + + updateContactInformations(); + updateContactStatusIcon(); } catch (RemoteException e) { Log.e(TAG, e.getMessage()); } + Log.v(TAG, "END onServiceConnected."); } @Override public void onServiceDisconnected(ComponentName name) { - _xmppFacade = null; - _broadcastReceiver.setBinded(false); + Log.v(TAG, "BEGIN onServiceDisconnected."); + mXmppFacade = null; + mBroadcastReceiver.setBinded(false); + try { + mRoster.removeRosterListener(mBeemRosterListener); + } catch (RemoteException e) { + Log.e(TAG, e.getMessage()); + } + Log.v(TAG, "END onServiceDisconnected."); } } @@ -154,8 +269,17 @@ @Override public void onPresenceChanged(PresenceAdapter presence) throws RemoteException { - // TODO Auto-generated method stub - + Log.v(TAG, "BEGIN onPresenceChanged."); + if (mContact.getJID().equals(StringUtils.parseBareAddress(presence.getFrom()))) { + mHandler.post(new Runnable() { + @Override + public void run() { + updateContactInformations(); + updateContactStatusIcon(); + } + }); + } + Log.v(TAG, "END onPresenceChanged."); } } @@ -167,14 +291,199 @@ private class OnMessageListener extends IMessageListener.Stub { @Override - public void processMessage(IChat chat, Message msg) throws RemoteException { - // TODO Auto-generated method stub + public void processMessage(IChat chat, final Message msg) throws RemoteException { + Log.v(TAG, "BEGIN processMessage."); + mHandler.post(new Runnable() { + + @Override + public void run() { + if (msg.getBody() != null && msg.getType() != Message.MSG_TYPE_ERROR) { + mListMessages.add(new MessageText(msg.getFrom(), msg.getBody())); + mMessagesListAdapter.notifyDataSetChanged(); + } + } + }); + Log.v(TAG, "END processMessage."); } @Override public void stateChanged(IChat chat) throws RemoteException { - // TODO Auto-generated method stub - + Log.v(TAG, "BEGIN stateChanged."); + mHandler.post(new Runnable() { + + @Override + public void run() { + } + }); + Log.v(TAG, "END stateChanged."); + } + + } + + /** + * + * @author Jamu + * + */ + private class OnChatManagerListener extends IChatManagerListener.Stub { + /** + * Constructor. + */ + public OnChatManagerListener() { + Log.v(TAG, "OnChatManagerListener constructor."); + } + + @Override + public void chatCreated(IChat chat, boolean locally) throws RemoteException { + Log.i(TAG, "Chat has been created."); } } + + /** + * Update the contact informations. + * + */ + private void updateContactInformations() { + Log.v(TAG, "BEGIN updateContactInformations."); + // Check for a contact name update + if (!(mContactNameTextView.getText().toString().equals(mContact.getName()))) + mContactNameTextView.setText(mContact.getName()); + + // Check for a contact status message update + if (!(mContactStatusMsgTextView.getText().toString().equals(mContact.getMsgState()))) { + Log.d(TAG, "Setting status message - " + mContact.getMsgState()); + if (mContact.getMsgState() == null) + mContactStatusMsgTextView.setText("Message de status de test de la mort tres tres long, voir meme trop long!"); + else + mContactStatusMsgTextView.setText(mContact.getMsgState()); + Linkify.addLinks(mContactStatusMsgTextView, Linkify.WEB_URLS); + } + Log.v(TAG, "END updateContactInformations."); + } + + /** + * Update the contact status icon. + */ + private void updateContactStatusIcon() { + Log.v(TAG, "BEGIN updateContactStatusIcon."); + mContactStatusIcon.setImageBitmap(mStatusIconsMap.get(mContact.getStatus())); + Log.v(TAG, "END updateContactStatusIcon."); + } + + /** + * Prepare the status icons map. + */ + private void prepareIconsStatus() { + mStatusIconsMap.put(Status.CONTACT_STATUS_AVAILABLE, BitmapFactory.decodeResource(getResources(), R.drawable.status_available)); + mStatusIconsMap.put(Status.CONTACT_STATUS_AVAILABLE_FOR_CHAT, BitmapFactory.decodeResource(getResources(), R.drawable.status_available)); + mStatusIconsMap.put(Status.CONTACT_STATUS_AWAY, BitmapFactory.decodeResource(getResources(), R.drawable.status_away)); + mStatusIconsMap.put(Status.CONTACT_STATUS_BUSY, BitmapFactory.decodeResource(getResources(), R.drawable.status_dnd)); + mStatusIconsMap.put(Status.CONTACT_STATUS_DISCONNECT, BitmapFactory.decodeResource(getResources(), R.drawable.status_offline)); + mStatusIconsMap.put(Status.CONTACT_STATUS_UNAVAILABLE, BitmapFactory.decodeResource(getResources(), R.drawable.status_requested)); + } + + private class MessagesListAdapter extends BaseAdapter { + + private Context mContext; + + public MessagesListAdapter(Context context) { + mContext = context; + } + + public int getCount() { + return mListMessages.size(); + } + + public Object getItem(int position) { + return position; + } + + public long getItemId(int position) { + return position; + } + + public View getView(int position, View convertView, ViewGroup parent) { + MessageView sv; + if (convertView == null) { + sv = new MessageView(mContext, mListMessages.get(position).getName(), + mListMessages.get(position).getMessage()); + } else { + sv = (MessageView) convertView; + sv.setName(mListMessages.get(position).getName()); + sv.setMessage(mListMessages.get(position).getMessage()); + } + + return sv; + } + } + + private class MessageText { + private String mName; + private String mMessage; + + public MessageText(String name, String message) { + mName = name; + mMessage = message; + } + + public String getName() { + return mName; + } + + public String getMessage() { + return mMessage; + } + + public void setName(String name) { + mName = name; + } + + public void setMessage(String message) { + mMessage = message; + } + } + + /** + * We will use a MessageView to display each message. + */ + private class MessageView extends LinearLayout { + private TextView mName; + private TextView mMessage; + + /** + * Constructor. + * @param context + * @param name + * @param message + */ + public MessageView(Context context, String name, String message) { + super(context); + + this.setOrientation(VERTICAL); + + mName = new TextView(context); + mName.setText(name); + addView(mName, new LinearLayout.LayoutParams( + LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT)); + + mMessage = new TextView(context); + mMessage.setText(message); + addView(mMessage, new LinearLayout.LayoutParams( + LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT)); + } + + /** + * Convenience method to set the title of a MessageView + */ + public void setName(String name) { + mName.setText(name); + } + + /** + * Convenience method to set the dialogue of a MessageView + */ + public void setMessage(String message) { + mMessage.setText(message); + } + } } diff -r b64155c6d0f3 -r dd9ad5fec728 src/com/beem/project/beem/ui/SendIM.java --- a/src/com/beem/project/beem/ui/SendIM.java Fri Nov 06 18:00:19 2009 +0100 +++ b/src/com/beem/project/beem/ui/SendIM.java Fri Nov 06 18:00:49 2009 +0100 @@ -476,7 +476,6 @@ Linkify.addLinks(mStatusText, Linkify.WEB_URLS); } } - } /**