• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 Esmertec AG.
3  * Copyright (C) 2008 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
6  * use this file except in compliance with the License. You may obtain a copy of
7  * the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14  * License for the specific language governing permissions and limitations under
15  * the License.
16  */
17 package com.android.im.app;
18 
19 import static com.android.im.service.ImServiceConstants.ACTION_MANAGE_SUBSCRIPTION;
20 import static com.android.im.service.ImServiceConstants.EXTRA_INTENT_ACCOUNT_ID;
21 import static com.android.im.service.ImServiceConstants.EXTRA_INTENT_FROM_ADDRESS;
22 import static com.android.im.service.ImServiceConstants.EXTRA_INTENT_PROVIDER_ID;
23 import static com.android.im.service.ImServiceConstants.EXTRA_INTENT_SHOW_MULTIPLE;
24 
25 import com.android.im.IChatSession;
26 import com.android.im.R;
27 import com.android.im.app.adapter.ChatListenerAdapter;
28 import com.android.im.plugin.BrandingResourceIDs;
29 
30 import android.app.Activity;
31 import android.app.AlertDialog;
32 import android.content.ContentResolver;
33 import android.content.ContentUris;
34 import android.content.DialogInterface;
35 import android.content.Intent;
36 import android.database.Cursor;
37 import android.graphics.drawable.Drawable;
38 import android.net.Uri;
39 import android.os.Bundle;
40 import android.os.Handler;
41 import android.os.RemoteException;
42 import android.provider.Im;
43 import android.view.KeyEvent;
44 import android.view.LayoutInflater;
45 import android.view.Menu;
46 import android.view.MenuInflater;
47 import android.view.MenuItem;
48 import android.view.View;
49 import android.view.ViewGroup;
50 import android.view.Window;
51 import android.widget.ImageView;
52 import android.widget.SimpleAdapter;
53 import android.widget.Toast;
54 
55 import java.util.ArrayList;
56 import java.util.HashMap;
57 import java.util.List;
58 import java.util.Map;
59 
60 public class NewChatActivity extends Activity {
61 
62     private static final int REQUEST_PICK_CONTACTS = RESULT_FIRST_USER + 1;
63 
64     ImApp mApp;
65 
66     ChatView mChatView;
67     SimpleAlertHandler mHandler;
68 
69     private AlertDialog mSmileyDialog;
70     private ChatSwitcher mChatSwitcher;
71 
72     private LayoutInflater mInflater;
73 
74     @Override
onCreate(Bundle icicle)75     protected void onCreate(Bundle icicle) {
76         super.onCreate(icicle);
77 
78         requestWindowFeature(Window.FEATURE_NO_TITLE);
79 
80         setContentView(R.layout.chat_view);
81 
82         mChatView = (ChatView) findViewById(R.id.chatView);
83         mHandler = mChatView.mHandler;
84         mInflater = LayoutInflater.from(this);
85 
86         mApp = ImApp.getApplication(this);
87         mChatSwitcher = new ChatSwitcher(this, mHandler, mApp, mInflater, null);
88 
89         final Handler handler = new Handler();
90         mApp.callWhenServiceConnected(handler, new Runnable() {
91             public void run() {
92                 resolveIntent(getIntent());
93             }
94         });
95     }
96 
97     @Override
onResume()98     protected void onResume() {
99         super.onResume();
100         mChatView.onResume();
101     }
102 
103     @Override
onPause()104     protected void onPause() {
105         mChatView.onPause();
106         super.onPause();
107     }
108 
109     @Override
onNewIntent(Intent intent)110     protected void onNewIntent(Intent intent) {
111         resolveIntent(intent);
112     }
113 
resolveIntent(Intent intent)114     void resolveIntent(Intent intent) {
115         if (requireOpenDashboardOnStart(intent)) {
116             long providerId = intent.getLongExtra(EXTRA_INTENT_PROVIDER_ID, -1L);
117             final long accountId = intent.getLongExtra(EXTRA_INTENT_ACCOUNT_ID, -1L);
118             if (providerId == -1L || accountId == -1L) {
119                 finish();
120             } else {
121                 mChatSwitcher.open();
122             }
123             return;
124         }
125 
126         if (ACTION_MANAGE_SUBSCRIPTION.equals(intent.getAction())) {
127             long providerId = intent.getLongExtra(EXTRA_INTENT_PROVIDER_ID, -1);
128             String from = intent.getStringExtra(EXTRA_INTENT_FROM_ADDRESS);
129             if ((providerId == -1) || (from == null)) {
130                 finish();
131             } else {
132                 mChatView.bindSubscription(providerId, from);
133             }
134         } else {
135             Uri data = intent.getData();
136             String type = getContentResolver().getType(data);
137             if (Im.Chats.CONTENT_ITEM_TYPE.equals(type)) {
138                 mChatView.bindChat(ContentUris.parseId(data));
139             } else if (Im.Invitation.CONTENT_ITEM_TYPE.equals(type)) {
140                 mChatView.bindInvitation(ContentUris.parseId(data));
141             }
142         }
143     }
144 
145     @Override
onCreateOptionsMenu(Menu menu)146     public boolean onCreateOptionsMenu(Menu menu) {
147         MenuInflater inflater = getMenuInflater();
148         inflater.inflate(R.menu.chat_screen_menu, menu);
149 
150         long providerId = mChatView.getProviderId();
151         BrandingResources brandingRes = mApp.getBrandingResource(providerId);
152         menu.findItem(R.id.menu_view_friend_list).setTitle(
153                 brandingRes.getString(BrandingResourceIDs.STRING_MENU_CONTACT_LIST));
154         menu.findItem(R.id.menu_switch_chats).setTitle(
155                 brandingRes.getString(BrandingResourceIDs.STRING_MENU_SWITCH_CHATS));
156         menu.findItem(R.id.menu_insert_smiley).setTitle(
157                 brandingRes.getString(BrandingResourceIDs.STRING_MENU_INSERT_SMILEY));
158         menu.findItem(R.id.menu_end_conversation).setTitle(
159                 brandingRes.getString(BrandingResourceIDs.STRING_MENU_END_CHAT));
160         menu.findItem(R.id.menu_view_profile).setTitle(
161                 brandingRes.getString(BrandingResourceIDs.STRING_MENU_VIEW_PROFILE));
162         menu.findItem(R.id.menu_block_contact).setTitle(
163                 brandingRes.getString(BrandingResourceIDs.STRING_MENU_BLOCK_CONTACT));
164         return true;
165     }
166 
167     @Override
onPrepareOptionsMenu(Menu menu)168     public boolean onPrepareOptionsMenu(Menu menu) {
169         super.onPrepareOptionsMenu(menu);
170 
171         //XXX hide the invite menu, group chat is not supported by the server.
172         menu.findItem(R.id.menu_invite_contact).setVisible(false);
173 
174         //XXX HACK: Yahoo! doesn't allow to block a friend. We can only block a temporary contact.
175         ProviderDef provider = mApp.getProvider(mChatView.getProviderId());
176         if ((provider != null) && Im.ProviderNames.YAHOO.equals(provider.mName)) {
177             if (Im.Contacts.TYPE_TEMPORARY != mChatView.mType) {
178                 menu.findItem(R.id.menu_block_contact).setVisible(false);
179             }
180         }
181         return true;
182     }
183 
184     @Override
onOptionsItemSelected(MenuItem item)185     public boolean onOptionsItemSelected(MenuItem item) {
186         switch (item.getItemId()) {
187             case R.id.menu_view_friend_list:
188                 finish();
189                 showRosterScreen();
190                 return true;
191 
192             case R.id.menu_insert_smiley:
193                 showSmileyDialog();
194                 return true;
195 
196             case R.id.menu_end_conversation:
197                 mChatView.closeChatSession();
198                 return true;
199 
200             case R.id.menu_switch_chats:
201                 if (mChatSwitcher.isOpen()) {
202                     mChatSwitcher.close();
203                 } else {
204                     mChatSwitcher.open();
205                 }
206 
207                 return true;
208 
209             case R.id.menu_invite_contact:
210                 startContactPicker();
211                 return true;
212 
213             case R.id.menu_view_profile:
214                 mChatView.viewProfile();
215                 return true;
216 
217             case R.id.menu_block_contact:
218                 mChatView.blockContact();
219                 return true;
220 
221             case R.id.menu_prev_chat:
222                 switchChat(-1);
223                 return true;
224 
225             case R.id.menu_next_chat:
226                 switchChat(1);
227                 return true;
228 
229             case R.id.menu_quick_switch_0:
230             case R.id.menu_quick_switch_1:
231             case R.id.menu_quick_switch_2:
232             case R.id.menu_quick_switch_3:
233             case R.id.menu_quick_switch_4:
234             case R.id.menu_quick_switch_5:
235             case R.id.menu_quick_switch_6:
236             case R.id.menu_quick_switch_7:
237             case R.id.menu_quick_switch_8:
238             case R.id.menu_quick_switch_9:
239                 mChatSwitcher.handleShortcut(item.getAlphabeticShortcut());
240                 return true;
241         }
242 
243         return super.onOptionsItemSelected(item);
244     }
245 
246     @Override
dispatchKeyEvent(KeyEvent event)247     public boolean dispatchKeyEvent(KeyEvent event) {
248         if (event.getKeyCode() == KeyEvent.KEYCODE_BACK
249                 && event.getAction() == KeyEvent.ACTION_DOWN) {
250             mChatView.closeChatSessionIfInactive();
251         }
252         return super.dispatchKeyEvent(event);
253     }
254 
255     /**
256      * Check whether we are asked to open Dashboard on startup.
257      */
requireOpenDashboardOnStart(Intent intent)258     private boolean requireOpenDashboardOnStart(Intent intent) {
259         return intent.getBooleanExtra(EXTRA_INTENT_SHOW_MULTIPLE, false);
260     }
261 
showRosterScreen()262     private void showRosterScreen() {
263         Intent intent = new Intent(Intent.ACTION_VIEW);
264         intent.setClass(this, ContactListActivity.class);
265         intent.putExtra(EXTRA_INTENT_ACCOUNT_ID, mChatView.getAccountId());
266         startActivity(intent);
267     }
268 
showSmileyDialog()269     private void showSmileyDialog() {
270         if (mSmileyDialog == null) {
271             long providerId = mChatView.getProviderId();
272 
273             final BrandingResources brandingRes = mApp.getBrandingResource(providerId);
274             int[] icons = brandingRes.getSmileyIcons();
275             String[] names = brandingRes.getStringArray(
276                     BrandingResourceIDs.STRING_ARRAY_SMILEY_NAMES);
277             final String[] texts = brandingRes.getStringArray(
278                     BrandingResourceIDs.STRING_ARRAY_SMILEY_TEXTS);
279 
280             final int N = names.length;
281 
282             List<Map<String, ?>> entries = new ArrayList<Map<String, ?>>();
283             for (int i = 0; i < N; i++) {
284                 // We might have different ASCII for the same icon, skip it if
285                 // the icon is already added.
286                 boolean added = false;
287                 for (int j = 0; j < i; j++) {
288                     if (icons[i] == icons[j]) {
289                         added = true;
290                         break;
291                     }
292                 }
293                 if (!added) {
294                     HashMap<String, Object> entry = new HashMap<String, Object>();
295 
296                     entry. put("icon", icons[i]);
297                     entry. put("name", names[i]);
298                     entry.put("text", texts[i]);
299 
300                     entries.add(entry);
301                 }
302             }
303 
304             final SimpleAdapter a = new SimpleAdapter(
305                     this,
306                     entries,
307                     R.layout.smiley_menu_item,
308                     new String[] {"icon", "name", "text"},
309                     new int[] {R.id.smiley_icon, R.id.smiley_name, R.id.smiley_text});
310             SimpleAdapter.ViewBinder viewBinder = new SimpleAdapter.ViewBinder() {
311                 public boolean setViewValue(View view, Object data, String textRepresentation) {
312                     if (view instanceof ImageView) {
313                         Drawable img = brandingRes.getSmileyIcon((Integer)data);
314                         ((ImageView)view).setImageDrawable(img);
315                         return true;
316                     }
317                     return false;
318                 }
319             };
320             a.setViewBinder(viewBinder);
321 
322             AlertDialog.Builder b = new AlertDialog.Builder(this);
323 
324             b.setTitle(brandingRes.getString(
325                     BrandingResourceIDs.STRING_MENU_INSERT_SMILEY));
326 
327             b.setCancelable(true);
328             b.setAdapter(a, new DialogInterface.OnClickListener() {
329                 public final void onClick(DialogInterface dialog, int which) {
330                     HashMap<String, Object> item = (HashMap<String, Object>) a.getItem(which);
331                     mChatView.insertSmiley((String)item.get("text"));
332                 }
333             });
334 
335             mSmileyDialog = b.create();
336         }
337 
338         mSmileyDialog.show();
339     }
340 
switchChat(int delta)341     private void switchChat(int delta) {
342         long providerId = mChatView.getProviderId();
343         long accountId = mChatView.getAccountId();
344         String contact = mChatView.getUserName();
345 
346         mChatSwitcher.rotateChat(delta, contact, accountId, providerId);
347     }
348 
startContactPicker()349     private void startContactPicker() {
350         Uri.Builder builder = Im.Contacts.CONTENT_URI_ONLINE_CONTACTS_BY.buildUpon();
351         ContentUris.appendId(builder, mChatView.getProviderId());
352         ContentUris.appendId(builder, mChatView.getAccountId());
353         Uri data = builder.build();
354 
355         try {
356             Intent i = new Intent(Intent.ACTION_PICK, data);
357             i.putExtra(ContactsPickerActivity.EXTRA_EXCLUDED_CONTACTS,
358                     mChatView.getCurrentChatSession().getPariticipants());
359             startActivityForResult(i, REQUEST_PICK_CONTACTS);
360         } catch (RemoteException e) {
361             mHandler.showServiceErrorAlert();
362         }
363     }
364 
365     @Override
onActivityResult(int requestCode, int resultCode, Intent data)366     protected void onActivityResult(int requestCode, int resultCode,
367             Intent data) {
368         if (resultCode == RESULT_OK) {
369             if (requestCode == REQUEST_PICK_CONTACTS) {
370                 String username = data.getStringExtra(
371                         ContactsPickerActivity.EXTRA_RESULT_USERNAME);
372                 try {
373                     IChatSession chatSession = mChatView.getCurrentChatSession();
374                     if (chatSession.isGroupChatSession()) {
375                         chatSession.inviteContact(username);
376                         showInvitationHasSent(username);
377                     } else {
378                         chatSession.convertToGroupChat();
379                         new ContactInvitor(chatSession, username).start();
380                     }
381                 } catch (RemoteException e) {
382                     mHandler.showServiceErrorAlert();
383                 }
384             }
385         }
386     }
387 
showInvitationHasSent(String contact)388     void showInvitationHasSent(String contact) {
389         Toast.makeText(NewChatActivity.this,
390                 getString(R.string.invitation_sent_prompt, contact),
391                 Toast.LENGTH_SHORT).show();
392     }
393 
394     private class ContactInvitor extends ChatListenerAdapter {
395         private final IChatSession mChatSession;
396         String mContact;
397 
ContactInvitor(IChatSession session, String data)398         public ContactInvitor(IChatSession session, String data) {
399             mChatSession = session;
400             mContact = data;
401         }
402 
403         @Override
onConvertedToGroupChat(IChatSession ses)404         public void onConvertedToGroupChat(IChatSession ses) {
405             try {
406                 final long chatId = mChatSession.getId();
407                 mChatSession.inviteContact(mContact);
408                 mHandler.post(new Runnable(){
409                     public void run() {
410                         mChatView.bindChat(chatId);
411                         showInvitationHasSent(mContact);
412                     }
413                 });
414                 mChatSession.unregisterChatListener(this);
415             } catch (RemoteException e) {
416                 mHandler.showServiceErrorAlert();
417             }
418         }
419 
start()420         public void start() throws RemoteException {
421             mChatSession.registerChatListener(this);
422         }
423     }
424 }
425