Java tutorial
/* * Copyright 2016 Mobicage NV * * 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. * * @@license_version:1.1@@ */ package com.mobicage.rogerthat.plugins.messaging; import java.io.File; import java.io.IOException; import java.util.Comparator; import java.util.HashMap; import java.util.Map; import java.util.SortedSet; import java.util.Timer; import java.util.TimerTask; import java.util.TreeSet; import java.util.UUID; import org.json.JSONObject; import org.json.simple.JSONValue; import thirdparty.nishantnair.FlowLayout; import android.Manifest; import android.app.AlertDialog; import android.app.ProgressDialog; import android.content.BroadcastReceiver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Color; import android.graphics.PorterDuff; import android.graphics.Typeface; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.view.Gravity; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup.MarginLayoutParams; import android.view.WindowManager; import android.webkit.WebSettings; import android.webkit.WebView; import android.widget.Button; import android.widget.EditText; import android.widget.FrameLayout; import android.widget.HorizontalScrollView; import android.widget.ImageButton; import android.widget.ImageView; import android.widget.ImageView.ScaleType; import android.widget.LinearLayout; import android.widget.LinearLayout.LayoutParams; import android.widget.RelativeLayout; import android.widget.ScrollView; import android.widget.TableLayout; import android.widget.TableRow; import android.widget.TextView; import com.mobicage.rogerth.at.R; import com.mobicage.rogerthat.IdentityStore; import com.mobicage.rogerthat.MainActivity; import com.mobicage.rogerthat.ServiceBoundMapActivity; import com.mobicage.rogerthat.plugins.friends.Friend; import com.mobicage.rogerthat.plugins.friends.FriendBroadcastInfo; import com.mobicage.rogerthat.plugins.friends.FriendsPlugin; import com.mobicage.rogerthat.plugins.friends.ServiceActionMenuActivity; import com.mobicage.rogerthat.plugins.messaging.BrandingMgr.BrandingResult; import com.mobicage.rogerthat.plugins.messaging.BrandingMgr.ColorScheme; import com.mobicage.rogerthat.plugins.messaging.mfr.EmptyStaticFlowException; import com.mobicage.rogerthat.plugins.messaging.mfr.JsMfr; import com.mobicage.rogerthat.plugins.messaging.mfr.MessageFlowRun; import com.mobicage.rogerthat.plugins.messaging.widgets.Widget; import com.mobicage.rogerthat.util.IOUtils; import com.mobicage.rogerthat.util.TextUtils; import com.mobicage.rogerthat.util.logging.L; import com.mobicage.rogerthat.util.system.SafeBroadcastReceiver; import com.mobicage.rogerthat.util.system.SafeDialogInterfaceOnClickListener; import com.mobicage.rogerthat.util.system.SafeRunnable; import com.mobicage.rogerthat.util.system.SafeViewOnClickListener; import com.mobicage.rogerthat.util.system.SystemUtils; import com.mobicage.rogerthat.util.system.T; import com.mobicage.rogerthat.util.time.TimeUtils; import com.mobicage.rogerthat.util.ui.UIUtils; import com.mobicage.rpc.IJSONable; import com.mobicage.to.messaging.AttachmentTO; import com.mobicage.to.messaging.ButtonTO; import com.mobicage.to.messaging.MemberStatusTO; import com.mobicage.to.service.PressMenuIconRequestTO; public class ServiceMessageDetailActivity extends ServiceBoundMapActivity { private final static String HINT_BROADCAST = "com.mobicage.rogerthat.plugins.messaging.ServiceMessageDetailActivity.HINT_BROADCAST"; public final static String BUTTON_INFO = "buttonInfo"; public final static String STARTED_FROM_SERVICE_MENU = "STARTED_FROM_SERVICE_MENU"; private final static int[] DETAIL_SECTIONS = new int[] { R.id.previous_messages_in_thread_title, R.id.previous_messages_in_thread, R.id.message_section_title, R.id.member_details_title, R.id.members, R.id.next_messages_in_thread_title, R.id.next_messages_in_thread }; /** * Intent action which trigger an updateView(true) */ private static final String[] UPDATE_VIEW_INTENT_ACTIONS = new String[] { MessagingPlugin.MESSAGE_MEMBER_STATUS_UPDATE_RECEIVED_INTENT, MessagingPlugin.MESSAGE_LOCKED_INTENT, MessagingPlugin.MESSAGE_PROCESSED_INTENT, FriendsPlugin.FRIEND_UPDATE_INTENT, IdentityStore.IDENTITY_CHANGED_INTENT, FriendsPlugin.FRIENDS_LIST_REFRESHED, FriendsPlugin.FRIEND_AVATAR_CHANGED_INTENT }; public static final int PERMISSION_REQUEST_UI_FLAG_LOCATION = 1; public static final int PERMISSION_REQUEST_GPS_LCOATION_WIDGET = 2; public static final int PERMISSION_REQUEST_PHOTO_UPLOAD_WIDGET = 3; // UI Thread owns these private FriendsPlugin mFriendsPlugin; private MessagingPlugin mMessagingPlugin; private MessageStore mStore; private Message mCurrentMessage; private int mDisplayWidth; private BroadcastReceiver mBroadcastReceiver; private boolean mMustQuit = false; private ProgressDialog mDialog = null; private Timer mExpectNextTimer = null; private boolean mSomebodyAnswered = false; private boolean mTransfering = false; private Typeface mFontAwesomeTypeFace; private RelativeLayout activity; private ImageView mStatusImage; private String mContext; public void setTransfering(boolean b) { mTransfering = b; } public void transferComplete() { T.UI(); L.d("Transfer completed"); mTransfering = false; dismissTransferingDialog(); MemberStatusTO myMemberStatus = mCurrentMessage .getMemberStatus(mService.getIdentityStore().getIdentity().getEmail()); if ((myMemberStatus.status & MessagingPlugin.STATUS_ACKED) == MessagingPlugin.STATUS_ACKED) { ButtonTO button = mCurrentMessage.getButton(myMemberStatus.button_id); animateAfterAck(getExpectNext(button)); jumpToServiceHomeScreen(button, null); updateView(false); } } public void showTransferingDialog() { T.UI(); mDialog = new ProgressDialog(this); mDialog.setMessage(getString(R.string.transmitting)); mDialog.setCancelable(true); mDialog.setButton(DialogInterface.BUTTON_NEGATIVE, getString(R.string.send_to_background), new DialogInterface.OnClickListener() { // TODO: SafeRunnable @Override public void onClick(DialogInterface dialog, int which) { T.UI(); mTransfering = false; dismissTransferingDialog(); jumpToServiceHomeScreen(null, null); updateView(false); } }); mDialog.show(); } public void dismissTransferingDialog() { T.UI(); if (mDialog != null) { mDialog.dismiss(); mDialog = null; } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); mFontAwesomeTypeFace = Typeface.createFromAsset(getAssets(), "FontAwesome.ttf"); } @Override public boolean dispatchTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { View v = getCurrentFocus(); if (v instanceof EditText) { int scrcoords[] = new int[2]; v.getLocationOnScreen(scrcoords); float x = event.getRawX() + v.getLeft() - scrcoords[0]; float y = event.getRawY() + v.getTop() - scrcoords[1]; if (x < v.getLeft() || x >= v.getRight() || y < v.getTop() || y > v.getBottom()) { // Tapped outside the editText UIUtils.hideKeyboard(this, v); } } } return super.dispatchTouchEvent(event); } @Override protected void onServiceBound() { T.UI(); mFriendsPlugin = mService.getPlugin(FriendsPlugin.class); mMessagingPlugin = mService.getPlugin(MessagingPlugin.class); mStore = mMessagingPlugin.getStore(); mDisplayWidth = UIUtils.getDisplayWidth(this); final View activityView = LayoutInflater.from(this).inflate(R.layout.message_detail, null); ((ImageButton) activityView.findViewById(R.id.expand)).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { expandDetails(); } }); mStatusImage = (ImageView) activityView.findViewById(R.id.status_image); setContentView(activityView); activity = (RelativeLayout) activityView; final Intent intent = getIntent(); String messageKey = intent.getStringExtra("message"); mCurrentMessage = mStore.getFullMessageByKey(messageKey); if (intent.hasExtra("submitToJSMFR")) { messageSubmitToJsMfr(intent, intent.getAction()); } updateView(false); if (MainActivity.ACTION_NOTIFICATION_PHOTO_UPLOAD_DONE.equals(intent.getAction())) animateAfterAck(2); mBroadcastReceiver = getBroadcastReceiver(); final IntentFilter filter = getIntentFilter(); registerReceiver(mBroadcastReceiver, filter); ((TextView) findViewById(R.id.show_magic_message_header)) .setText(getString(R.string.show_message_header, getString(R.string.app_name))); } @Override protected void onServiceUnbound() { T.UI(); if (mBroadcastReceiver != null) unregisterReceiver(mBroadcastReceiver); if (mCurrentMessage.form != null) { LinearLayout widgetLayout = (LinearLayout) findViewById(R.id.widget_layout); Widget widget = (Widget) widgetLayout.getChildAt(0); widget.onServiceUnbound(); } } @Override protected void onDestroy() { if (mExpectNextTimer != null) mExpectNextTimer.cancel(); super.onDestroy(); } protected void expandDetails() { // Memberdetails for (int id : new int[] { R.id.member_details_title, R.id.members }) { findViewById(id).setVisibility(View.VISIBLE); } findViewById(R.id.member_summary).setVisibility(View.GONE); final ScrollView msgScrollView = (ScrollView) findViewById(R.id.message_scroll_view); msgScrollView.post(new SafeRunnable() { @Override protected void safeRun() throws Exception { msgScrollView.fullScroll(ScrollView.FOCUS_DOWN); } }); } protected void collapseDetails(int[] sections) { for (int id : sections) { findViewById(id).setVisibility(View.GONE); } } protected void updateMessageDetail(final boolean isUpdate) { T.UI(); // Set sender avatar ImageView avatarImage = (ImageView) findViewById(R.id.avatar); String sender = mCurrentMessage.sender; setAvatar(avatarImage, sender); // Set sender name TextView senderView = (TextView) findViewById(R.id.sender); final String senderName = mFriendsPlugin.getName(sender); senderView.setText(senderName == null ? sender : senderName); // Set timestamp TextView timestampView = (TextView) findViewById(R.id.timestamp); timestampView.setText(TimeUtils.getDayTimeStr(this, mCurrentMessage.timestamp * 1000)); // Set clickable region on top to go to friends detail final RelativeLayout messageHeader = (RelativeLayout) findViewById(R.id.message_header); messageHeader.setOnClickListener(getFriendDetailOnClickListener(mCurrentMessage.sender)); messageHeader.setVisibility(View.VISIBLE); // Set message TextView messageView = (TextView) findViewById(R.id.message); WebView web = (WebView) findViewById(R.id.webview); FrameLayout flay = (FrameLayout) findViewById(R.id.message_details); Resources resources = getResources(); flay.setBackgroundColor(resources.getColor(R.color.mc_background)); boolean showBranded = false; int darkSchemeTextColor = resources.getColor(android.R.color.primary_text_dark); int lightSchemeTextColor = resources.getColor(android.R.color.primary_text_light); senderView.setTextColor(lightSchemeTextColor); timestampView.setTextColor(lightSchemeTextColor); BrandingResult br = null; if (!TextUtils.isEmptyOrWhitespace(mCurrentMessage.branding)) { boolean brandingAvailable = false; try { brandingAvailable = mMessagingPlugin.getBrandingMgr().isBrandingAvailable(mCurrentMessage.branding); } catch (BrandingFailureException e1) { L.d(e1); } try { if (brandingAvailable) { br = mMessagingPlugin.getBrandingMgr().prepareBranding(mCurrentMessage); WebSettings settings = web.getSettings(); settings.setJavaScriptEnabled(false); settings.setBlockNetworkImage(false); web.loadUrl("file://" + br.file.getAbsolutePath()); web.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY); if (br.color != null) { flay.setBackgroundColor(br.color); } if (!br.showHeader) { messageHeader.setVisibility(View.GONE); MarginLayoutParams mlp = (MarginLayoutParams) web.getLayoutParams(); mlp.setMargins(0, 0, 0, mlp.bottomMargin); } else if (br.scheme == ColorScheme.dark) { senderView.setTextColor(darkSchemeTextColor); timestampView.setTextColor(darkSchemeTextColor); } showBranded = true; } else { mMessagingPlugin.getBrandingMgr().queueGenericBranding(mCurrentMessage.branding); } } catch (BrandingFailureException e) { L.bug("Could not display message with branding: branding is available, but prepareBranding failed", e); } } if (showBranded) { web.setVisibility(View.VISIBLE); messageView.setVisibility(View.GONE); } else { web.setVisibility(View.GONE); messageView.setVisibility(View.VISIBLE); messageView.setText(mCurrentMessage.message); } // Add list of members who did not ack yet FlowLayout memberSummary = (FlowLayout) findViewById(R.id.member_summary); memberSummary.removeAllViews(); SortedSet<MemberStatusTO> memberSummarySet = new TreeSet<MemberStatusTO>(getMemberstatusComparator()); for (MemberStatusTO ms : mCurrentMessage.members) { if ((ms.status & MessagingPlugin.STATUS_ACKED) != MessagingPlugin.STATUS_ACKED && !ms.member.equals(mCurrentMessage.sender)) { memberSummarySet.add(ms); } } FlowLayout.LayoutParams flowLP = new FlowLayout.LayoutParams(2, 0); for (MemberStatusTO ms : memberSummarySet) { FrameLayout fl = new FrameLayout(this); fl.setLayoutParams(flowLP); memberSummary.addView(fl); fl.addView(createParticipantView(ms)); } memberSummary.setVisibility(memberSummarySet.size() < 2 ? View.GONE : View.VISIBLE); // Add members statuses final LinearLayout members = (LinearLayout) findViewById(R.id.members); members.removeAllViews(); final String myEmail = mService.getIdentityStore().getIdentity().getEmail(); boolean isMember = false; mSomebodyAnswered = false; for (MemberStatusTO ms : mCurrentMessage.members) { boolean showMember = true; View view = getLayoutInflater().inflate(R.layout.message_member_detail, null); // Set receiver avatar RelativeLayout rl = (RelativeLayout) view.findViewById(R.id.avatar); rl.addView(createParticipantView(ms)); // Set receiver name TextView receiverView = (TextView) view.findViewById(R.id.receiver); final String memberName = mFriendsPlugin.getName(ms.member); receiverView.setText(memberName == null ? sender : memberName); // Set received timestamp TextView receivedView = (TextView) view.findViewById(R.id.received_timestamp); if ((ms.status & MessagingPlugin.STATUS_RECEIVED) == MessagingPlugin.STATUS_RECEIVED) { final String humanTime = TimeUtils.getDayTimeStr(this, ms.received_timestamp * 1000); if (ms.member.equals(mCurrentMessage.sender)) receivedView.setText(getString(R.string.sent_at, humanTime)); else receivedView.setText(getString(R.string.received_at, humanTime)); } else { receivedView.setText(R.string.not_yet_received); } // Set replied timestamp TextView repliedView = (TextView) view.findViewById(R.id.acked_timestamp); if ((ms.status & MessagingPlugin.STATUS_ACKED) == MessagingPlugin.STATUS_ACKED) { mSomebodyAnswered = true; String acked_timestamp = TimeUtils.getDayTimeStr(this, ms.acked_timestamp * 1000); if (ms.button_id != null) { ButtonTO button = null; for (ButtonTO b : mCurrentMessage.buttons) { if (b.id.equals(ms.button_id)) { button = b; break; } } if (button == null) { repliedView.setText(getString(R.string.dismissed_at, acked_timestamp)); // Do not show sender as member if he hasn't clicked a // button showMember = !ms.member.equals(mCurrentMessage.sender); } else { repliedView.setText(getString(R.string.replied_at, button.caption, acked_timestamp)); } } else { if (ms.custom_reply == null) { // Do not show sender as member if he hasn't clicked a // button showMember = !ms.member.equals(mCurrentMessage.sender); repliedView.setText(getString(R.string.dismissed_at, acked_timestamp)); } else repliedView.setText(getString(R.string.replied_at, ms.custom_reply, acked_timestamp)); } } else { repliedView.setText(R.string.not_yet_replied); showMember = !ms.member.equals(mCurrentMessage.sender); } if (br != null && br.scheme == ColorScheme.dark) { receiverView.setTextColor(darkSchemeTextColor); receivedView.setTextColor(darkSchemeTextColor); repliedView.setTextColor(darkSchemeTextColor); } else { receiverView.setTextColor(lightSchemeTextColor); receivedView.setTextColor(lightSchemeTextColor); repliedView.setTextColor(lightSchemeTextColor); } if (showMember) members.addView(view); isMember |= ms.member.equals(myEmail); } boolean isLocked = (mCurrentMessage.flags & MessagingPlugin.FLAG_LOCKED) == MessagingPlugin.FLAG_LOCKED; boolean canEdit = isMember && !isLocked; // Add attachments LinearLayout attachmentLayout = (LinearLayout) findViewById(R.id.attachment_layout); attachmentLayout.removeAllViews(); if (mCurrentMessage.attachments.length > 0) { attachmentLayout.setVisibility(View.VISIBLE); for (final AttachmentTO attachment : mCurrentMessage.attachments) { View v = getLayoutInflater().inflate(R.layout.attachment_item, null); ImageView attachment_image = (ImageView) v.findViewById(R.id.attachment_image); if (AttachmentViewerActivity.CONTENT_TYPE_JPEG.equalsIgnoreCase(attachment.content_type) || AttachmentViewerActivity.CONTENT_TYPE_PNG.equalsIgnoreCase(attachment.content_type)) { attachment_image.setImageResource(R.drawable.attachment_img); } else if (AttachmentViewerActivity.CONTENT_TYPE_PDF.equalsIgnoreCase(attachment.content_type)) { attachment_image.setImageResource(R.drawable.attachment_pdf); } else if (AttachmentViewerActivity.CONTENT_TYPE_VIDEO_MP4 .equalsIgnoreCase(attachment.content_type)) { attachment_image.setImageResource(R.drawable.attachment_video); } else { attachment_image.setImageResource(R.drawable.attachment_unknown); L.d("attachment.content_type not known: " + attachment.content_type); } TextView attachment_text = (TextView) v.findViewById(R.id.attachment_text); attachment_text.setText(attachment.name); v.setOnClickListener(new SafeViewOnClickListener() { @Override public void safeOnClick(View v) { String downloadUrlHash = mMessagingPlugin .attachmentDownloadUrlHash(attachment.download_url); File attachmentsDir; try { attachmentsDir = mMessagingPlugin.attachmentsDir(mCurrentMessage.getThreadKey(), null); } catch (IOException e) { L.d("Unable to create attachment directory", e); UIUtils.showAlertDialog(ServiceMessageDetailActivity.this, "", R.string.unable_to_read_write_sd_card); return; } boolean attachmentAvailable = mMessagingPlugin.attachmentExists(attachmentsDir, downloadUrlHash); if (!attachmentAvailable) { try { attachmentsDir = mMessagingPlugin.attachmentsDir(mCurrentMessage.getThreadKey(), mCurrentMessage.key); } catch (IOException e) { L.d("Unable to create attachment directory", e); UIUtils.showAlertDialog(ServiceMessageDetailActivity.this, "", R.string.unable_to_read_write_sd_card); return; } attachmentAvailable = mMessagingPlugin.attachmentExists(attachmentsDir, downloadUrlHash); } if (!mService.getNetworkConnectivityManager().isConnected() && !attachmentAvailable) { AlertDialog.Builder builder = new AlertDialog.Builder( ServiceMessageDetailActivity.this); builder.setMessage(R.string.no_internet_connection_try_again); builder.setPositiveButton(R.string.rogerthat, null); AlertDialog dialog = builder.create(); dialog.show(); return; } if (IOUtils.shouldCheckExternalStorageAvailable()) { String state = Environment.getExternalStorageState(); if (Environment.MEDIA_MOUNTED.equals(state)) { // Its all oke } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) { if (!attachmentAvailable) { L.d("Unable to write to sd-card"); UIUtils.showAlertDialog(ServiceMessageDetailActivity.this, "", R.string.unable_to_read_write_sd_card); return; } } else { L.d("Unable to read or write to sd-card"); UIUtils.showAlertDialog(ServiceMessageDetailActivity.this, "", R.string.unable_to_read_write_sd_card); return; } } L.d("attachment.content_type: " + attachment.content_type); L.d("attachment.download_url: " + attachment.download_url); L.d("attachment.name: " + attachment.name); L.d("attachment.size: " + attachment.size); if (AttachmentViewerActivity.supportsContentType(attachment.content_type)) { Intent i = new Intent(ServiceMessageDetailActivity.this, AttachmentViewerActivity.class); i.putExtra("thread_key", mCurrentMessage.getThreadKey()); i.putExtra("message", mCurrentMessage.key); i.putExtra("content_type", attachment.content_type); i.putExtra("download_url", attachment.download_url); i.putExtra("name", attachment.name); i.putExtra("download_url_hash", downloadUrlHash); startActivity(i); } else { AlertDialog.Builder builder = new AlertDialog.Builder( ServiceMessageDetailActivity.this); builder.setMessage(getString(R.string.attachment_can_not_be_displayed_in_your_version, getString(R.string.app_name))); builder.setPositiveButton(R.string.rogerthat, null); AlertDialog dialog = builder.create(); dialog.show(); } } }); attachmentLayout.addView(v); } } else { attachmentLayout.setVisibility(View.GONE); } LinearLayout widgetLayout = (LinearLayout) findViewById(R.id.widget_layout); if (mCurrentMessage.form == null) { widgetLayout.setVisibility(View.GONE); } else { widgetLayout.setVisibility(View.VISIBLE); widgetLayout.setEnabled(canEdit); displayWidget(widgetLayout, br); } // Add buttons TableLayout tableLayout = (TableLayout) findViewById(R.id.buttons); tableLayout.removeAllViews(); for (final ButtonTO button : mCurrentMessage.buttons) { addButton(senderName, myEmail, mSomebodyAnswered, canEdit, tableLayout, button); } if (mCurrentMessage.form == null && (mCurrentMessage.flags & MessagingPlugin.FLAG_ALLOW_DISMISS) == MessagingPlugin.FLAG_ALLOW_DISMISS) { ButtonTO button = new ButtonTO(); button.caption = "Roger that!"; addButton(senderName, myEmail, mSomebodyAnswered, canEdit, tableLayout, button); } if (mCurrentMessage.broadcast_type != null) { L.d("Show broadcast spam control"); final RelativeLayout broadcastSpamControl = (RelativeLayout) findViewById(R.id.broadcast_spam_control); View broadcastSpamControlBorder = findViewById(R.id.broadcast_spam_control_border); final View broadcastSpamControlDivider = findViewById(R.id.broadcast_spam_control_divider); final LinearLayout broadcastSpamControlTextContainer = (LinearLayout) findViewById( R.id.broadcast_spam_control_text_container); TextView broadcastSpamControlText = (TextView) findViewById(R.id.broadcast_spam_control_text); final LinearLayout broadcastSpamControlSettingsContainer = (LinearLayout) findViewById( R.id.broadcast_spam_control_settings_container); TextView broadcastSpamControlSettingsText = (TextView) findViewById( R.id.broadcast_spam_control_settings_text); TextView broadcastSpamControlIcon = (TextView) findViewById(R.id.broadcast_spam_control_icon); broadcastSpamControlIcon.setTypeface(mFontAwesomeTypeFace); broadcastSpamControlIcon.setText(R.string.fa_bell); final FriendBroadcastInfo fbi = mFriendsPlugin.getFriendBroadcastFlowForMfr(mCurrentMessage.sender); if (fbi == null) { L.bug("BroadcastData was null for: " + mCurrentMessage.sender); collapseDetails(DETAIL_SECTIONS); return; } broadcastSpamControl.setVisibility(View.VISIBLE); broadcastSpamControlSettingsContainer.setOnClickListener(new SafeViewOnClickListener() { @Override public void safeOnClick(View v) { L.d("goto broadcast settings"); PressMenuIconRequestTO request = new PressMenuIconRequestTO(); request.coords = fbi.coords; request.static_flow_hash = fbi.staticFlowHash; request.hashed_tag = fbi.hashedTag; request.generation = fbi.generation; request.service = mCurrentMessage.sender; mContext = "MENU_" + UUID.randomUUID().toString(); request.context = mContext; request.timestamp = System.currentTimeMillis() / 1000; showTransmitting(null); Map<String, Object> userInput = new HashMap<String, Object>(); userInput.put("request", request.toJSONMap()); userInput.put("func", "com.mobicage.api.services.pressMenuItem"); MessageFlowRun mfr = new MessageFlowRun(); mfr.staticFlowHash = fbi.staticFlowHash; try { JsMfr.executeMfr(mfr, userInput, mService, true); } catch (EmptyStaticFlowException ex) { completeTransmit(null); AlertDialog.Builder builder = new AlertDialog.Builder(ServiceMessageDetailActivity.this); builder.setMessage(ex.getMessage()); builder.setPositiveButton(R.string.rogerthat, null); AlertDialog dialog = builder.create(); dialog.show(); return; } } }); UIUtils.showHint(this, mService, HINT_BROADCAST, R.string.hint_broadcast, mCurrentMessage.broadcast_type, mFriendsPlugin.getName(mCurrentMessage.sender)); broadcastSpamControlText .setText(getString(R.string.broadcast_subscribed_to, mCurrentMessage.broadcast_type)); broadcastSpamControlSettingsText.setText(fbi.label); int ligthAlpha = 180; int darkAlpha = 70; int alpha = ligthAlpha; if (br != null && br.scheme == ColorScheme.dark) { broadcastSpamControlIcon.setTextColor(getResources().getColor(android.R.color.black)); broadcastSpamControlBorder.setBackgroundColor(darkSchemeTextColor); broadcastSpamControlDivider.setBackgroundColor(darkSchemeTextColor); activity.setBackgroundColor(darkSchemeTextColor); broadcastSpamControlText.setTextColor(lightSchemeTextColor); broadcastSpamControlSettingsText.setTextColor(lightSchemeTextColor); int alpacolor = Color.argb(darkAlpha, Color.red(lightSchemeTextColor), Color.green(lightSchemeTextColor), Color.blue(lightSchemeTextColor)); broadcastSpamControl.setBackgroundColor(alpacolor); alpha = darkAlpha; } else { broadcastSpamControlIcon.setTextColor(getResources().getColor(android.R.color.white)); broadcastSpamControlBorder.setBackgroundColor(lightSchemeTextColor); broadcastSpamControlDivider.setBackgroundColor(lightSchemeTextColor); activity.setBackgroundColor(lightSchemeTextColor); broadcastSpamControlText.setTextColor(darkSchemeTextColor); broadcastSpamControlSettingsText.setTextColor(darkSchemeTextColor); int alpacolor = Color.argb(darkAlpha, Color.red(darkSchemeTextColor), Color.green(darkSchemeTextColor), Color.blue(darkSchemeTextColor)); broadcastSpamControl.setBackgroundColor(alpacolor); } if (br != null && br.color != null) { int alphaColor = Color.argb(alpha, Color.red(br.color), Color.green(br.color), Color.blue(br.color)); broadcastSpamControl.setBackgroundColor(alphaColor); } mService.postOnUIHandler(new SafeRunnable() { @Override protected void safeRun() throws Exception { int maxHeight = broadcastSpamControl.getHeight(); broadcastSpamControlDivider.getLayoutParams().height = maxHeight; broadcastSpamControlDivider.requestLayout(); broadcastSpamControlSettingsContainer.getLayoutParams().height = maxHeight; broadcastSpamControlSettingsContainer.requestLayout(); broadcastSpamControlTextContainer.getLayoutParams().height = maxHeight; broadcastSpamControlTextContainer.requestLayout(); int broadcastSpamControlWidth = broadcastSpamControl.getWidth(); android.view.ViewGroup.LayoutParams lp = broadcastSpamControlSettingsContainer .getLayoutParams(); lp.width = broadcastSpamControlWidth / 4; broadcastSpamControlSettingsContainer.setLayoutParams(lp); } }); } if (!isUpdate) collapseDetails(DETAIL_SECTIONS); } private void displayWidget(LinearLayout widgetLayout, BrandingResult br) { final String type = (String) mCurrentMessage.form.get("type"); widgetLayout.removeAllViews(); final Widget widget = (Widget) getLayoutInflater().inflate(Widget.RESOURCES.get(type), null, false); if (br != null) { widget.setColorScheme(br.scheme); } widget.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT)); widget.setEnabled(widgetLayout.isEnabled()); widget.loadMessage(mCurrentMessage, this, widgetLayout); if (!widgetLayout.isEnabled()) { for (int i = 0; i < widget.getChildCount(); i++) { View v = widget.getChildAt(i); v.setEnabled(false); } } widgetLayout.addView(widget); } private Comparator<MemberStatusTO> getMemberstatusComparator() { return new Comparator<MemberStatusTO>() { @Override public int compare(MemberStatusTO ms1, MemberStatusTO ms2) { if (ms1.status == ms2.status) return ms1.member.compareTo(ms2.member); if ((ms1.status & MessagingPlugin.STATUS_ACKED) == MessagingPlugin.STATUS_ACKED) return -1; if ((ms1.status & MessagingPlugin.STATUS_RECEIVED) == MessagingPlugin.STATUS_RECEIVED) { if ((ms2.status & MessagingPlugin.STATUS_ACKED) == MessagingPlugin.STATUS_ACKED) { return 1; } return -1; } return 1; } }; } private long getExpectNext(long uiFlags) { if ((uiFlags & MessagingPlugin.UI_FLAG_EXPECT_NEXT_WAIT_5) == MessagingPlugin.UI_FLAG_EXPECT_NEXT_WAIT_5) return 10; return 0; } private long getExpectNext(final ButtonTO button) { if (button.id == null) { return getExpectNext(mCurrentMessage.dismiss_button_ui_flags); } else { return getExpectNext(button.ui_flags); } } private void jumpToServiceHomeScreen(final ButtonTO button, final Bundle extras) { // detect if we come from message history if (getIntent().getStringExtra(MessagingPlugin.MEMBER_FILTER) == null && (button == null || getExpectNext(button) == 0) && mFriendsPlugin.getStore() .getFriendType(mCurrentMessage.sender) == FriendsPlugin.FRIEND_TYPE_SERVICE && mFriendsPlugin.getStore().getExistence(mCurrentMessage.sender) == Friend.ACTIVE) { L.d("Jumping to service home screen"); // Message flow ended. Intent intent = new Intent(ServiceMessageDetailActivity.this, ServiceActionMenuActivity.class); intent.putExtra(ServiceActionMenuActivity.SERVICE_EMAIL, mCurrentMessage.sender); if (extras != null) intent.putExtras(extras); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent); overridePendingTransition(R.anim.slide_in_left, R.anim.slide_out_right); quit(); } } public void excecutePositiveButtonClick() { for (final ButtonTO button : mCurrentMessage.buttons) { if (Message.POSITIVE.equals(button.id)) { final LinearLayout container = (LinearLayout) getLayoutInflater() .inflate(R.layout.message_button_detail, null); container.setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL); executeButtonClick(button, container, true); break; } } } private boolean askPermissionIfNeeded(final ButtonTO button, final SafeRunnable onGranted, final SafeRunnable onDenied) { if (SystemUtils.isFlagEnabled(button.ui_flags, MessagingPlugin.UI_FLAG_AUTHORIZE_LOCATION)) { return askPermissionIfNeeded(Manifest.permission.ACCESS_FINE_LOCATION, PERMISSION_REQUEST_UI_FLAG_LOCATION, onGranted, onDenied); } return false; } private void executeButtonClick(final ButtonTO button, final LinearLayout container, final boolean shouldAskConfirmation) { executeButtonClick(button, container, shouldAskConfirmation, false); } private void executeButtonClick(final ButtonTO button, final LinearLayout container, final boolean shouldAskConfirmation, final boolean alreadyAskedPermission) { boolean askedPermission = !alreadyAskedPermission && askPermissionIfNeeded(button, new SafeRunnable() { @Override protected void safeRun() throws Exception { executeButtonClick(button, container, shouldAskConfirmation, true); } }, null); if (askedPermission) { return; } Map<String, String> actionInfo = mMessagingPlugin.getButtonActionInfo(button); final String buttonAction = actionInfo.get("androidAction"); final String buttonUrl = actionInfo.get("androidUrl"); if (shouldAskConfirmation && Message.MC_CONFIRM_PREFIX.equals(buttonAction)) { askConfirmation(button, buttonUrl, container); } else { if (!buttonPressed(button, container)) return; if (!mTransfering) jumpToServiceHomeScreen(button, null); if (buttonAction != null && !Message.MC_CONFIRM_PREFIX.equals(buttonAction)) { final Intent intent = new Intent(buttonAction, Uri.parse(buttonUrl)); startActivity(intent); } } } private void askConfirmation(final ButtonTO button, final String text, final LinearLayout container) { AlertDialog.Builder builder = new AlertDialog.Builder(ServiceMessageDetailActivity.this); builder.setTitle(R.string.message_confirm); builder.setMessage(text); builder.setPositiveButton(R.string.yes, new SafeDialogInterfaceOnClickListener() { @Override public void safeOnClick(DialogInterface dialog, int which) { T.UI(); dialog.dismiss(); executeButtonClick(button, container, false); } }); builder.setNegativeButton(R.string.no, new SafeDialogInterfaceOnClickListener() { @Override public void safeOnClick(DialogInterface dialog, int which) { T.UI(); dialog.dismiss(); } }); builder.create().show(); } private boolean buttonPressed(final ButtonTO button, final LinearLayout container) { long expectNext = getExpectNext(button); boolean submitted = true; if (mCurrentMessage.form == null) { ackMessage(button, expectNext, container); } else { submitted = submitForm(button); } if (!mTransfering && submitted) { animateAfterAck(expectNext); } return submitted; } private void ackMessage(final ButtonTO button, final long expectNext, final LinearLayout container) { SafeRunnable updateDoneHandler = null; if (expectNext == 0) { updateDoneHandler = new SafeRunnable() { @Override protected void safeRun() throws Exception { T.dontCare(); if (T.getThreadType() == T.UI) { dismissTransferingDialog(); } else if (mService != null) { mService.postOnUIHandler(this); } } }; } mMessagingPlugin.ackMessage(mCurrentMessage, button.id, null, updateDoneHandler, ServiceMessageDetailActivity.this, container); } private boolean submitForm(final ButtonTO button) { LinearLayout widgetLayout = (LinearLayout) findViewById(R.id.widget_layout); Widget widget = (Widget) widgetLayout.getChildAt(0); if (Message.POSITIVE.equals(button.id)) { widget.putValue(); } if (!widget.proceedWithSubmit(button.id)) { return false; } if (Message.POSITIVE.equals(button.id)) { try { final IJSONable formResult = widget.getFormResult(); if (formResult != null) { String validationError = mMessagingPlugin.validateFormResult(mCurrentMessage, formResult); if (validationError != null) { AlertDialog.Builder builder = new AlertDialog.Builder(ServiceMessageDetailActivity.this); builder.setTitle(R.string.validation_failed); builder.setMessage(validationError); builder.setPositiveButton(R.string.ok, new SafeDialogInterfaceOnClickListener() { @Override public void safeOnClick(DialogInterface dialog, int which) { T.UI(); dialog.dismiss(); } }); builder.create().show(); return false; } } } catch (Exception e) { L.bug(e); } } try { widget.submit(button.id, mService.currentTimeMillis() / 1000); } catch (Exception e) { L.bug(e); dismissTransferingDialog(); return false; } mMessagingPlugin.formSubmitted(mCurrentMessage, button.id); return true; } private void addButton(final String senderName, String myEmail, boolean somebodyAnswered, boolean canEdit, TableLayout tableLayout, final ButtonTO button) { TableRow row = new TableRow(this); tableLayout.addView(row); row.setLayoutParams(new TableLayout.LayoutParams(TableLayout.LayoutParams.WRAP_CONTENT, TableLayout.LayoutParams.WRAP_CONTENT, 1)); // XXX: inconsistent margin between 2 rows final Button buttonView = new Button(this); buttonView.setMinWidth(UIUtils.convertDipToPixels(this, 100)); buttonView.setText(button.caption); buttonView.setTextColor(getResources().getColor(android.R.color.primary_text_dark)); if (somebodyAnswered) buttonView.setGravity(Gravity.RIGHT | Gravity.CENTER_VERTICAL); else { buttonView.setWidth(mDisplayWidth - UIUtils.convertDipToPixels(this, 12)); } buttonView.setTextSize(19); row.addView(buttonView); final LinearLayout container = (LinearLayout) getLayoutInflater().inflate(R.layout.message_button_detail, null); container.setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL); boolean buttonSelectedByMe = false; for (MemberStatusTO status : mCurrentMessage.members) { if ((status.status & MessagingPlugin.STATUS_ACKED) == MessagingPlugin.STATUS_ACKED && ((button.id == null && status.button_id == null) || (button.id != null && button.id.equals(status.button_id)))) { getLayoutInflater().inflate(R.layout.avatar, container); ImageView avatar = (ImageView) container.getChildAt(container.getChildCount() - 1); setAvatar(avatar, status.member); if (status.member.equals(myEmail)) buttonSelectedByMe = true; int dp42 = UIUtils.convertDipToPixels(this, 42); int dp2 = UIUtils.convertDipToPixels(this, 1); LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) avatar.getLayoutParams(); lp.setMargins(0, dp2, 0, 0); lp.width = dp42; lp.height = dp42; } } row.addView(container); boolean hasAction = button.action != null && !"".equals(button.action); final boolean buttonIsEnabled = canEdit && (mCurrentMessage.form != null || !buttonSelectedByMe || hasAction); buttonView.setEnabled(buttonIsEnabled); int color; if (button.id == null || mCurrentMessage.form != null && Message.POSITIVE.equals(button.id)) { color = buttonIsEnabled ? Message.GREEN_BUTTON_COLOR : Message.GREENGRAY_BUTTON_COLOR; } else if (mCurrentMessage.form != null && Message.NEGATIVE.equals(button.id)) { color = buttonIsEnabled ? Message.RED_BUTTON_COLOR : Message.REDGRAY_BUTTON_COLOR; } else { color = buttonIsEnabled ? Message.BLUE_BUTTON_COLOR : Message.BLUEGRAY_BUTTON_COLOR; } buttonView.getBackground().setColorFilter(color, PorterDuff.Mode.MULTIPLY); buttonView.setOnClickListener(new SafeViewOnClickListener() { @Override public void safeOnClick(View v) { T.UI(); executeButtonClick(button, container, true); } }); final HorizontalScrollView scroller = (HorizontalScrollView) findViewById(R.id.button_scroller); scroller.post(new SafeRunnable() { @Override protected void safeRun() throws Exception { scroller.fullScroll(ScrollView.FOCUS_RIGHT); } }); } @Override protected boolean showFABMenu() { return false; } @Override public boolean onCreateOptionsMenu(Menu menu) { T.UI(); super.onCreateOptionsMenu(menu); MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.message_menu, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { T.UI(); switch (item.getItemId()) { case R.id.show_details: expandDetails(); return true; } return super.onOptionsItemSelected(item); } private void setAvatar(ImageView imageView, final String email) { if (FriendsPlugin.SYSTEM_FRIEND.equals(email)) { imageView.setImageResource(R.drawable.ic_dashboard); } else { imageView.setImageBitmap(mFriendsPlugin.getAvatarBitmap(email, true)); final SafeViewOnClickListener listener = getFriendDetailOnClickListener(email); if (listener != null) imageView.setOnClickListener(listener); } } private SafeViewOnClickListener getFriendDetailOnClickListener(final String email) { if (FriendsPlugin.SYSTEM_FRIEND.equals(email)) return null; final int contactType = mFriendsPlugin.getContactType(email); return new SafeViewOnClickListener() { @Override public void safeOnClick(View v) { T.UI(); if ((contactType & FriendsPlugin.FRIEND) == FriendsPlugin.FRIEND) { mFriendsPlugin.launchDetailActivity(ServiceMessageDetailActivity.this, email); } else { if ((contactType & FriendsPlugin.NON_FRIEND) == FriendsPlugin.NON_FRIEND) { new AlertDialog.Builder(ServiceMessageDetailActivity.this) .setMessage(getString(R.string.invite_as_friend, new Object[] { email })) .setPositiveButton(R.string.yes, new SafeDialogInterfaceOnClickListener() { @Override public void safeOnClick(DialogInterface dialog, int which) { mFriendsPlugin.inviteFriend(email, null, null, true); } }).setNegativeButton(R.string.no, null).create().show(); } } } }; } private void setStatusIcon(ImageView imageView, final MemberStatusTO ms) { int resource; if ((ms.status & MessagingPlugin.STATUS_ACKED) == MessagingPlugin.STATUS_ACKED) resource = R.drawable.status_blue; else if ((ms.status & MessagingPlugin.STATUS_RECEIVED) == MessagingPlugin.STATUS_RECEIVED) resource = R.drawable.status_green; else resource = R.drawable.status_yellow; imageView.setImageResource(resource); } private RelativeLayout createParticipantView(MemberStatusTO ms) { RelativeLayout rl = new RelativeLayout(this); int rlW = UIUtils.convertDipToPixels(this, 55); rl.setLayoutParams(new RelativeLayout.LayoutParams(rlW, rlW)); getLayoutInflater().inflate(R.layout.avatar, rl); ImageView avatar = (ImageView) rl.getChildAt(rl.getChildCount() - 1); RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(avatar.getLayoutParams()); params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE); params.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE); avatar.setLayoutParams(params); setAvatar(avatar, ms.member); ImageView statusView = new ImageView(this); int w = UIUtils.convertDipToPixels(this, 12); RelativeLayout.LayoutParams iconParams = new RelativeLayout.LayoutParams(w, w); iconParams.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE); iconParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, RelativeLayout.TRUE); statusView.setLayoutParams(iconParams); statusView.setAdjustViewBounds(true); statusView.setScaleType(ScaleType.CENTER_CROP); setStatusIcon(statusView, ms); rl.addView(statusView); return rl; } protected void updateView(boolean isUpdate) { T.UI(); if (mMustQuit) { if (!isFinishing()) finish(); return; } if (isUpdate) mCurrentMessage = mStore.getFullMessageByKey(mCurrentMessage.key); boolean isLocked = (mCurrentMessage.flags & MessagingPlugin.FLAG_LOCKED) == MessagingPlugin.FLAG_LOCKED; boolean isRinging = mCurrentMessage.alert_flags >= AlertManager.ALERT_FLAG_RING_5 && !mMessagingPlugin.isMessageAckedByMe(mCurrentMessage); if (isLocked) { mStatusImage.setImageResource(R.drawable.status_locked); mStatusImage.setVisibility(View.VISIBLE); } else if (isRinging) { mStatusImage.setImageResource(R.drawable.status_ringing); mStatusImage.setVisibility(View.VISIBLE); } else { mStatusImage.setVisibility(View.GONE); } updateMessageDetail(isUpdate); if (mCurrentMessage.dirty) { mMessagingPlugin.cleanDirtyFlag(mCurrentMessage.key); if ((mCurrentMessage.flags & MessagingPlugin.FLAG_SENT_BY_JSMFR) == 0) { mMessagingPlugin.markMessagesAsRead(mCurrentMessage.getThreadKey(), new String[] { mCurrentMessage.key }); } mCurrentMessage.dirty = false; } } protected void quit() { mMustQuit = true; } protected SafeBroadcastReceiver getBroadcastReceiver() { return new SafeBroadcastReceiver() { @Override public String[] onSafeReceive(Context context, Intent intent) { T.UI(); String action = intent.getAction(); if (MessagingPlugin.MESSAGE_MEMBER_STATUS_UPDATE_RECEIVED_INTENT.equals(action) || MessagingPlugin.MESSAGE_LOCKED_INTENT.equals(action) || MessagingPlugin.MESSAGE_PROCESSED_INTENT.equals(action)) { if (mCurrentMessage != null && intent.hasExtra("message") && intent.getStringExtra("message").equals(mCurrentMessage.key)) { updateView(true); return UPDATE_VIEW_INTENT_ACTIONS; } } if (FriendsPlugin.FRIEND_UPDATE_INTENT.equals(action) || IdentityStore.IDENTITY_CHANGED_INTENT.equals(action) || FriendsPlugin.FRIENDS_LIST_REFRESHED.equals(action) || FriendsPlugin.FRIEND_AVATAR_CHANGED_INTENT.equals(action)) { updateView(true); return UPDATE_VIEW_INTENT_ACTIONS; } if (MessagingPlugin.NEW_MESSAGE_RECEIVED_INTENT.equals(action)) { String trasferFailedMessage = "DASHBOARD_" + mCurrentMessage.key; if (mTransfering && trasferFailedMessage.equals(intent.getStringExtra("context"))) { final Intent i = new Intent(context, ServiceMessageDetailActivity.class); i.putExtra("message", intent.getStringExtra("message")); startActivity(i); overridePendingTransition(R.anim.slide_in_bottom, R.anim.slide_out_up); dismissTransferingDialog(); finish(); return new String[] { action }; } if (mContext != null && mContext.equals(intent.getStringExtra("context"))) { L.d("Showing broadcast flow"); } else { if (mExpectNextTimer == null) // Not interested in NEW_MESSAGE_RECEIVED_INTENTS at this moment return new String[] { action }; // We are expecting a reply on this thread! String pKey = mCurrentMessage.getThreadKey(); if (!pKey.equals(intent.getStringExtra("parent"))) { L.d("New message is from another thread"); return null; // New message is from another thread } // We received the reply! mExpectNextTimer.cancel(); mExpectNextTimer = null; } final Intent i = new Intent(context, ServiceMessageDetailActivity.class); i.putExtra("message", intent.getStringExtra("message")); startActivity(i); overridePendingTransition(R.anim.slide_in_bottom, R.anim.slide_out_up); dismissTransferingDialog(); finish(); return new String[] { action }; } if (MessagingPlugin.MESSAGE_JSMFR_ERROR.equals(action)) { if (mExpectNextTimer == null) // Not interested in MESSAGE_JSMFR_ERROR at this moment return new String[] { action }; String threadKey = mCurrentMessage.getThreadKey(); if (!threadKey.equals(intent.getStringExtra("parent_message_key")) && !threadKey.equals(intent.getStringExtra("message_key"))) { return null; // Intent is for another thread } mExpectNextTimer.cancel(); mExpectNextTimer = null; dismissTransferingDialog(); Bundle extras = new Bundle(); extras.putBoolean(ServiceActionMenuActivity.SHOW_ERROR_POPUP, true); jumpToServiceHomeScreen(null, extras); updateView(false); return new String[] { action }; } if (MessagingPlugin.MESSAGE_FLOW_ENDED_INTENT.equals(action)) { if (mExpectNextTimer == null) // Not interested in MESSAGE_JSMFR_ERROR at this moment return new String[] { action }; String threadKey = mCurrentMessage.getThreadKey(); if (!threadKey.equals(intent.getStringExtra("parent_message_key"))) { return null; // Intent is for another thread } if (intent.getBooleanExtra("wait_for_followup", false)) { return null; // We must keep on waiting } mExpectNextTimer.cancel(); mExpectNextTimer = null; dismissTransferingDialog(); jumpToServiceHomeScreen(null, null); return new String[] { action }; } if (BrandingMgr.GENERIC_BRANDING_AVAILABLE_INTENT.equals(intent.getAction())) { if (intent.getStringExtra(BrandingMgr.BRANDING_KEY).equals(mCurrentMessage.branding)) { updateView(false); return new String[] { action }; } } if (MessagingPlugin.MESSAGE_SUBMIT_PHOTO_UPLOAD.equals(action)) { L.d("MessagingPlugin.MESSAGE_SUBMIT_PHOTO_UPLOAD.equals(action)"); if (intent.hasExtra("submitToJSMFR")) messageSubmitToJsMfr(intent, action); String messageKey = intent.getStringExtra("message_key"); if (mCurrentMessage.key.equals(messageKey)) { transferComplete(); } return null; } return null; } }; } protected IntentFilter getIntentFilter() { final IntentFilter filter = new IntentFilter(MessagingPlugin.MESSAGE_MEMBER_STATUS_UPDATE_RECEIVED_INTENT); filter.addAction(MessagingPlugin.MESSAGE_LOCKED_INTENT); filter.addAction(MessagingPlugin.MESSAGE_PROCESSED_INTENT); filter.addAction(MessagingPlugin.NEW_MESSAGE_RECEIVED_INTENT); filter.addAction(MessagingPlugin.MESSAGE_JSMFR_ERROR); filter.addAction(MessagingPlugin.MESSAGE_FLOW_ENDED_INTENT); filter.addAction(FriendsPlugin.FRIEND_AVATAR_CHANGED_INTENT); filter.addAction(FriendsPlugin.FRIEND_UPDATE_INTENT); filter.addAction(IdentityStore.IDENTITY_CHANGED_INTENT); filter.addAction(FriendsPlugin.FRIENDS_LIST_REFRESHED); filter.addAction(BrandingMgr.GENERIC_BRANDING_AVAILABLE_INTENT); filter.addAction(MessagingPlugin.MESSAGE_SUBMIT_PHOTO_UPLOAD); return filter; } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); mDisplayWidth = UIUtils.getDisplayWidth(this); if (!mSomebodyAnswered) { TableLayout tableLayout = (TableLayout) findViewById(R.id.buttons); for (int i = 0; i < tableLayout.getChildCount(); i++) { TableRow row = (TableRow) tableLayout.getChildAt(i); Button button = (Button) row.getChildAt(0); button.setWidth(mDisplayWidth - UIUtils.convertDipToPixels(this, 12)); } } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (mCurrentMessage.form != null) { LinearLayout widgetLayout = (LinearLayout) findViewById(R.id.widget_layout); Widget widget = (Widget) widgetLayout.getChildAt(0); widget.onActivityResult(requestCode, resultCode, data); } } protected void messageSubmitToJsMfr(Intent intent, String function) { T.UI(); MessagingPlugin plugin = mService.getPlugin(MessagingPlugin.class); if (MainActivity.ACTION_NOTIFICATION_PHOTO_UPLOAD_DONE.equals(function)) { JSONObject transfers = plugin.jsmfrTransferCompletedGetNext(); while (transfers != null) { String threadKey; try { threadKey = (String) transfers.get("threadKey"); String requestJSON = (String) transfers.get("submitToJSMFR"); @SuppressWarnings("unchecked") Map<String, Object> request = (Map<String, Object>) JSONValue.parse(requestJSON); plugin.answerJsMfrMessage(threadKey, request, function, ServiceMessageDetailActivity.this, (LinearLayout) findViewById(R.id.widget_layout)); transfers = plugin.jsmfrTransferCompletedGetNext(); } catch (Exception e) { L.e(e); e.printStackTrace(); } } } else { String threadKey = intent.getStringExtra("threadKey"); String requestJSON = intent.getStringExtra("submitToJSMFR"); @SuppressWarnings("unchecked") Map<String, Object> request = (Map<String, Object>) JSONValue.parse(requestJSON); plugin.answerJsMfrMessage(threadKey, request, function, ServiceMessageDetailActivity.this, (LinearLayout) findViewById(R.id.widget_layout)); } } private void animateAfterAck(long expectNext) { mDialog = ProgressDialog.show(ServiceMessageDetailActivity.this, "", getString(R.string.transmitting), true, expectNext != 0); mDialog.show(); if (expectNext == 0 || (mCurrentMessage.flags & MessagingPlugin.FLAG_SENT_BY_JSMFR) == 0 && !checkConnectivity()) { dismissTransferingDialog(); quit(); } else { mExpectNextTimer = new Timer("expect_next"); mExpectNextTimer.schedule(new TimerTask() { @Override public void run() { if (mService != null) { mService.postOnUIHandler(new SafeRunnable() { @Override public void safeRun() { T.UI(); dismissTransferingDialog(); finish(); } }); } } }, 1000 * expectNext); } } @Override protected boolean isRouteDisplayed() { return false; } }