Merge remote-tracking branch 'refs/remotes/siacs/master'
This commit is contained in:
commit
c23642b8cd
13 changed files with 128 additions and 71 deletions
|
@ -1,9 +1,16 @@
|
|||
###Changelog
|
||||
|
||||
####Version 1.13.1
|
||||
* add database importer from local storage as backup
|
||||
* bug fixes
|
||||
|
||||
####Version 1.13.0
|
||||
* changed applicationId
|
||||
* play videos directly without touching play button
|
||||
|
||||
####Version 1.12.6
|
||||
* bug fixes
|
||||
* add database exporter to local storage as backup
|
||||
|
||||
####Version 1.12.5
|
||||
* bug fixes
|
||||
|
|
|
@ -31,7 +31,7 @@ dependencies {
|
|||
compile project(':libs:MemorizingTrustManager')
|
||||
compile project(':libs:audiowife')
|
||||
|
||||
playstoreCompile 'com.google.android.gms:play-services-gcm:9.0.0'
|
||||
playstoreCompile 'com.google.android.gms:play-services-gcm:9.0.1'
|
||||
compile 'org.sufficientlysecure:openpgp-api:10.0'
|
||||
compile 'com.soundcloud.android:android-crop:1.0.1@aar'
|
||||
compile 'com.android.support:support-v13:24.0.0-beta1'
|
||||
|
@ -55,8 +55,8 @@ dependencies {
|
|||
compile 'com.github.bumptech.glide:glide:3.5.2'
|
||||
compile 'com.github.chrisbanes:PhotoView:1.2.6'
|
||||
compile 'com.github.rtoshiro.fullscreenvideoview:fullscreenvideoview:1.1.0'
|
||||
compile 'com.google.android.gms:play-services-location:9.0.0'
|
||||
compile 'com.google.android.gms:play-services-maps:9.0.0'
|
||||
compile 'com.google.android.gms:play-services-location:9.0.1'
|
||||
compile 'com.google.android.gms:play-services-maps:9.0.1'
|
||||
}
|
||||
|
||||
ext {
|
||||
|
@ -136,4 +136,4 @@ android {
|
|||
exclude 'META-INF/BCKEY.DSA'
|
||||
exclude 'META-INF/BCKEY.SF'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -93,7 +93,8 @@
|
|||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="https" />
|
||||
<data android:host="jabber.pix-art.de" />
|
||||
<data android:pathPrefix="/i/"/>
|
||||
<data android:pathPrefix="/i/" />
|
||||
<data android:pathPrefix="/j/" />
|
||||
</intent-filter>
|
||||
|
||||
</activity>
|
||||
|
|
|
@ -19,7 +19,7 @@ public class Message extends AbstractEntity {
|
|||
|
||||
public static final String TABLENAME = "messages";
|
||||
|
||||
public static final String MERGE_SEPARATOR = "\n\u0004\n";
|
||||
public static final String MERGE_SEPARATOR = "\n\u200B\n";
|
||||
|
||||
public static final int STATUS_RECEIVED = 0;
|
||||
public static final int STATUS_UNSEND = 1;
|
||||
|
|
|
@ -219,6 +219,7 @@ public class HttpUploadConnection implements Transferable {
|
|||
mXmppConnectionService.resendMessage(message, delayed);
|
||||
}
|
||||
} else {
|
||||
Log.d(Config.LOGTAG,"http upload failed because response code was "+code);
|
||||
fail();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
|
|
|
@ -96,6 +96,7 @@ import eu.siacs.conversations.utils.ExceptionHelper;
|
|||
import eu.siacs.conversations.utils.OnPhoneContactsLoadedListener;
|
||||
import eu.siacs.conversations.utils.PRNGFixes;
|
||||
import eu.siacs.conversations.utils.PhoneHelper;
|
||||
import eu.siacs.conversations.utils.ReplacingSerialSingleThreadExecutor;
|
||||
import eu.siacs.conversations.utils.SerialSingleThreadExecutor;
|
||||
import eu.siacs.conversations.utils.Xmlns;
|
||||
import eu.siacs.conversations.xml.Element;
|
||||
|
@ -123,7 +124,7 @@ import eu.siacs.conversations.xmpp.stanzas.MessagePacket;
|
|||
import eu.siacs.conversations.xmpp.stanzas.PresencePacket;
|
||||
import me.leolin.shortcutbadger.ShortcutBadger;
|
||||
|
||||
public class XmppConnectionService extends Service implements OnPhoneContactsLoadedListener {
|
||||
public class XmppConnectionService extends Service {
|
||||
|
||||
public static final String ACTION_CLEAR_NOTIFICATION = "clear_notification";
|
||||
public static final String ACTION_DISABLE_FOREGROUND = "disable_foreground";
|
||||
|
@ -135,6 +136,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
|||
public static final String ACTION_GCM_MESSAGE_RECEIVED = "gcm_message_received";
|
||||
private final SerialSingleThreadExecutor mFileAddingExecutor = new SerialSingleThreadExecutor();
|
||||
private final SerialSingleThreadExecutor mDatabaseExecutor = new SerialSingleThreadExecutor();
|
||||
private ReplacingSerialSingleThreadExecutor mContactMergerExecutor = new ReplacingSerialSingleThreadExecutor(true);
|
||||
private final IBinder mBinder = new XmppConnectionBinder();
|
||||
private final List<Conversation> conversations = new CopyOnWriteArrayList<>();
|
||||
private final IqGenerator mIqGenerator = new IqGenerator(this);
|
||||
|
@ -350,7 +352,6 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
|||
private WakeLock wakeLock;
|
||||
private PowerManager pm;
|
||||
private LruCache<String, Bitmap> mBitmapCache;
|
||||
private Thread mPhoneContactMergerThread;
|
||||
private EventReceiver mEventReceiver = new EventReceiver();
|
||||
|
||||
private boolean mRestoredFromDatabase = false;
|
||||
|
@ -1148,53 +1149,6 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
|||
sendIqPacket(account, iqPacket, mDefaultIqHandler);
|
||||
}
|
||||
|
||||
public void onPhoneContactsLoaded(final List<Bundle> phoneContacts) {
|
||||
if (mPhoneContactMergerThread != null) {
|
||||
mPhoneContactMergerThread.interrupt();
|
||||
}
|
||||
mPhoneContactMergerThread = new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Log.d(Config.LOGTAG, "start merging phone contacts with roster");
|
||||
for (Account account : accounts) {
|
||||
List<Contact> withSystemAccounts = account.getRoster().getWithSystemAccounts();
|
||||
for (Bundle phoneContact : phoneContacts) {
|
||||
if (Thread.interrupted()) {
|
||||
Log.d(Config.LOGTAG, "interrupted merging phone contacts");
|
||||
return;
|
||||
}
|
||||
Jid jid;
|
||||
try {
|
||||
jid = Jid.fromString(phoneContact.getString("jid"));
|
||||
} catch (final InvalidJidException e) {
|
||||
continue;
|
||||
}
|
||||
final Contact contact = account.getRoster().getContact(jid);
|
||||
String systemAccount = phoneContact.getInt("phoneid")
|
||||
+ "#"
|
||||
+ phoneContact.getString("lookup");
|
||||
contact.setSystemAccount(systemAccount);
|
||||
if (contact.setPhotoUri(phoneContact.getString("photouri"))) {
|
||||
getAvatarService().clear(contact);
|
||||
}
|
||||
contact.setSystemName(phoneContact.getString("displayname"));
|
||||
withSystemAccounts.remove(contact);
|
||||
}
|
||||
for (Contact contact : withSystemAccounts) {
|
||||
contact.setSystemAccount(null);
|
||||
contact.setSystemName(null);
|
||||
if (contact.setPhotoUri(null)) {
|
||||
getAvatarService().clear(contact);
|
||||
}
|
||||
}
|
||||
}
|
||||
Log.d(Config.LOGTAG, "finished merging phone contacts");
|
||||
updateAccountUi();
|
||||
}
|
||||
});
|
||||
mPhoneContactMergerThread.start();
|
||||
}
|
||||
|
||||
private void restoreFromDatabase() {
|
||||
synchronized (this.conversations) {
|
||||
final Map<String, Account> accountLookupTable = new Hashtable<>();
|
||||
|
@ -1215,7 +1169,6 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
|||
account.initAccountServices(XmppConnectionService.this); //roster needs to be loaded at this stage
|
||||
}
|
||||
getBitmapCache().evictAll();
|
||||
Looper.prepare();
|
||||
loadPhoneContacts();
|
||||
Log.d(Config.LOGTAG, "restoring messages");
|
||||
for (Conversation conversation : conversations) {
|
||||
|
@ -1239,9 +1192,47 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
|||
}
|
||||
|
||||
public void loadPhoneContacts() {
|
||||
PhoneHelper.loadPhoneContacts(getApplicationContext(),
|
||||
new CopyOnWriteArrayList<Bundle>(),
|
||||
XmppConnectionService.this);
|
||||
mContactMergerExecutor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
PhoneHelper.loadPhoneContacts(XmppConnectionService.this, new OnPhoneContactsLoadedListener() {
|
||||
@Override
|
||||
public void onPhoneContactsLoaded(List<Bundle> phoneContacts) {
|
||||
Log.d(Config.LOGTAG, "start merging phone contacts with roster");
|
||||
for (Account account : accounts) {
|
||||
List<Contact> withSystemAccounts = account.getRoster().getWithSystemAccounts();
|
||||
for (Bundle phoneContact : phoneContacts) {
|
||||
Jid jid;
|
||||
try {
|
||||
jid = Jid.fromString(phoneContact.getString("jid"));
|
||||
} catch (final InvalidJidException e) {
|
||||
continue;
|
||||
}
|
||||
final Contact contact = account.getRoster().getContact(jid);
|
||||
String systemAccount = phoneContact.getInt("phoneid")
|
||||
+ "#"
|
||||
+ phoneContact.getString("lookup");
|
||||
contact.setSystemAccount(systemAccount);
|
||||
if (contact.setPhotoUri(phoneContact.getString("photouri"))) {
|
||||
getAvatarService().clear(contact);
|
||||
}
|
||||
contact.setSystemName(phoneContact.getString("displayname"));
|
||||
withSystemAccounts.remove(contact);
|
||||
}
|
||||
for (Contact contact : withSystemAccounts) {
|
||||
contact.setSystemAccount(null);
|
||||
contact.setSystemName(null);
|
||||
if (contact.setPhotoUri(null)) {
|
||||
getAvatarService().clear(contact);
|
||||
}
|
||||
}
|
||||
}
|
||||
Log.d(Config.LOGTAG, "finished merging phone contacts");
|
||||
updateAccountUi();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public List<Conversation> getConversations() {
|
||||
|
@ -3120,6 +3111,16 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
|||
return contacts;
|
||||
}
|
||||
|
||||
public Conversation findFirstMuc(Jid jid) {
|
||||
for(Conversation conversation : getConversations()) {
|
||||
if (conversation.getJid().toBareJid().equals(jid.toBareJid())
|
||||
&& conversation.getMode() == Conversation.MODE_MULTI) {
|
||||
return conversation;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public NotificationService getNotificationService() {
|
||||
return this.mNotificationService;
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import android.os.Bundle;
|
|||
import android.os.Handler;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.text.InputType;
|
||||
import android.util.Log;
|
||||
import android.view.ContextMenu;
|
||||
import android.view.ContextMenu.ContextMenuInfo;
|
||||
import android.view.Gravity;
|
||||
|
@ -157,7 +158,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
|
|||
ConversationFragment.this.conversation.populateWithMessages(ConversationFragment.this.messageList);
|
||||
updateStatusMessages();
|
||||
messageListAdapter.notifyDataSetChanged();
|
||||
int pos = getIndexOf(uuid,messageList);
|
||||
int pos = Math.max(getIndexOf(uuid,messageList),0);
|
||||
messagesView.setSelectionFromTop(pos, pxOffset);
|
||||
messagesLoaded = true;
|
||||
if (messageLoaderToast != null) {
|
||||
|
@ -210,7 +211,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
|
|||
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
private final int KEYCHAIN_UNLOCK_NOT_REQUIRED = 0;
|
||||
|
@ -813,11 +814,13 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
|
|||
this.messagesLoaded = true;
|
||||
synchronized (this.messageList) {
|
||||
final Message first = conversation.getFirstUnreadMessage();
|
||||
final int bottom = Math.max(0, this.messageList.size() - 1);
|
||||
final int pos;
|
||||
if (first == null) {
|
||||
pos = Math.max(0,this.messageList.size() - 1);
|
||||
pos = bottom;
|
||||
} else {
|
||||
pos = getIndexOf(first.getUuid(), this.messageList);
|
||||
int i = getIndexOf(first.getUuid(), this.messageList);
|
||||
pos = i < 0 ? bottom : i;
|
||||
}
|
||||
messagesView.setSelection(pos);
|
||||
}
|
||||
|
|
|
@ -846,7 +846,16 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
|
|||
|
||||
private boolean handleJid(Invite invite) {
|
||||
List<Contact> contacts = xmppConnectionService.findContacts(invite.getJid());
|
||||
if (contacts.size() == 0) {
|
||||
if (invite.isMuc()) {
|
||||
Conversation muc = xmppConnectionService.findFirstMuc(invite.getJid());
|
||||
if (muc != null) {
|
||||
switchToConversation(muc);
|
||||
return true;
|
||||
} else {
|
||||
showJoinConferenceDialog(invite.getJid().toBareJid().toString());
|
||||
return false;
|
||||
}
|
||||
} else if (contacts.size() == 0) {
|
||||
showCreateContactDialog(invite.getJid().toString(),invite.getFingerprint());
|
||||
return false;
|
||||
} else if (contacts.size() == 1) {
|
||||
|
@ -1020,13 +1029,13 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
|
|||
|
||||
boolean invite() {
|
||||
if (jid != null) {
|
||||
if (muc) {
|
||||
showJoinConferenceDialog(jid);
|
||||
} else {
|
||||
return handleJid(this);
|
||||
}
|
||||
return handleJid(this);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isMuc() {
|
||||
return muc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,12 +13,14 @@ import android.os.Bundle;
|
|||
import android.provider.ContactsContract;
|
||||
import android.provider.ContactsContract.Profile;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.RejectedExecutionException;
|
||||
|
||||
public class PhoneHelper {
|
||||
|
||||
public static void loadPhoneContacts(Context context, final List<Bundle> phoneContacts, final OnPhoneContactsLoadedListener listener) {
|
||||
public static void loadPhoneContacts(Context context, final OnPhoneContactsLoadedListener listener) {
|
||||
final List<Bundle> phoneContacts = new ArrayList<>();
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
|
||||
&& context.checkSelfPermission(Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
|
||||
listener.onPhoneContactsLoaded(phoneContacts);
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
package eu.siacs.conversations.utils;
|
||||
|
||||
public class ReplacingSerialSingleThreadExecutor extends SerialSingleThreadExecutor {
|
||||
|
||||
public ReplacingSerialSingleThreadExecutor(boolean prepareLooper) {
|
||||
super(prepareLooper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void execute(final Runnable r) {
|
||||
tasks.clear();
|
||||
super.execute(r);
|
||||
}
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
package eu.siacs.conversations.utils;
|
||||
|
||||
import android.os.Looper;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.Executor;
|
||||
|
@ -8,9 +10,24 @@ import java.util.concurrent.Executors;
|
|||
public class SerialSingleThreadExecutor implements Executor {
|
||||
|
||||
final Executor executor = Executors.newSingleThreadExecutor();
|
||||
final Queue<Runnable> tasks = new ArrayDeque();
|
||||
protected final Queue<Runnable> tasks = new ArrayDeque();
|
||||
Runnable active;
|
||||
|
||||
public SerialSingleThreadExecutor() {
|
||||
this(false);
|
||||
}
|
||||
|
||||
public SerialSingleThreadExecutor(boolean prepareLooper) {
|
||||
if (prepareLooper) {
|
||||
execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Looper.prepare();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void execute(final Runnable r) {
|
||||
tasks.offer(new Runnable() {
|
||||
public void run() {
|
||||
|
|
|
@ -7,6 +7,7 @@ public class XmlHelper {
|
|||
content = content.replace(">", ">");
|
||||
content = content.replace("\"", """);
|
||||
content = content.replace("'", "'");
|
||||
content = content.replaceAll("\\p{Cc}", "");
|
||||
return content;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,6 +47,7 @@ public class XmppUri {
|
|||
// sample : https://conversations.im/i/foo/bar.com
|
||||
jid = segments.get(1) + "@" + segments.get(2);
|
||||
}
|
||||
muc = segments.size() > 1 && "j".equalsIgnoreCase(segments.get(0));
|
||||
} else if ("xmpp".equalsIgnoreCase(scheme)) {
|
||||
// sample: xmpp:foo@bar.com
|
||||
muc = "join".equalsIgnoreCase(uri.getQuery());
|
||||
|
|
Reference in a new issue