diff options
Diffstat (limited to 'src/main/java/eu')
27 files changed, 762 insertions, 93 deletions
diff --git a/src/main/java/eu/siacs/conversations/Config.java b/src/main/java/eu/siacs/conversations/Config.java index e39cd6549..3979135c6 100644 --- a/src/main/java/eu/siacs/conversations/Config.java +++ b/src/main/java/eu/siacs/conversations/Config.java @@ -36,45 +36,49 @@ public final class Config { public static final String LOGTAG = "conversations"; - - public static final String DOMAIN_LOCK = null; //only allow account creation for this domain + public static final String DOMAIN_LOCK = "pix-art.de"; //only allow account creation for this domain public static final String CONFERENCE_DOMAIN_LOCK = null; //only allow conference creation for this domain public static final boolean LOCK_DOMAINS_IN_CONVERSATIONS = false; //only add contacts and conferences for own domains - public static final boolean LOCK_SETTINGS = false; //set to true to disallow account and settings editing + public static final boolean SINGLE_ACCOUNT = true; //set to true to allow only one account public static final boolean DISALLOW_REGISTRATION_IN_UI = false; //hide the register checkbox public static final boolean ALLOW_NON_TLS_CONNECTIONS = false; //very dangerous. you should have a good reason to set this to true + public static final boolean FORCE_ORBOT = false; // always use TOR public static final boolean HIDE_MESSAGE_TEXT_IN_NOTIFICATION = false; + public static final boolean SHOW_CONNECTED_ACCOUNTS = false; //show number of connected accounts in foreground notification public static final boolean ALWAYS_NOTIFY_BY_DEFAULT = false; - public static final boolean LEGACY_NAMESPACE_HTTP_UPLOAD = false; + public static final boolean LEGACY_NAMESPACE_HTTP_UPLOAD = false; // true = 'eu:siacs:conversations:http:upload' false = 'urn:xmpp:http:upload' public static final int PING_MAX_INTERVAL = 300; public static final int PING_MIN_INTERVAL = 30; public static final int PING_TIMEOUT = 15; public static final int SOCKET_TIMEOUT = 15; - public static final int CONNECT_TIMEOUT = 90; + public static final int CONNECT_TIMEOUT = 60; public static final int CONNECT_DISCO_TIMEOUT = 20; + public static final int CARBON_GRACE_PERIOD = 90; public static final int MINI_GRACE_PERIOD = 750; public static final boolean CLOSE_TCP_WHEN_SWITCHING_TO_BACKGROUND = false; - public static final int AVATAR_SIZE = 192; - public static final Bitmap.CompressFormat AVATAR_FORMAT = Bitmap.CompressFormat.WEBP; + public static final int AVATAR_SIZE = 640; + public static final Bitmap.CompressFormat AVATAR_FORMAT = Bitmap.CompressFormat.PNG; public static final int IMAGE_SIZE = 1920; public static final Bitmap.CompressFormat IMAGE_FORMAT = Bitmap.CompressFormat.JPEG; public static final int IMAGE_QUALITY = 75; - public static final int IMAGE_MAX_SIZE = 524288; //512KiB + public static final int IMAGE_MAX_SIZE = 524288; //512 KiB + + public static final int FILE_MAX_SIZE = 1048576; //1 MiB public static final int MESSAGE_MERGE_WINDOW = 20; - public static final int PAGE_SIZE = 50; + public static final int PAGE_SIZE = 20; public static final int MAX_NUM_PAGES = 3; public static final int REFRESH_UI_INTERVAL = 500; @@ -102,7 +106,10 @@ public final class Config { public static final int MAM_MAX_MESSAGES = 500; public static final ChatState DEFAULT_CHATSTATE = ChatState.ACTIVE; - public static final int TYPING_TIMEOUT = 8; + public static final int TYPING_TIMEOUT = 5; + + public static final String UPDATE_URL = "http://xmpp.pix-art.de/Conversations/update/"; + public static final long UPDATE_CHECK_TIMER = 24 * 60 * 60; // in seconds public static final String ENABLED_CIPHERS[] = { "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", diff --git a/src/main/java/eu/siacs/conversations/entities/Conversation.java b/src/main/java/eu/siacs/conversations/entities/Conversation.java index a3ae906b5..2f086a34d 100644 --- a/src/main/java/eu/siacs/conversations/entities/Conversation.java +++ b/src/main/java/eu/siacs/conversations/entities/Conversation.java @@ -22,6 +22,7 @@ import java.util.Iterator; import java.util.List; import eu.siacs.conversations.Config; +import eu.siacs.conversations.R; import eu.siacs.conversations.crypto.axolotl.AxolotlService; import eu.siacs.conversations.xmpp.chatstate.ChatState; import eu.siacs.conversations.xmpp.jid.InvalidJidException; @@ -431,6 +432,19 @@ public class Conversation extends AbstractEntity implements Blockable { return this.getContact().getDisplayName(); } } + + public String getParticipants() { + if (getMode() == MODE_MULTI) { + String generatedName = getMucOptions().createNameFromParticipants(); + if (generatedName != null) { + return generatedName; + } else { + return null; + } + } else { + return null; + } + } public String getAccountUuid() { return this.accountUuid; diff --git a/src/main/java/eu/siacs/conversations/entities/MucOptions.java b/src/main/java/eu/siacs/conversations/entities/MucOptions.java index db27810fc..ac627aaae 100644 --- a/src/main/java/eu/siacs/conversations/entities/MucOptions.java +++ b/src/main/java/eu/siacs/conversations/entities/MucOptions.java @@ -404,7 +404,7 @@ public class MucOptions { } public String createNameFromParticipants() { - if (users.size() >= 2) { + if (users.size() >= 1) { List<String> names = new ArrayList<>(); for (User user : getUsers(5)) { Contact contact = user.getContact(); diff --git a/src/main/java/eu/siacs/conversations/entities/Transferable.java b/src/main/java/eu/siacs/conversations/entities/Transferable.java index 5a47c4512..1ce4d8ccf 100644 --- a/src/main/java/eu/siacs/conversations/entities/Transferable.java +++ b/src/main/java/eu/siacs/conversations/entities/Transferable.java @@ -4,28 +4,75 @@ import java.util.Arrays; import java.util.List; public interface Transferable { + List<String> VALID_IMAGE_EXTENSIONS = Arrays.asList( + "webp", + "jpeg", + "jpg", + "png", + "jpe", + "gif", + "tif" + ); + List<String> VALID_CRYPTO_EXTENSIONS = Arrays.asList( + "pgp", + "gpg", + "otr" + ); + List<String> WELL_KNOWN_EXTENSIONS = Arrays.asList( + //documents + "pdf", + "doc", + "docx", + "txt", + //audio + "m4a", + "m4b", + "mp3", + "mp2", + "wav", + "aac", + "aif", + "aiff", + "aifc", + "mid", + "midi", + "3gpp", + //video + "avi", + "mp4", + "mpeg", + "mpg", + "mpe", + "mov", + "3gp", + //applications + "apk", + //contact + "vcf", + //calendar + "ics", + //compressed + "zip", + "rar" + ); - List<String> VALID_IMAGE_EXTENSIONS = Arrays.asList("webp", "jpeg", "jpg", "png", "jpe"); - List<String> VALID_CRYPTO_EXTENSIONS = Arrays.asList("pgp", "gpg", "otr"); - List<String> WELL_KNOWN_EXTENSIONS = Arrays.asList("pdf","m4a","mp4","3gp","aac","amr","mp3"); + int STATUS_UNKNOWN = 0x200; + int STATUS_CHECKING = 0x201; + int STATUS_FAILED = 0x202; + int STATUS_OFFER = 0x203; + int STATUS_DOWNLOADING = 0x204; + int STATUS_DELETED = 0x205; + int STATUS_OFFER_CHECK_FILESIZE = 0x206; + int STATUS_UPLOADING = 0x207; - int STATUS_UNKNOWN = 0x200; - int STATUS_CHECKING = 0x201; - int STATUS_FAILED = 0x202; - int STATUS_OFFER = 0x203; - int STATUS_DOWNLOADING = 0x204; - int STATUS_DELETED = 0x205; - int STATUS_OFFER_CHECK_FILESIZE = 0x206; - int STATUS_UPLOADING = 0x207; + boolean start(); - boolean start(); + int getStatus(); - int getStatus(); + long getFileSize(); - long getFileSize(); + int getProgress(); - int getProgress(); - - void cancel(); + void cancel(); } diff --git a/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java b/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java index 05fa0b82e..f63b4d092 100644 --- a/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java @@ -42,7 +42,9 @@ public abstract class AbstractGenerator { "urn:xmpp:message-correct:0" }; private String mVersion = null; - protected final String IDENTITY_NAME = "Conversations"; + + private String mVersionOs = null; + protected final String IDENTITY_NAME = "Pix-Art Messenger"; protected final String IDENTITY_TYPE = "phone"; private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US); @@ -60,6 +62,14 @@ public abstract class AbstractGenerator { return this.mVersion; } + protected String getIdentityVersionOs() { + if (mVersionOs == null) { + this.mVersionOs = "Android/" + android.os.Build.MODEL + + "/" + android.os.Build.VERSION.RELEASE; + } + return this.mVersionOs; + } + public String getIdentityName() { return IDENTITY_NAME + " " + getIdentityVersion(); } diff --git a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java index b7911ef7d..d8a0572b6 100644 --- a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java @@ -57,6 +57,7 @@ public class IqGenerator extends AbstractGenerator { Element query = packet.query("jabber:iq:version"); query.addChild("name").setContent(IDENTITY_NAME); query.addChild("version").setContent(getIdentityVersion()); + query.addChild("os").setContent(getIdentityVersionOs()); return packet; } diff --git a/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java b/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java index e337509b5..df3740ff7 100644 --- a/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java +++ b/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java @@ -89,8 +89,12 @@ public class HttpUploadConnection implements Transferable { private void fail() { mHttpConnectionManager.finishUploadConnection(this); message.setTransferable(null); - mXmppConnectionService.markMessage(message, Message.STATUS_SEND_FAILED); - FileBackend.close(mFileInputStream); + if (!canceled && file.getExpectedSize()<=Config.FILE_MAX_SIZE){ + mXmppConnectionService.resendMessage(message, delayed); + } else { + mXmppConnectionService.markMessage(message, Message.STATUS_SEND_FAILED); + FileBackend.close(mFileInputStream); + } } public void init(Message message, boolean delay) { diff --git a/src/main/java/eu/siacs/conversations/services/AvatarService.java b/src/main/java/eu/siacs/conversations/services/AvatarService.java index 276be10d1..8f9b26ab4 100644 --- a/src/main/java/eu/siacs/conversations/services/AvatarService.java +++ b/src/main/java/eu/siacs/conversations/services/AvatarService.java @@ -45,12 +45,12 @@ public class AvatarService { if (avatar != null || cachedOnly) { return avatar; } - if (contact.getProfilePhoto() != null) { - avatar = mXmppConnectionService.getFileBackend().cropCenterSquare(Uri.parse(contact.getProfilePhoto()), size); - } if (avatar == null && contact.getAvatar() != null) { avatar = mXmppConnectionService.getFileBackend().getAvatar(contact.getAvatar(), size); } + if (avatar == null && contact.getProfilePhoto() != null) { + avatar = mXmppConnectionService.getFileBackend().cropCenterSquare(Uri.parse(contact.getProfilePhoto()), size); + } if (avatar == null) { avatar = get(contact.getDisplayName(), size, cachedOnly); } @@ -332,12 +332,22 @@ public class AvatarService { Contact contact = user.getContact(); if (contact != null) { Uri uri = null; - if (contact.getProfilePhoto() != null) { - uri = Uri.parse(contact.getProfilePhoto()); - } else if (contact.getAvatar() != null) { + if (contact.getAvatar() != null) { uri = mXmppConnectionService.getFileBackend().getAvatarUri( contact.getAvatar()); + } else if (contact.getProfilePhoto() != null) { + uri = Uri.parse(contact.getProfilePhoto()); + } + if (drawTile(canvas, uri, left, top, right, bottom)) { + return true; + } + } else if (user.getAvatar() != null) { + Uri uri = mXmppConnectionService.getFileBackend().getAvatarUri(user.getAvatar()); + if (drawTile(canvas, uri, left, top, right, bottom)) { + return true; } + } else if (user.getAvatar() != null) { + Uri uri = mXmppConnectionService.getFileBackend().getAvatarUri(user.getAvatar()); if (drawTile(canvas, uri, left, top, right, bottom)) { return true; } diff --git a/src/main/java/eu/siacs/conversations/services/CheckAppVersionService.java b/src/main/java/eu/siacs/conversations/services/CheckAppVersionService.java new file mode 100644 index 000000000..33faeaeca --- /dev/null +++ b/src/main/java/eu/siacs/conversations/services/CheckAppVersionService.java @@ -0,0 +1,43 @@ +package eu.siacs.conversations.services; + +import com.google.gson.JsonObject; + +import java.io.IOException; +import java.io.PrintWriter; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +public class CheckAppVersionService extends HttpServlet { + private static final long serialVersionUID = 1L; + + public CheckAppVersionService() { + super(); + } + + protected void doGet(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + doPost(request,response); + } + + protected void doPost(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + + PrintWriter out = response.getWriter(); + response.setContentType("text/html"); + + //send a JSON response with the app Version and file URI + JsonObject myObj = new JsonObject(); + myObj.addProperty("success", false); + myObj.addProperty("latestVersionCode", 2); + myObj.addProperty("latestVersion", "1.0.0"); + myObj.addProperty("changelog", ""); + myObj.addProperty("appURI", ""); + out.println(myObj.toString()); + out.close(); + + } + +} diff --git a/src/main/java/eu/siacs/conversations/services/NotificationService.java b/src/main/java/eu/siacs/conversations/services/NotificationService.java index cec9a3ef8..5d4927279 100644 --- a/src/main/java/eu/siacs/conversations/services/NotificationService.java +++ b/src/main/java/eu/siacs/conversations/services/NotificationService.java @@ -301,7 +301,7 @@ public class NotificationService { final ArrayList<Message> messages, final boolean notify) { try { final Bitmap bitmap = mXmppConnectionService.getFileBackend() - .getThumbnail(message, getPixel(288), false); + .getThumbnail(message, getPixel(200), false); final ArrayList<Message> tmp = new ArrayList<>(); for (final Message msg : messages) { if (msg.getType() == Message.TYPE_TEXT @@ -541,9 +541,6 @@ public class NotificationService { cancelIcon = R.drawable.ic_action_cancel; } mBuilder.setSmallIcon(R.drawable.ic_link_white_24dp); - mBuilder.addAction(cancelIcon, - mXmppConnectionService.getString(R.string.disable_foreground_service), - createDisableForeground()); return mBuilder.build(); } diff --git a/src/main/java/eu/siacs/conversations/services/UpdaterWebService.java b/src/main/java/eu/siacs/conversations/services/UpdaterWebService.java new file mode 100644 index 000000000..cb58b49eb --- /dev/null +++ b/src/main/java/eu/siacs/conversations/services/UpdaterWebService.java @@ -0,0 +1,103 @@ +package eu.siacs.conversations.services; + +import android.app.IntentService; +import android.content.Intent; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.util.Log; + +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.StatusLine; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.conn.params.ConnManagerParams; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.params.HttpConnectionParams; +import org.apache.http.params.HttpParams; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import eu.siacs.conversations.Config; +import eu.siacs.conversations.R; +import eu.siacs.conversations.ui.UpdaterActivity.UpdateReceiver; + +public class UpdaterWebService extends IntentService{ + public static final String REQUEST_STRING = ""; + public static final String RESPONSE_MESSAGE = ""; + + private String URL = null; + public static final int REGISTRATION_TIMEOUT = 3 * 1000; + public static final int WAIT_TIMEOUT = 30 * 1000; + + public UpdaterWebService() { + super("UpdaterWebService"); + } + + @Override + protected void onHandleIntent(Intent intent) { + + String requestString = intent.getStringExtra(REQUEST_STRING); + Log.d(Config.LOGTAG, "AppUpdater: " + requestString); + String responseMessage; + PackageInfo pInfo = null; + try { + pInfo = getPackageManager().getPackageInfo(getPackageName(), 0); + } + catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + //get the app version Name for display + final String versionName = pInfo.versionName; + + try { + + URL = requestString; + HttpClient httpclient = new DefaultHttpClient(); + HttpParams params = httpclient.getParams(); + + HttpConnectionParams.setConnectionTimeout(params, REGISTRATION_TIMEOUT); + HttpConnectionParams.setSoTimeout(params, WAIT_TIMEOUT); + ConnManagerParams.setTimeout(params, WAIT_TIMEOUT); + + HttpGet httpGet = new HttpGet(URL); + httpGet.setHeader("User-Agent", getString(R.string.app_name) + " " + versionName); + HttpResponse response = httpclient.execute(httpGet); + + StatusLine statusLine = response.getStatusLine(); + Log.d(Config.LOGTAG, "AppUpdater: HTTP Status Code: " + statusLine.getStatusCode()); + if(statusLine.getStatusCode() == HttpStatus.SC_OK){ + ByteArrayOutputStream out = new ByteArrayOutputStream(); + response.getEntity().writeTo(out); + out.close(); + responseMessage = out.toString(); + } else { + Log.e(Config.LOGTAG, "AppUpdater: HTTP1:" + statusLine.getReasonPhrase()); + response.getEntity().getContent().close(); + throw new IOException(statusLine.getReasonPhrase()); + } + + } catch (ClientProtocolException e) { + Log.e(Config.LOGTAG, "AppUpdater: HTTP2:" + e); + responseMessage = ""; + } catch (IOException e) { + Log.e(Config.LOGTAG, "AppUpdater: HTTP3:" + e); + responseMessage = ""; + }catch (Exception e) { + Log.e(Config.LOGTAG, "AppUpdater: HTTP4:" + e); + responseMessage = ""; + } + + + Intent broadcastIntent = new Intent(); + broadcastIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + broadcastIntent.setAction(UpdateReceiver.PROCESS_RESPONSE); + broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT); + broadcastIntent.putExtra(RESPONSE_MESSAGE, responseMessage); + sendBroadcast(broadcastIntent); + + } + +}
\ No newline at end of file diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 2aaf9b622..7849f8a39 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -2681,7 +2681,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } public boolean allowMessageCorrection() { - return getPreferences().getBoolean("allow_message_correction", false); + return getPreferences().getBoolean("allow_message_correction", true); } public boolean sendChatStates() { diff --git a/src/main/java/eu/siacs/conversations/ui/AboutPreference.java b/src/main/java/eu/siacs/conversations/ui/AboutPreference.java index bd2042fb6..451f0bfa6 100644 --- a/src/main/java/eu/siacs/conversations/ui/AboutPreference.java +++ b/src/main/java/eu/siacs/conversations/ui/AboutPreference.java @@ -26,7 +26,7 @@ public class AboutPreference extends Preference { } private void setSummary() { - setSummary("Conversations " + PhoneHelper.getVersionName(getContext())); + setSummary("Pix-Art Messenger " + PhoneHelper.getVersionName(getContext())); } } diff --git a/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java b/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java index e4fc59fab..a43709ae5 100644 --- a/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java @@ -370,7 +370,7 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd account = contact.getAccount().getJid().toBareJid().toString(); } accountJidTv.setText(getString(R.string.using_account, account)); - badge.setImageBitmap(avatarService().get(contact, getPixel(72))); + badge.setImageBitmap(avatarService().get(contact, getPixel(Config.AVATAR_SIZE))); badge.setOnClickListener(this.onBadgeClick); keys.removeAllViews(); diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java index 920c07af1..868835da8 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java @@ -6,10 +6,12 @@ import android.app.AlertDialog; import android.app.FragmentTransaction; import android.app.PendingIntent; import android.content.ClipData; +import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.content.Intent; import android.content.IntentSender.SendIntentException; +import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.net.Uri; import android.os.Build; @@ -32,6 +34,7 @@ import android.widget.ArrayAdapter; import android.widget.CheckBox; import android.widget.PopupMenu; import android.widget.PopupMenu.OnMenuItemClickListener; +import android.widget.TextView; import android.widget.Toast; import net.java.otr4j.session.SessionStatus; @@ -53,6 +56,7 @@ import eu.siacs.conversations.entities.Blockable; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.Message; +import eu.siacs.conversations.entities.Presence; import eu.siacs.conversations.entities.Transferable; import eu.siacs.conversations.persistance.FileBackend; import eu.siacs.conversations.services.XmppConnectionService; @@ -61,12 +65,14 @@ import eu.siacs.conversations.services.XmppConnectionService.OnConversationUpdat import eu.siacs.conversations.services.XmppConnectionService.OnRosterUpdate; import eu.siacs.conversations.ui.adapter.ConversationAdapter; import eu.siacs.conversations.utils.ExceptionHelper; +import eu.siacs.conversations.utils.UIHelper; import eu.siacs.conversations.xmpp.OnUpdateBlocklist; +import eu.siacs.conversations.xmpp.chatstate.ChatState; import eu.siacs.conversations.xmpp.jid.InvalidJidException; import eu.siacs.conversations.xmpp.jid.Jid; public class ConversationActivity extends XmppActivity - implements OnAccountUpdate, OnConversationUpdate, OnRosterUpdate, OnUpdateBlocklist, XmppConnectionService.OnShowErrorToast { + implements OnAccountUpdate, OnConversationUpdate, OnRosterUpdate, OnUpdateBlocklist, XmppConnectionService.OnShowErrorToast, View.OnClickListener { public static final String ACTION_DOWNLOAD = "eu.siacs.conversations.action.DOWNLOAD"; @@ -179,6 +185,8 @@ public class ConversationActivity extends XmppActivity } } + AppUpdate(); + setContentView(R.layout.fragment_conversations_overview); this.mConversationFragment = new ConversationFragment(); @@ -276,8 +284,9 @@ public class ConversationActivity extends XmppActivity listView.enableSwipeToDismiss(); listView.setSwipingLayout(R.id.swipeable_item); listView.setUndoStyle(EnhancedListView.UndoStyle.SINGLE_POPUP); - listView.setUndoHideDelay(5000); + listView.setUndoHideDelay(10000); listView.setRequireTouchBeforeDismiss(false); + listView.setSwipeDirection(EnhancedListView.SwipeDirection.START); // swipe to left to close conversation mContentView = findViewById(R.id.content_view_spl); if (mContentView == null) { @@ -318,6 +327,32 @@ public class ConversationActivity extends XmppActivity } } + protected void AppUpdate() { + String PREFS_NAME = "UpdateTimeStamp"; + SharedPreferences UpdateTimeStamp = getApplicationContext().getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE); + long lastUpdateTime = UpdateTimeStamp.getLong("lastUpdateTime", 0); + + Log.d(Config.LOGTAG, "AppUpdater - LastUpdateTime: " + lastUpdateTime); + + if ((lastUpdateTime + (Config.UPDATE_CHECK_TIMER * 1000)) < System.currentTimeMillis()) { + lastUpdateTime = System.currentTimeMillis(); + SharedPreferences.Editor editor = UpdateTimeStamp.edit(); + editor.putLong("lastUpdateTime", lastUpdateTime); + editor.commit(); + + // run AppUpdater + Log.d(Config.LOGTAG, "AppUpdater - CurrentTime: " + lastUpdateTime); + Intent AppUpdater = new Intent(this, UpdaterActivity.class); + startActivity(AppUpdater); + Log.d(Config.LOGTAG, "AppUpdater started"); + + } else { + + Log.d(Config.LOGTAG, "AppUpdater stopped"); + return; + } + } + @Override public void switchToConversation(Conversation conversation) { setSelectedConversation(conversation); @@ -335,24 +370,69 @@ public class ConversationActivity extends XmppActivity } private void updateActionBarTitle(boolean titleShouldBeName) { - final ActionBar ab = getActionBar(); - final Conversation conversation = getSelectedConversation(); - if (ab != null) { - if (titleShouldBeName && conversation != null) { - ab.setDisplayHomeAsUpEnabled(true); - ab.setHomeButtonEnabled(true); - if (conversation.getMode() == Conversation.MODE_SINGLE || useSubjectToIdentifyConference()) { - ab.setTitle(conversation.getName()); - } else { - ab.setTitle(conversation.getJid().toBareJid().toString()); - } - } else { - ab.setDisplayHomeAsUpEnabled(false); - ab.setHomeButtonEnabled(false); - ab.setTitle(R.string.app_name); - } - } - } + final ActionBar ab = getActionBar(); + final Conversation conversation = getSelectedConversation(); + if (ab != null) { + if (titleShouldBeName && conversation != null) { + ab.setDisplayHomeAsUpEnabled(true); + ab.setHomeButtonEnabled(true); + ab.setDisplayShowTitleEnabled(false); + ab.setDisplayShowCustomEnabled(true); + ab.setCustomView(R.layout.ab_title); + if (conversation.getMode() == Conversation.MODE_SINGLE || useSubjectToIdentifyConference()) { + TextView abtitle = (TextView) findViewById(android.R.id.text1); + abtitle.setText(conversation.getName()); + abtitle.setOnClickListener(this); + if (conversation.getMode() == Conversation.MODE_SINGLE) { + if (conversation.getContact().getMostAvailableStatus() == Presence.Status.OFFLINE) { + TextView absubtitle = (TextView) findViewById(android.R.id.text2); + absubtitle.setText(getString(R.string.account_status_offline)); + absubtitle.setOnClickListener(this); + } else { + ChatState state = conversation.getIncomingChatState(); + if (state == ChatState.COMPOSING) { + TextView absubtitle = (TextView) findViewById(android.R.id.text2); + absubtitle.setText(getString(R.string.is_typing)); + absubtitle.setOnClickListener(this); + } else if (state == ChatState.PAUSED) { + TextView absubtitle = (TextView) findViewById(android.R.id.text2); + absubtitle.setText(UIHelper.lastseen(getApplicationContext(), conversation.getContact().lastseen.time)); + absubtitle.setOnClickListener(this); + } else { + TextView absubtitle = (TextView) findViewById(android.R.id.text2); + absubtitle.setText(UIHelper.lastseen(getApplicationContext(), conversation.getContact().lastseen.time)); + absubtitle.setOnClickListener(this); + } + } + } else if (useSubjectToIdentifyConference()) { + if (conversation.getParticipants() != null) { + TextView absubtitle = (TextView) findViewById(android.R.id.text2); + absubtitle.setText(conversation.getParticipants()); + absubtitle.setOnClickListener(this); + } else { + TextView absubtitle = (TextView) findViewById(android.R.id.text2); + absubtitle.setText(R.string.no_participants); + absubtitle.setOnClickListener(this); + } + } + } else { + TextView abtitle = (TextView) findViewById(android.R.id.text1); + abtitle.setText(conversation.getJid().toBareJid().toString()); + abtitle.setOnClickListener(this); + TextView absubtitle = (TextView) findViewById(android.R.id.text2); + absubtitle.setText(null); + absubtitle.setOnClickListener(this); + } + } else { + ab.setDisplayHomeAsUpEnabled(false); + ab.setHomeButtonEnabled(false); + ab.setDisplayShowTitleEnabled(true); + ab.setDisplayShowCustomEnabled(false); + ab.setTitle(R.string.app_name); + ab.setSubtitle(null); + } + } + } private void openConversation() { this.updateActionBarTitle(); @@ -376,19 +456,16 @@ public class ConversationActivity extends XmppActivity getMenuInflater().inflate(R.menu.conversations, menu); final MenuItem menuSecure = menu.findItem(R.id.action_security); final MenuItem menuArchive = menu.findItem(R.id.action_archive); - final MenuItem menuMucDetails = menu.findItem(R.id.action_muc_details); - final MenuItem menuContactDetails = menu.findItem(R.id.action_contact_details); final MenuItem menuAttach = menu.findItem(R.id.action_attach_file); final MenuItem menuClearHistory = menu.findItem(R.id.action_clear_history); final MenuItem menuAdd = menu.findItem(R.id.action_add); final MenuItem menuInviteContact = menu.findItem(R.id.action_invite); final MenuItem menuMute = menu.findItem(R.id.action_mute); final MenuItem menuUnmute = menu.findItem(R.id.action_unmute); + final MenuItem menuUpdater = menu.findItem(R.id.action_check_updates); if (isConversationsOverviewVisable() && isConversationsOverviewHideable()) { menuArchive.setVisible(false); - menuMucDetails.setVisible(false); - menuContactDetails.setVisible(false); menuSecure.setVisible(false); menuInviteContact.setVisible(false); menuAttach.setVisible(false); @@ -397,6 +474,9 @@ public class ConversationActivity extends XmppActivity menuUnmute.setVisible(false); } else { menuAdd.setVisible(!isConversationsOverviewHideable()); + //hide settings, accounts and updater in all menus except in main window + menuUpdater.setVisible(false); + if (this.getSelectedConversation() != null) { if (this.getSelectedConversation().getNextEncryption() != Message.ENCRYPTION_NONE) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { @@ -406,7 +486,6 @@ public class ConversationActivity extends XmppActivity } } if (this.getSelectedConversation().getMode() == Conversation.MODE_MULTI) { - menuContactDetails.setVisible(false); menuAttach.setVisible(getSelectedConversation().getAccount().httpUploadAvailable() && getSelectedConversation().getMucOptions().participating()); menuInviteContact.setVisible(getSelectedConversation().getMucOptions().canInvite()); menuSecure.setVisible((Config.supportOpenPgp() || Config.supportOmemo()) && Config.multipleEncryptionChoices()); //only if pgp is supported we have a choice @@ -629,6 +708,7 @@ public class ConversationActivity extends XmppActivity case R.id.action_archive: this.endConversation(getSelectedConversation()); break; +/* case R.id.action_contact_details: switchToContactDetails(getSelectedConversation().getContact()); break; @@ -639,6 +719,7 @@ public class ConversationActivity extends XmppActivity intent.putExtra("uuid", getSelectedConversation().getUuid()); startActivity(intent); break; +*/ case R.id.action_invite: inviteToConversation(getSelectedConversation()); break; @@ -955,8 +1036,7 @@ public class ConversationActivity extends XmppActivity } else if (modifier && key == downKey) { if (isConversationsOverviewHideable() && !isConversationsOverviewVisable()) { showConversationsOverview(); - ; - } + } return selectDownConversation(); } else if (modifier && key == upKey) { if (isConversationsOverviewHideable() && !isConversationsOverviewVisable()) { @@ -1085,6 +1165,8 @@ public class ConversationActivity extends XmppActivity sendReadMarkerIfNecessary(getSelectedConversation()); } + AppUpdate(); + } @Override @@ -1414,7 +1496,7 @@ public class ConversationActivity extends XmppActivity if (conversation == null) { return; } - xmppConnectionService.attachLocationToConversation(conversation,uri, new UiCallback<Message>() { + xmppConnectionService.attachLocationToConversation(conversation, uri, new UiCallback<Message>() { @Override public void success(Message message) { @@ -1553,7 +1635,7 @@ public class ConversationActivity extends XmppActivity } public boolean useWhiteBackground() { - return getPreferences().getBoolean("use_white_background",false); + return getPreferences().getBoolean("use_white_background", false); } protected boolean trustKeysIfNeeded(int requestCode) { @@ -1643,6 +1725,20 @@ public class ConversationActivity extends XmppActivity return !isConversationsOverviewHideable() || this.conversationWasSelectedByKeyboard; } + @Override + public void onClick(View view) { + final Conversation conversation = getSelectedConversation(); + if (conversation.getMode() == Conversation.MODE_SINGLE) { + switchToContactDetails(getSelectedConversation().getContact()); + } else if (conversation.getMode() == Conversation.MODE_MULTI) { + Intent intent = new Intent(this, + ConferenceDetailsActivity.class); + intent.setAction(ConferenceDetailsActivity.ACTION_VIEW_MUC); + intent.putExtra("uuid", getSelectedConversation().getUuid()); + startActivity(intent); + } + } + public void setMessagesLoaded() { if (mConversationFragment != null) { mConversationFragment.setMessagesLoaded(); diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 095bf58fa..ca996b505 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -1116,18 +1116,18 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa if (conversation.getMode() == Conversation.MODE_SINGLE) { ChatState state = conversation.getIncomingChatState(); if (state == ChatState.COMPOSING) { - this.messageList.add(Message.createStatusMessage(conversation, getString(R.string.contact_is_typing, conversation.getName()))); + //this.messageList.add(Message.createStatusMessage(conversation, getString(R.string.contact_is_typing, conversation.getName()))); } else if (state == ChatState.PAUSED) { - this.messageList.add(Message.createStatusMessage(conversation, getString(R.string.contact_has_stopped_typing, conversation.getName()))); + //this.messageList.add(Message.createStatusMessage(conversation, getString(R.string.contact_has_stopped_typing, conversation.getName()))); } else { for (int i = this.messageList.size() - 1; i >= 0; --i) { if (this.messageList.get(i).getStatus() == Message.STATUS_RECEIVED) { return; } else { if (this.messageList.get(i).getStatus() == Message.STATUS_SEND_DISPLAYED) { - this.messageList.add(i + 1, - Message.createStatusMessage(conversation, getString(R.string.contact_has_read_up_to_this_point, conversation.getName()))); - return; +// this.messageList.add(i + 1, +// Message.createStatusMessage(conversation, getString(R.string.contact_has_read_up_to_this_point, conversation.getName()))); +// return; } } } diff --git a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java index 9d73290a5..787c325ae 100644 --- a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java @@ -32,12 +32,12 @@ import android.widget.TableLayout; import android.widget.TableRow; import android.widget.TextView; import android.widget.Toast; - +import org.whispersystems.libaxolotl.IdentityKey; +import java.util.Set; import java.util.Arrays; import java.util.List; import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; - import eu.siacs.conversations.Config; import eu.siacs.conversations.R; import eu.siacs.conversations.crypto.axolotl.AxolotlService; @@ -433,7 +433,7 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate this.mAxolotlFingerprint = (TextView) findViewById(R.id.axolotl_fingerprint); this.mAxolotlFingerprintBox = (RelativeLayout) findViewById(R.id.axolotl_fingerprint_box); this.mAxolotlFingerprintToClipboardButton = (ImageButton) findViewById(R.id.action_copy_axolotl_to_clipboard); - this.mRegenerateAxolotlKeyButton = (ImageButton) findViewById(R.id.action_regenerate_axolotl_key); + this.mRegenerateAxolotlKeyButton = (ImageButton) findViewById(R.id.action_regenerate_omemo_key); this.keysCard = (LinearLayout) findViewById(R.id.other_device_keys_card); this.keys = (LinearLayout) findViewById(R.id.other_device_keys); this.mNamePort = (LinearLayout) findViewById(R.id.name_port); @@ -630,7 +630,7 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate if (!mInitMode) { this.mAvatar.setVisibility(View.VISIBLE); - this.mAvatar.setImageBitmap(avatarService().get(this.mAccount, getPixel(72))); + this.mAvatar.setImageBitmap(avatarService().get(this.mAccount, getPixel(Config.AVATAR_SIZE))); } if (this.mAccount.isOptionSet(Account.OPTION_REGISTER)) { this.mRegisterNew.setVisibility(View.VISIBLE); diff --git a/src/main/java/eu/siacs/conversations/ui/ManageAccountActivity.java b/src/main/java/eu/siacs/conversations/ui/ManageAccountActivity.java index feac2c622..82bce31c0 100644 --- a/src/main/java/eu/siacs/conversations/ui/ManageAccountActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ManageAccountActivity.java @@ -114,7 +114,7 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); ManageAccountActivity.this.getMenuInflater().inflate( - R.menu.manageaccounts_context, menu); + R.menu.manageaccounts_context, menu); AdapterContextMenuInfo acmi = (AdapterContextMenuInfo) menuInfo; this.selectedAccount = accountList.get(acmi.position); if (this.selectedAccount.isOptionSet(Account.OPTION_DISABLED)) { @@ -155,9 +155,9 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda addAccount.setVisible(false); addAccountWithCertificate.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); } else { - addAccount.setVisible(!Config.LOCK_SETTINGS); + addAccount.setVisible(!(Config.LOCK_SETTINGS || Config.SINGLE_ACCOUNT)); } - addAccountWithCertificate.setVisible(!Config.LOCK_SETTINGS); + addAccountWithCertificate.setVisible(!(Config.LOCK_SETTINGS || Config.SINGLE_ACCOUNT)); if (!accountsLeftToEnable()) { enableAll.setVisible(false); diff --git a/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java b/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java index 27a3efe59..2b25ad321 100644 --- a/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java @@ -1,3 +1,4 @@ + package eu.siacs.conversations.ui; import android.app.PendingIntent; @@ -200,7 +201,7 @@ public class PublishProfilePictureActivity extends XmppActivity { source = Uri.parse("file://"+original); } Uri destination = Uri.fromFile(new File(getCacheDir(), "croppedAvatar")); - final int size = getPixel(192); + final int size = getPixel(Config.AVATAR_SIZE); Crop.of(source, destination).asSquare().withMaxSize(size, size).start(this); break; case REQUEST_CHOOSE_FILE: @@ -240,7 +241,7 @@ public class PublishProfilePictureActivity extends XmppActivity { if (this.avatarUri == null) { if (this.account.getAvatar() != null || this.defaultUri == null) { - this.avatar.setImageBitmap(avatarService().get(account, getPixel(192))); + this.avatar.setImageBitmap(avatarService().get(account, getPixel(Config.AVATAR_SIZE))); if (this.defaultUri != null) { this.avatar .setOnLongClickListener(this.backToDefaultListener); @@ -285,7 +286,7 @@ public class PublishProfilePictureActivity extends XmppActivity { protected void loadImageIntoPreview(Uri uri) { Bitmap bm = null; try { - bm = xmppConnectionService.getFileBackend().cropCenterSquare(uri, getPixel(192)); + bm = xmppConnectionService.getFileBackend().cropCenterSquare(uri, getPixel(Config.AVATAR_SIZE)); } catch (Exception e) { e.printStackTrace(); } diff --git a/src/main/java/eu/siacs/conversations/ui/UpdaterActivity.java b/src/main/java/eu/siacs/conversations/ui/UpdaterActivity.java new file mode 100644 index 000000000..7c8efe5be --- /dev/null +++ b/src/main/java/eu/siacs/conversations/ui/UpdaterActivity.java @@ -0,0 +1,308 @@ +package eu.siacs.conversations.ui; + +import android.Manifest; +import android.app.Activity; +import android.app.AlertDialog; +import android.app.DownloadManager; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.os.Environment; +import android.support.v4.app.ActivityCompat; +import android.util.Log; +import android.view.WindowManager; +import android.widget.TextView; +import android.widget.Toast; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.File; + +import eu.siacs.conversations.Config; +import eu.siacs.conversations.R; +import eu.siacs.conversations.services.UpdaterWebService; + +public class UpdaterActivity extends Activity { + + private UpdateReceiver receiver = null; + private int versionCode = 0; + String appURI = ""; + + private DownloadManager downloadManager; + private long downloadReference; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + //set activity + setContentView(R.layout.activity_updater); + TextView textView = (TextView) findViewById(R.id.updater); + textView.setText(R.string.update_info); + + //Broadcast receiver for our Web Request + IntentFilter filter = new IntentFilter(UpdateReceiver.PROCESS_RESPONSE); + filter.addCategory(Intent.CATEGORY_DEFAULT); + receiver = new UpdateReceiver(); + registerReceiver(receiver, filter); + + //Broadcast receiver for the download manager (download complete) + registerReceiver(downloadReceiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)); + + //check of internet is available before making a web service request + if (isNetworkAvailable(this)) { + Intent msgIntent = new Intent(this, UpdaterWebService.class); + msgIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + msgIntent.putExtra(UpdaterWebService.REQUEST_STRING, Config.UPDATE_URL); + + Toast.makeText(getApplicationContext(), + getText(R.string.checking_for_updates), + Toast.LENGTH_SHORT).show(); + startService(msgIntent); + } + } + + @Override + public void onDestroy() { + //unregister your receivers + this.unregisterReceiver(receiver); + this.unregisterReceiver(downloadReceiver); + super.onDestroy(); + //enable touch events + getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE); + } + + @Override + public void onSaveInstanceState(Bundle savedInstanceState) { + super.onSaveInstanceState(savedInstanceState); + } + + @Override + public void onRestoreInstanceState(Bundle savedInstanceState) { + super.onRestoreInstanceState(savedInstanceState); + } + + //check for internet connection + private boolean isNetworkAvailable(Context context) { + ConnectivityManager connectivity = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); + if (connectivity != null) { + NetworkInfo[] info = connectivity.getAllNetworkInfo(); + if (info != null) { + for (int i = 0; i < info.length; i++) { + Log.d(Config.LOGTAG, "AppUpdater: " + String.valueOf(i)); + if (info[i].getState() == NetworkInfo.State.CONNECTED) { + Log.d(Config.LOGTAG, "AppUpdater: connected to update Server!"); + return true; + } + } + } + } + return false; + } + + //broadcast receiver to get notification when the web request finishes + public class UpdateReceiver extends BroadcastReceiver { + + public static final String PROCESS_RESPONSE = "eu.siacs.conversations.intent.action.PROCESS_RESPONSE"; + + @Override + public void onReceive(Context context, Intent intent) { + + //disable touch events + getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, + WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE); + + String responseMessage = intent.getStringExtra(UpdaterWebService.RESPONSE_MESSAGE); + Log.d(Config.LOGTAG, "AppUpdater: Reponse: " + responseMessage); + + if (responseMessage == "" || responseMessage.isEmpty() || responseMessage == null) { + Toast.makeText(getApplicationContext(), + getText(R.string.failed), + Toast.LENGTH_LONG).show(); + Log.e(Config.LOGTAG, "AppUpdater: error connecting to server"); + UpdaterActivity.this.finish(); + } else { + Log.d(Config.LOGTAG, "AppUpdater: connecting to server"); + //parse the JSON reponse + JSONObject reponseObj; + + try { + //if the response was successful check further + reponseObj = new JSONObject(responseMessage); + boolean success = reponseObj.getBoolean("success"); + if (success) { + //Overall information about the contents of a package + //This corresponds to all of the information collected from AndroidManifest.xml. + PackageInfo pInfo = null; + try { + pInfo = getPackageManager().getPackageInfo(getPackageName(), 0); + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + //get the app version Name for display + final String versionName = pInfo.versionName; + final int versionCode = pInfo.versionCode; + //get the latest version from the JSON string + int latestVersionCode = reponseObj.getInt("latestVersionCode"); + String latestVersion = reponseObj.getString("latestVersion"); + String changelog = reponseObj.getString("changelog"); + //get the lastest application URI from the JSON string + appURI = reponseObj.getString("appURI"); + //check if we need to upgrade? + if (latestVersionCode > versionCode) { + Log.d(Config.LOGTAG, "AppUpdater: update available"); + //delete old downloaded version files + File dir = new File(getExternalFilesDir(null), Environment.DIRECTORY_DOWNLOADS); + Log.d(Config.LOGTAG, "AppUpdater: delete old update files in: " + dir); + if (dir.isDirectory()) { + String[] children = dir.list(); + for (int i = 0; i < children.length; i++) { + new File(dir, children[i]).delete(); + } + } + //enable touch events + getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE); + + //oh yeah we do need an upgrade, let the user know send an alert message + AlertDialog.Builder builder = new AlertDialog.Builder(UpdaterActivity.this); + builder.setCancelable(false); + + String UpdateMessageInfo = getResources().getString(R.string.update_available); + builder.setMessage(String.format(UpdateMessageInfo, latestVersion, changelog, versionName)) + .setPositiveButton(R.string.update, new DialogInterface.OnClickListener() { + //if the user agrees to upgrade + public void onClick(DialogInterface dialog, int id) { + //disable touch events + getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, + WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE); + //ask for permissions on devices >= SDK 23 + if (isStoragePermissionGranted()) { + //start downloading the file using the download manager + downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE); + Uri Download_Uri = Uri.parse(appURI); + DownloadManager.Request request = new DownloadManager.Request(Download_Uri); + //request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI); + //request.setAllowedOverRoaming(false); + request.setTitle("Pix-Art Messenger Update"); + request.setDestinationInExternalFilesDir(UpdaterActivity.this, Environment.DIRECTORY_DOWNLOADS, "Conversations.apk"); + downloadReference = downloadManager.enqueue(request); + Toast.makeText(getApplicationContext(), + getText(R.string.download_started), + Toast.LENGTH_LONG).show(); + } + } + }) + .setNeutralButton(R.string.changelog, new DialogInterface.OnClickListener() { + //open link to changelog + public void onClick(DialogInterface dialog, int id) { + Uri uri = Uri.parse("https://github.com/kriztan/Conversations/blob/development/CHANGELOG.md"); // missing 'http://' will cause crashed + Intent intent = new Intent(Intent.ACTION_VIEW, uri); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(intent); + //restart updater to show dialog again after coming back after opening changelog + recreate(); + } + }) + .setNegativeButton(R.string.remind_later, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + // User cancelled the dialog + UpdaterActivity.this.finish(); + } + }); + //show the alert message + builder.create().show(); + } else { + Toast.makeText(getApplicationContext(), + getText(R.string.no_update_available), + Toast.LENGTH_SHORT).show(); + Log.d(Config.LOGTAG, "AppUpdater: no update available"); + UpdaterActivity.this.finish(); + } + } else { + Toast.makeText(getApplicationContext(), + getText(R.string.failed), + Toast.LENGTH_LONG).show(); + Log.e(Config.LOGTAG, "AppUpdater: contact to server not successfull"); + UpdaterActivity.this.finish(); + } + } catch (JSONException e) { + e.printStackTrace(); + } + } + + } + + } + + public boolean isStoragePermissionGranted() { + if (Build.VERSION.SDK_INT >= 23) { + if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) + == PackageManager.PERMISSION_GRANTED) { + Log.d(Config.LOGTAG, "AppUpdater: Permission is granted"); + return true; + } else { + + Log.d(Config.LOGTAG, "AppUpdater: Permission is revoked"); + ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1); + return false; + } + } else { //permission is automatically granted on sdk<23 upon installation + Log.d(Config.LOGTAG, "AppUpdater: Permission is granted"); + return true; + } + } + + //broadcast receiver to get notification about ongoing downloads + BroadcastReceiver downloadReceiver = new BroadcastReceiver() { + + @Override + public void onReceive(Context context, Intent intent) { + //check if the broadcast message is for our Enqueued download + long referenceId = intent.getExtras().getLong(DownloadManager.EXTRA_DOWNLOAD_ID); + if (downloadReference == referenceId) { + File file = new File(getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "Conversations.apk"); + Log.d(Config.LOGTAG, "AppUpdater: Downloading of the new app version complete. Starting installation from " + file); + + //start the installation of the latest version + Intent installIntent = new Intent(Intent.ACTION_INSTALL_PACKAGE); + installIntent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive"); + installIntent.putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, true); + installIntent.putExtra(Intent.EXTRA_RETURN_RESULT, true); + installIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(installIntent); + + UpdaterActivity.this.finish(); + } + } + }; + + //show warning on back pressed + @Override + public void onBackPressed() { + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setMessage(R.string.cancel_update) + .setCancelable(false) + .setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + UpdaterActivity.this.finish(); + } + }) + .setNegativeButton(R.string.no, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + dialog.cancel(); + } + }); + AlertDialog alert = builder.create(); + alert.show(); + } +} diff --git a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java index 7d70b20fe..646c9d3f4 100644 --- a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java @@ -341,6 +341,9 @@ public abstract class XmppActivity extends Activity { case R.id.action_settings: startActivity(new Intent(this, SettingsActivity.class)); break; + case R.id.action_check_updates: + startActivity(new Intent(this, UpdaterActivity.class)); + break; case R.id.action_accounts: startActivity(new Intent(this, ManageAccountActivity.class)); break; diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/AccountAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/AccountAdapter.java index 98250af94..c1b9cbdf6 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/AccountAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/AccountAdapter.java @@ -43,7 +43,7 @@ public class AccountAdapter extends ArrayAdapter<Account> { } TextView statusView = (TextView) view.findViewById(R.id.account_status); ImageView imageView = (ImageView) view.findViewById(R.id.account_image); - imageView.setImageBitmap(activity.avatarService().get(account, activity.getPixel(48))); + imageView.setImageBitmap(activity.avatarService().get(account, activity.getPixel(56))); statusView.setText(getContext().getString(account.getStatus().getReadableId())); switch (account.getStatus()) { case ONLINE: diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java index 0268097f4..d69fa4b95 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -130,6 +130,7 @@ public class MessageAdapter extends ArrayAdapter<Message> { boolean error = false; if (viewHolder.indicatorReceived != null) { viewHolder.indicatorReceived.setVisibility(View.GONE); + viewHolder.indicatorRead.setVisibility(View.GONE); } if (viewHolder.edit_indicator != null) { @@ -177,6 +178,7 @@ public class MessageAdapter extends ArrayAdapter<Message> { case Message.STATUS_SEND_DISPLAYED: if (mIndicateReceived) { viewHolder.indicatorReceived.setVisibility(View.VISIBLE); + viewHolder.indicatorRead.setVisibility(View.VISIBLE); } break; case Message.STATUS_SEND_FAILED: @@ -425,7 +427,7 @@ public class MessageAdapter extends ArrayAdapter<Message> { viewHolder.messageBody.setVisibility(View.GONE); viewHolder.image.setVisibility(View.VISIBLE); FileParams params = message.getFileParams(); - double target = metrics.density * 288; + double target = metrics.density * 200; int scalledW; int scalledH; if (params.width <= params.height) { @@ -493,6 +495,8 @@ public class MessageAdapter extends ArrayAdapter<Message> { .findViewById(R.id.message_time); viewHolder.indicatorReceived = (ImageView) view .findViewById(R.id.indicator_received); + viewHolder.indicatorRead = (ImageView) view + .findViewById(R.id.indicator_read); break; case RECEIVED: view = activity.getLayoutInflater().inflate( @@ -635,7 +639,8 @@ public class MessageAdapter extends ArrayAdapter<Message> { displayLocationMessage(viewHolder,message); } else if (message.bodyIsHeart()) { displayHeartMessage(viewHolder, message.getBody().trim()); - } else if (message.treatAsDownloadable() == Message.Decision.MUST) { + } else if (message.treatAsDownloadable() == Message.Decision.MUST || + message.treatAsDownloadable() == Message.Decision.SHOULD) { try { URL url = new URL(message.getBody()); displayDownloadableMessage(viewHolder, @@ -730,6 +735,7 @@ public class MessageAdapter extends ArrayAdapter<Message> { protected ImageView image; protected ImageView indicator; protected ImageView indicatorReceived; + protected ImageView indicatorRead; protected TextView time; protected TextView messageBody; protected ImageView contact_picture; diff --git a/src/main/java/eu/siacs/conversations/utils/ExceptionHelper.java b/src/main/java/eu/siacs/conversations/utils/ExceptionHelper.java index 8799b4a55..f2c3ea18a 100644 --- a/src/main/java/eu/siacs/conversations/utils/ExceptionHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/ExceptionHelper.java @@ -92,10 +92,11 @@ public class ExceptionHelper { Log.d(Config.LOGTAG, "using account=" + finalAccount.getJid().toBareJid() + " to send in stack trace"); + Conversation conversation = null; try { conversation = service.findOrCreateConversation(finalAccount, - Jid.fromString("bugs@siacs.eu"), false); + Jid.fromString("bugs@pix-art.de"), false); } catch (final InvalidJidException ignored) { } Message message = new Message(conversation, report diff --git a/src/main/java/eu/siacs/conversations/utils/GeoHelper.java b/src/main/java/eu/siacs/conversations/utils/GeoHelper.java index 74f91a98b..aa9b2e50f 100644 --- a/src/main/java/eu/siacs/conversations/utils/GeoHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/GeoHelper.java @@ -9,6 +9,7 @@ import java.util.ArrayList; import java.util.regex.Matcher; import java.util.regex.Pattern; +import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.Message; @@ -40,6 +41,7 @@ public class GeoHelper { return intents; } final Conversation conversation = message.getConversation(); + final Contact contact = message.getContact(); String label; if (conversation.getMode() == Conversation.MODE_SINGLE && message.getStatus() == Message.STATUS_RECEIVED) { try { @@ -60,6 +62,18 @@ public class GeoHelper { locationPluginIntent.putExtra("jid",message.getCounterpart().toString()); } else { + locationPluginIntent.putExtra("name", conversation.getAccount().getUsername()); + locationPluginIntent.putExtra("jid",conversation.getAccount().getJid().toString()); + } + } else { + if (message.getStatus() == Message.STATUS_RECEIVED) { + if (contact != null) { + locationPluginIntent.putExtra("name",contact.getDisplayName()); + } + locationPluginIntent.putExtra("jid",message.getCounterpart().toString()); + } + else { + locationPluginIntent.putExtra("name", conversation.getAccount().getUsername()); locationPluginIntent.putExtra("jid",conversation.getAccount().getJid().toString()); } } @@ -74,4 +88,4 @@ public class GeoHelper { intents.add(httpIntent); return intents; } -} +}
\ No newline at end of file diff --git a/src/main/java/eu/siacs/conversations/utils/PhoneHelper.java b/src/main/java/eu/siacs/conversations/utils/PhoneHelper.java index 6c1b4bef5..48c9104f9 100644 --- a/src/main/java/eu/siacs/conversations/utils/PhoneHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/PhoneHelper.java @@ -133,4 +133,8 @@ public class PhoneHelper { return "unknown"; } } + + public static String getOSVersion(Context context) { + return "Android/" + android.os.Build.MODEL + "/" + android.os.Build.VERSION.RELEASE; + } } diff --git a/src/main/java/eu/siacs/conversations/xmpp/OnNewKeysAvailable.java b/src/main/java/eu/siacs/conversations/xmpp/OnNewKeysAvailable.java new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/src/main/java/eu/siacs/conversations/xmpp/OnNewKeysAvailable.java |