Home | History | Annotate | Download | only in app
      1 /*
      2  * Copyright (C) 2007-2008 Esmertec AG.
      3  * Copyright (C) 2007-2008 The Android Open Source Project
      4  *
      5  * Licensed under the Apache License, Version 2.0 (the "License");
      6  * you may not use this file except in compliance with the License.
      7  * You may obtain a copy of 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,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  */
     17 package com.android.im.app;
     18 
     19 import com.android.im.IImConnection;
     20 import com.android.im.R;
     21 import com.android.im.engine.ImErrorInfo;
     22 import com.android.im.engine.Presence;
     23 import com.android.im.plugin.ImpsConfigNames;
     24 import com.android.im.provider.Imps;
     25 import com.google.android.collect.Lists;
     26 
     27 import android.app.Activity;
     28 import android.app.AlertDialog;
     29 import android.content.Context;
     30 import android.content.DialogInterface;
     31 import android.graphics.drawable.Drawable;
     32 import android.os.RemoteException;
     33 import android.text.TextUtils;
     34 import android.util.AttributeSet;
     35 import android.view.KeyEvent;
     36 import android.view.View;
     37 import android.view.ViewGroup;
     38 import android.widget.EditText;
     39 import android.widget.ImageButton;
     40 import android.widget.LinearLayout;
     41 import android.widget.TextView;
     42 
     43 import java.util.List;
     44 
     45 public class UserPresenceView extends LinearLayout {
     46 
     47     private ImageButton mStatusDialogButton;
     48 
     49     // views of the popup window
     50     TextView mStatusBar;
     51 
     52     private final SimpleAlertHandler mHandler;
     53 
     54     private IImConnection mConn;
     55     private long mProviderId;
     56     Presence mPresence;
     57 
     58     private String mLastStatusText;
     59     final List<StatusItem> mStatusItems = Lists.newArrayList();
     60 
     61     public UserPresenceView(Context context, AttributeSet attrs) {
     62         super(context, attrs);
     63         mHandler = new SimpleAlertHandler((Activity)context);
     64     }
     65 
     66     @Override
     67     protected void onFinishInflate() {
     68         super.onFinishInflate();
     69 
     70         mStatusDialogButton = (ImageButton)findViewById(R.id.statusDropDownButton);
     71         mStatusDialogButton.setOnClickListener(new OnClickListener() {
     72             public void onClick(View v) {
     73                 showStatusListDialog();
     74             }
     75         });
     76     }
     77 
     78     private void showStatusListDialog() {
     79         if (mConn == null) {
     80             return;
     81         }
     82 
     83         AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
     84         builder.setAdapter(getStatusAdapter(),
     85                 new DialogInterface.OnClickListener() {
     86                     public void onClick(DialogInterface dialog, int which) {
     87                         StatusItem item = mStatusItems.get(which);
     88                         int oldStatus = mPresence.getStatus();
     89                         if (item.getStatus() != oldStatus) {
     90                             updatePresence(item.getStatus(), item.getText().toString());
     91                         }
     92                     }
     93                 });
     94         builder.show();
     95     }
     96 
     97     private StatusIconAdapter getStatusAdapter() {
     98         try {
     99             mStatusItems.clear();
    100             int[] supportedStatus = mConn.getSupportedPresenceStatus();
    101             for (int i = 0; i < supportedStatus.length; i++) {
    102                 int s = PresenceUtils.convertStatus(supportedStatus[i]);
    103                 if (s == Imps.Presence.OFFLINE) {
    104                     s = Imps.Presence.INVISIBLE;
    105                 }
    106                 ImApp app = ImApp.getApplication((Activity)mContext);
    107                 BrandingResources brandingRes = app.getBrandingResource(mProviderId);
    108                 Drawable icon = brandingRes.getDrawable(PresenceUtils.getStatusIconId(s));
    109                 String text = brandingRes.getString(PresenceUtils.getStatusStringRes(s));
    110                 mStatusItems.add(new StatusItem(supportedStatus[i], icon, text));
    111             }
    112         } catch (RemoteException e) {
    113             mHandler.showServiceErrorAlert();
    114         }
    115 
    116         return new StatusIconAdapter(mContext, mStatusItems);
    117     }
    118 
    119     void updateStatusText() {
    120         String newStatusText = mStatusBar.getText().toString();
    121         if (TextUtils.isEmpty(newStatusText)) {
    122             newStatusText = "";
    123         }
    124         if (!newStatusText.equals(mLastStatusText)) {
    125             updatePresence(-1, newStatusText);
    126         }
    127     }
    128 
    129     public void setConnection(IImConnection conn) {
    130         mConn = conn;
    131         try {
    132             mPresence = conn.getUserPresence();
    133             mProviderId = conn.getProviderId();
    134         } catch (RemoteException e) {
    135             mHandler.showServiceErrorAlert();
    136         }
    137         if (mPresence == null) {
    138             mPresence = new Presence();
    139         }
    140         updateView();
    141     }
    142 
    143     private void updateView() {
    144         ImApp app = ImApp.getApplication((Activity)mContext);
    145         BrandingResources brandingRes = app.getBrandingResource(mProviderId);
    146         int status = PresenceUtils.convertStatus(mPresence.getStatus());
    147         mStatusDialogButton.setImageDrawable(brandingRes.getDrawable(
    148                 PresenceUtils.getStatusIconId(status)));
    149 
    150         String statusText = mPresence.getStatusText();
    151         if (TextUtils.isEmpty(statusText)) {
    152             statusText = brandingRes.getString(PresenceUtils.getStatusStringRes(status));
    153         }
    154         mLastStatusText = statusText;
    155 
    156         if (mStatusBar == null) {
    157             mStatusBar = initStatusBar(mProviderId);
    158         }
    159         mStatusBar.setText(statusText);
    160 
    161         // Disable the user to edit the custom status text because
    162         // the AIM and MSN server don't support it now.
    163         ProviderDef provider = app.getProvider(mProviderId);
    164         String providerName = provider == null ? null : provider.mName;
    165         if (Imps.ProviderNames.AIM.equals(providerName)
    166                 || Imps.ProviderNames.MSN.equals(providerName)) {
    167             mStatusBar.setFocusable(false);
    168         }
    169     }
    170 
    171     private TextView initStatusBar(long providerId) {
    172         String value = Imps.ProviderSettings.getStringValue(
    173                             mContext.getContentResolver(), providerId,
    174                             ImpsConfigNames.SUPPORT_USER_DEFINED_PRESENCE);
    175 
    176         if ("true".equalsIgnoreCase(value)) {
    177             EditText statusEdit = (EditText) findViewById(R.id.statusEdit);
    178             statusEdit.setVisibility(View.VISIBLE);
    179             statusEdit.setOnKeyListener(new OnKeyListener() {
    180                 public boolean onKey(View v, int keyCode, KeyEvent event) {
    181                     if (KeyEvent.ACTION_DOWN == event.getAction()) {
    182                         switch (keyCode) {
    183                             case KeyEvent.KEYCODE_DPAD_CENTER:
    184                             case KeyEvent.KEYCODE_ENTER:
    185                                 updateStatusText();
    186                                 return true;
    187                         }
    188                     }
    189                     return false;
    190                 }
    191             });
    192 
    193             statusEdit.setOnFocusChangeListener(new View.OnFocusChangeListener(){
    194                 public void onFocusChange(View v, boolean hasFocus) {
    195                     if (!hasFocus) {
    196                         updateStatusText();
    197                     }
    198                 }
    199             });
    200 
    201             return statusEdit;
    202         } else {
    203             TextView statusView = (TextView) findViewById(R.id.statusView);
    204             statusView.setVisibility(View.VISIBLE);
    205             return statusView;
    206         }
    207     }
    208 
    209     void updatePresence(int status, String statusText) {
    210         if (mPresence == null) {
    211             // We haven't get the connection yet. Don't allow to update presence now.
    212             return;
    213         }
    214 
    215         Presence newPresence = new Presence(mPresence);
    216 
    217         if (status != -1) {
    218             newPresence.setStatus(status);
    219         }
    220         newPresence.setStatusText(statusText);
    221 
    222         try {
    223             int res = mConn.updateUserPresence(newPresence);
    224             if (res != ImErrorInfo.NO_ERROR) {
    225                 mHandler.showAlert(R.string.error,
    226                         ErrorResUtils.getErrorRes(getResources(), res));
    227             } else {
    228                 mPresence = newPresence;
    229                 updateView();
    230             }
    231         } catch (RemoteException e) {
    232             mHandler.showServiceErrorAlert();
    233         }
    234     }
    235 
    236     private static class StatusItem implements ImageListAdapter.ImageListItem {
    237         private final int mStatus;
    238         private final Drawable mIcon;
    239         private final String   mText;
    240 
    241         public StatusItem(int status, Drawable icon, String text) {
    242             mStatus = status;
    243             mIcon = icon;
    244             mText = text;
    245         }
    246 
    247         public Drawable getDrawable() {
    248             return mIcon;
    249         }
    250 
    251         public CharSequence getText() {
    252             return mText;
    253         }
    254 
    255         public int getStatus() {
    256             return mStatus;
    257         }
    258     }
    259 
    260     private static class StatusIconAdapter extends ImageListAdapter {
    261         public StatusIconAdapter(Context context, List<StatusItem> data) {
    262             super(context, data);
    263         }
    264 
    265         @Override
    266         public long getItemId(int position) {
    267             StatusItem item = (StatusItem)getItem(position);
    268             return item.getStatus();
    269         }
    270 
    271         @Override
    272         public View getView(int position, View convertView, ViewGroup parent) {
    273             View view = super.getView(position, convertView, parent);
    274             return view;
    275         }
    276     }
    277 }
    278