From 4ddaa45ee3dd1a346da254f2ca9b72c933dc2292 Mon Sep 17 00:00:00 2001 From: Christian Schneppe Date: Sun, 29 Apr 2018 14:22:34 +0200 Subject: catch dead object exceptions when acquiring wake locks --- .../messenger/http/HttpDownloadConnection.java | 9 +- .../messenger/http/HttpUploadConnection.java | 5 +- .../messenger/services/ExportLogsService.java | 11 +- .../messenger/services/XmppConnectionService.java | 10 +- .../de/pixart/messenger/ui/UpdaterActivity.java | 7 +- .../de/pixart/messenger/utils/WakeLockHelper.java | 59 +++++++ .../xmpp/jingle/JingleSocks5Transport.java | 194 ++++++++++----------- 7 files changed, 166 insertions(+), 129 deletions(-) create mode 100644 src/main/java/de/pixart/messenger/utils/WakeLockHelper.java (limited to 'src/main/java/de/pixart/messenger') diff --git a/src/main/java/de/pixart/messenger/http/HttpDownloadConnection.java b/src/main/java/de/pixart/messenger/http/HttpDownloadConnection.java index dee5bcb05..fd2c054c3 100644 --- a/src/main/java/de/pixart/messenger/http/HttpDownloadConnection.java +++ b/src/main/java/de/pixart/messenger/http/HttpDownloadConnection.java @@ -29,6 +29,7 @@ import de.pixart.messenger.services.AbstractConnectionManager; import de.pixart.messenger.services.XmppConnectionService; import de.pixart.messenger.utils.CryptoHelper; import de.pixart.messenger.utils.FileWriterException; +import de.pixart.messenger.utils.WakeLockHelper; public class HttpDownloadConnection implements Transferable { @@ -225,7 +226,7 @@ public class HttpDownloadConnection implements Transferable { private long retrieveFileSize() throws IOException { PowerManager.WakeLock wakeLock = mHttpConnectionManager.createWakeLock("http_download_filesize" + message.getUuid()); try { - wakeLock.acquire(); + WakeLockHelper.acquire(wakeLock); Log.d(Config.LOGTAG, "retrieve file size. interactive:" + String.valueOf(interactive)); changeStatus(STATUS_CHECKING); HttpURLConnection connection; @@ -257,7 +258,7 @@ public class HttpDownloadConnection implements Transferable { } catch (NumberFormatException e) { throw new IOException(); } finally { - wakeLock.release(); + WakeLockHelper.release(wakeLock); } } @@ -298,7 +299,7 @@ public class HttpDownloadConnection implements Transferable { HttpURLConnection connection = null; PowerManager.WakeLock wakeLock = mHttpConnectionManager.createWakeLock("http_download_" + message.getUuid()); try { - wakeLock.acquire(); + WakeLockHelper.acquire(wakeLock); if (mUseTor) { connection = (HttpURLConnection) mUrl.openConnection(mHttpConnectionManager.getProxy()); } else { @@ -376,7 +377,7 @@ public class HttpDownloadConnection implements Transferable { if (connection != null) { connection.disconnect(); } - wakeLock.release(); + WakeLockHelper.release(wakeLock); } } diff --git a/src/main/java/de/pixart/messenger/http/HttpUploadConnection.java b/src/main/java/de/pixart/messenger/http/HttpUploadConnection.java index 7bdfd4db8..cd73d6895 100644 --- a/src/main/java/de/pixart/messenger/http/HttpUploadConnection.java +++ b/src/main/java/de/pixart/messenger/http/HttpUploadConnection.java @@ -28,6 +28,7 @@ import de.pixart.messenger.services.AbstractConnectionManager; import de.pixart.messenger.services.XmppConnectionService; import de.pixart.messenger.utils.CryptoHelper; import de.pixart.messenger.utils.Namespace; +import de.pixart.messenger.utils.WakeLockHelper; import de.pixart.messenger.xml.Element; import de.pixart.messenger.xmpp.stanzas.IqPacket; import rocks.xmpp.addr.Jid; @@ -237,9 +238,7 @@ public class HttpUploadConnection implements Transferable { if (connection != null) { connection.disconnect(); } - if (wakeLock.isHeld()) { - wakeLock.release(); - } + WakeLockHelper.release(wakeLock); } } } diff --git a/src/main/java/de/pixart/messenger/services/ExportLogsService.java b/src/main/java/de/pixart/messenger/services/ExportLogsService.java index 12a211e54..17cb11562 100644 --- a/src/main/java/de/pixart/messenger/services/ExportLogsService.java +++ b/src/main/java/de/pixart/messenger/services/ExportLogsService.java @@ -36,6 +36,7 @@ import de.pixart.messenger.entities.Message; import de.pixart.messenger.persistance.DatabaseBackend; import de.pixart.messenger.persistance.FileBackend; import de.pixart.messenger.utils.EncryptDecryptFile; +import de.pixart.messenger.utils.WakeLockHelper; import rocks.xmpp.addr.Jid; import static de.pixart.messenger.ui.SettingsActivity.USE_MULTI_ACCOUNTS; @@ -72,13 +73,7 @@ public class ExportLogsService extends Service { public void run() { export(); stopForeground(true); - if (wakeLock.isHeld()) { - try { - wakeLock.release(); - } catch (final RuntimeException ignored) { - //ignored - } - } + WakeLockHelper.release(wakeLock); running.set(false); stopSelf(); } @@ -88,7 +83,7 @@ public class ExportLogsService extends Service { } private void export() { - wakeLock.acquire(); + WakeLockHelper.acquire(wakeLock); List conversations = mDatabaseBackend.getConversations(Conversation.STATUS_AVAILABLE); conversations.addAll(mDatabaseBackend.getConversations(Conversation.STATUS_ARCHIVED)); NotificationManager mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); diff --git a/src/main/java/de/pixart/messenger/services/XmppConnectionService.java b/src/main/java/de/pixart/messenger/services/XmppConnectionService.java index ef98b6aa6..9fc322646 100644 --- a/src/main/java/de/pixart/messenger/services/XmppConnectionService.java +++ b/src/main/java/de/pixart/messenger/services/XmppConnectionService.java @@ -122,6 +122,7 @@ import de.pixart.messenger.utils.ReplacingSerialSingleThreadExecutor; import de.pixart.messenger.utils.ReplacingTaskManager; import de.pixart.messenger.utils.Resolver; import de.pixart.messenger.utils.SerialSingleThreadExecutor; +import de.pixart.messenger.utils.WakeLockHelper; import de.pixart.messenger.utils.XmppUri; import de.pixart.messenger.xml.Element; import de.pixart.messenger.xmpp.OnBindListener; @@ -684,7 +685,7 @@ public class XmppConnectionService extends Service { } } synchronized (this) { - this.wakeLock.acquire(); + WakeLockHelper.acquire(wakeLock); boolean pingNow = ConnectivityManager.CONNECTIVITY_ACTION.equals(action); HashSet pingCandidates = new HashSet<>(); for (Account account : accounts) { @@ -708,12 +709,7 @@ public class XmppConnectionService extends Service { scheduleWakeUpCall(lowTimeout ? Config.LOW_PING_TIMEOUT : Config.PING_TIMEOUT, account.getUuid().hashCode()); } } - if (wakeLock.isHeld()) { - try { - wakeLock.release(); - } catch (final RuntimeException ignored) { - } - } + WakeLockHelper.release(wakeLock); } if (SystemClock.elapsedRealtime() - mLastExpiryRun.get() >= Config.EXPIRY_INTERVAL) { expireOldMessages(); diff --git a/src/main/java/de/pixart/messenger/ui/UpdaterActivity.java b/src/main/java/de/pixart/messenger/ui/UpdaterActivity.java index f9b5ef164..562b75313 100644 --- a/src/main/java/de/pixart/messenger/ui/UpdaterActivity.java +++ b/src/main/java/de/pixart/messenger/ui/UpdaterActivity.java @@ -33,6 +33,7 @@ import java.util.List; import de.pixart.messenger.Config; import de.pixart.messenger.R; import de.pixart.messenger.persistance.FileBackend; +import de.pixart.messenger.utils.WakeLockHelper; public class UpdaterActivity extends XmppActivity { static final private String FileName = "update.apk"; @@ -196,7 +197,7 @@ public class UpdaterActivity extends XmppActivity { PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); if (pm != null) { mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, getClass().getName()); - mWakeLock.acquire(); + WakeLockHelper.acquire(mWakeLock); } mProgressDialog.show(); } @@ -273,9 +274,7 @@ public class UpdaterActivity extends XmppActivity { @Override protected void onPostExecute(String result) { - if (mWakeLock.isHeld()) { - mWakeLock.release(); - } + WakeLockHelper.release(mWakeLock); mProgressDialog.dismiss(); if (result != null) { Toast.makeText(getApplicationContext(), getString(R.string.failed), Toast.LENGTH_LONG).show(); diff --git a/src/main/java/de/pixart/messenger/utils/WakeLockHelper.java b/src/main/java/de/pixart/messenger/utils/WakeLockHelper.java new file mode 100644 index 000000000..21243e684 --- /dev/null +++ b/src/main/java/de/pixart/messenger/utils/WakeLockHelper.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2018, Daniel Gultsch All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package de.pixart.messenger.utils; + +import android.os.PowerManager; +import android.util.Log; + +import de.pixart.messenger.Config; + +public class WakeLockHelper { + + public static void acquire(PowerManager.WakeLock wakeLock) { + try { + wakeLock.acquire(2000); + } catch (RuntimeException e) { + Log.d(Config.LOGTAG, "unable to acquire wake lock", e); + } + } + + public static void release(PowerManager.WakeLock wakeLock) { + if (wakeLock == null) { + return; + } + try { + if (wakeLock.isHeld()) { + wakeLock.release(); + } + } catch (RuntimeException e) { + Log.d(Config.LOGTAG, "unable to release wake lock", e); + } + } +} \ No newline at end of file diff --git a/src/main/java/de/pixart/messenger/xmpp/jingle/JingleSocks5Transport.java b/src/main/java/de/pixart/messenger/xmpp/jingle/JingleSocks5Transport.java index 946849858..42beee9d6 100644 --- a/src/main/java/de/pixart/messenger/xmpp/jingle/JingleSocks5Transport.java +++ b/src/main/java/de/pixart/messenger/xmpp/jingle/JingleSocks5Transport.java @@ -17,6 +17,7 @@ import de.pixart.messenger.entities.DownloadableFile; import de.pixart.messenger.persistance.FileBackend; import de.pixart.messenger.utils.CryptoHelper; import de.pixart.messenger.utils.SocksSocketFactory; +import de.pixart.messenger.utils.WakeLockHelper; import de.pixart.messenger.xmpp.jingle.stanzas.Content; public class JingleSocks5Transport extends JingleTransport { @@ -27,10 +28,9 @@ public class JingleSocks5Transport extends JingleTransport { private InputStream inputStream; private boolean isEstablished = false; private boolean activated = false; - protected Socket socket; + private Socket socket; - public JingleSocks5Transport(JingleConnection jingleConnection, - JingleCandidate candidate) { + JingleSocks5Transport(JingleConnection jingleConnection, JingleCandidate candidate) { this.candidate = candidate; this.connection = jingleConnection; try { @@ -58,124 +58,112 @@ public class JingleSocks5Transport extends JingleTransport { } public void connect(final OnTransportConnected callback) { - new Thread(new Runnable() { - - @Override - public void run() { - try { - final boolean useTor = connection.getAccount().isOnion() || connection.getConnectionManager().getXmppConnectionService().useTorToConnect(); - if (useTor) { - socket = SocksSocketFactory.createSocketOverTor(candidate.getHost(), candidate.getPort()); - } else { - socket = new Socket(); - SocketAddress address = new InetSocketAddress(candidate.getHost(), candidate.getPort()); - socket.connect(address, Config.SOCKET_TIMEOUT * 1000); - } - inputStream = socket.getInputStream(); - outputStream = socket.getOutputStream(); - SocksSocketFactory.createSocksConnection(socket, destination, 0); - isEstablished = true; - callback.established(); - } catch (IOException e) { - callback.failed(); + new Thread(() -> { + try { + final boolean useTor = connection.getAccount().isOnion() || connection.getConnectionManager().getXmppConnectionService().useTorToConnect(); + if (useTor) { + socket = SocksSocketFactory.createSocketOverTor(candidate.getHost(), candidate.getPort()); + } else { + socket = new Socket(); + SocketAddress address = new InetSocketAddress(candidate.getHost(), candidate.getPort()); + socket.connect(address, Config.SOCKET_TIMEOUT * 1000); } + inputStream = socket.getInputStream(); + outputStream = socket.getOutputStream(); + SocksSocketFactory.createSocksConnection(socket, destination, 0); + isEstablished = true; + callback.established(); + } catch (IOException e) { + callback.failed(); } }).start(); } public void send(final DownloadableFile file, final OnFileTransmissionStatusChanged callback) { - new Thread(new Runnable() { - - @Override - public void run() { - InputStream fileInputStream = null; - final PowerManager.WakeLock wakeLock = connection.getConnectionManager().createWakeLock("jingle_send_" + connection.getSessionId()); - try { - wakeLock.acquire(); - MessageDigest digest = MessageDigest.getInstance("SHA-1"); - digest.reset(); - fileInputStream = connection.getFileInputStream(); - if (fileInputStream == null) { - Log.d(Config.LOGTAG, connection.getAccount().getJid().asBareJid() + ": could not create input stream"); - callback.onFileTransferAborted(); - return; - } - long size = file.getExpectedSize(); - long transmitted = 0; - int count; - byte[] buffer = new byte[8192]; - while ((count = fileInputStream.read(buffer)) > 0) { - outputStream.write(buffer, 0, count); - digest.update(buffer, 0, count); - transmitted += count; - connection.updateProgress((int) ((((double) transmitted) / size) * 100)); - } - outputStream.flush(); - file.setSha1Sum(digest.digest()); - if (callback != null) { - callback.onFileTransmitted(file); - } - } catch (Exception e) { - Log.d(Config.LOGTAG, connection.getAccount().getJid().asBareJid() + ": " + e.getMessage()); + new Thread(() -> { + InputStream fileInputStream = null; + final PowerManager.WakeLock wakeLock = connection.getConnectionManager().createWakeLock("jingle_send_" + connection.getSessionId()); + try { + WakeLockHelper.acquire(wakeLock); + MessageDigest digest = MessageDigest.getInstance("SHA-1"); + digest.reset(); + fileInputStream = connection.getFileInputStream(); + if (fileInputStream == null) { + Log.d(Config.LOGTAG, connection.getAccount().getJid().asBareJid() + ": could not create input stream"); callback.onFileTransferAborted(); - } finally { - FileBackend.close(fileInputStream); - wakeLock.release(); + return; + } + long size = file.getExpectedSize(); + long transmitted = 0; + int count; + byte[] buffer = new byte[8192]; + while ((count = fileInputStream.read(buffer)) > 0) { + outputStream.write(buffer, 0, count); + digest.update(buffer, 0, count); + transmitted += count; + connection.updateProgress((int) ((((double) transmitted) / size) * 100)); } + outputStream.flush(); + file.setSha1Sum(digest.digest()); + if (callback != null) { + callback.onFileTransmitted(file); + } + } catch (Exception e) { + Log.d(Config.LOGTAG, connection.getAccount().getJid().asBareJid() + ": " + e.getMessage()); + callback.onFileTransferAborted(); + } finally { + FileBackend.close(fileInputStream); + WakeLockHelper.release(wakeLock); } }).start(); } public void receive(final DownloadableFile file, final OnFileTransmissionStatusChanged callback) { - new Thread(new Runnable() { - - @Override - public void run() { - OutputStream fileOutputStream = null; - final PowerManager.WakeLock wakeLock = connection.getConnectionManager().createWakeLock("jingle_receive_" + connection.getSessionId()); - try { - wakeLock.acquire(); - MessageDigest digest = MessageDigest.getInstance("SHA-1"); - digest.reset(); - //inputStream.skip(45); - socket.setSoTimeout(30000); - fileOutputStream = connection.getFileOutputStream(); - if (fileOutputStream == null) { + new Thread(() -> { + OutputStream fileOutputStream = null; + final PowerManager.WakeLock wakeLock = connection.getConnectionManager().createWakeLock("jingle_receive_" + connection.getSessionId()); + try { + WakeLockHelper.acquire(wakeLock); + MessageDigest digest = MessageDigest.getInstance("SHA-1"); + digest.reset(); + //inputStream.skip(45); + socket.setSoTimeout(30000); + fileOutputStream = connection.getFileOutputStream(); + if (fileOutputStream == null) { + callback.onFileTransferAborted(); + Log.d(Config.LOGTAG, connection.getAccount().getJid().asBareJid() + ": could not create output stream"); + return; + } + double size = file.getExpectedSize(); + long remainingSize = file.getExpectedSize(); + byte[] buffer = new byte[8192]; + int count; + while (remainingSize > 0) { + count = inputStream.read(buffer); + if (count == -1) { callback.onFileTransferAborted(); - Log.d(Config.LOGTAG, connection.getAccount().getJid().asBareJid() + ": could not create output stream"); + Log.d(Config.LOGTAG, connection.getAccount().getJid().asBareJid() + ": file ended prematurely with " + remainingSize + " bytes remaining"); return; + } else { + fileOutputStream.write(buffer, 0, count); + digest.update(buffer, 0, count); + remainingSize -= count; } - double size = file.getExpectedSize(); - long remainingSize = file.getExpectedSize(); - byte[] buffer = new byte[8192]; - int count; - while (remainingSize > 0) { - count = inputStream.read(buffer); - if (count == -1) { - callback.onFileTransferAborted(); - Log.d(Config.LOGTAG, connection.getAccount().getJid().asBareJid() + ": file ended prematurely with " + remainingSize + " bytes remaining"); - return; - } else { - fileOutputStream.write(buffer, 0, count); - digest.update(buffer, 0, count); - remainingSize -= count; - } - connection.updateProgress((int) (((size - remainingSize) / size) * 100)); - } - fileOutputStream.flush(); - fileOutputStream.close(); - file.setSha1Sum(digest.digest()); - callback.onFileTransmitted(file); - } catch (Exception e) { - Log.d(Config.LOGTAG, connection.getAccount().getJid().asBareJid() + ": " + e.getMessage()); - callback.onFileTransferAborted(); - } finally { - wakeLock.release(); - FileBackend.close(fileOutputStream); - FileBackend.close(inputStream); + connection.updateProgress((int) (((size - remainingSize) / size) * 100)); } + fileOutputStream.flush(); + fileOutputStream.close(); + file.setSha1Sum(digest.digest()); + callback.onFileTransmitted(file); + } catch (Exception e) { + Log.d(Config.LOGTAG, connection.getAccount().getJid().asBareJid() + ": " + e.getMessage()); + callback.onFileTransferAborted(); + } finally { + WakeLockHelper.release(wakeLock); + FileBackend.close(fileOutputStream); + FileBackend.close(inputStream); } }).start(); } @@ -205,4 +193,4 @@ public class JingleSocks5Transport extends JingleTransport { public void setActivated(boolean activated) { this.activated = activated; } -} +} \ No newline at end of file -- cgit v1.2.3