2018-12-24 12:27:45 +00:00
package eu.faircode.email ;
2018-12-31 08:04:33 +00:00
/ *
This file is part of FairEmail .
FairEmail is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
FairEmail is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with FairEmail . If not , see < http : //www.gnu.org/licenses/>.
2022-01-01 08:46:36 +00:00
Copyright 2018 - 2022 by Marcel Bokhorst ( M66B )
2018-12-31 08:04:33 +00:00
* /
2019-07-22 07:18:03 +00:00
import android.app.ActivityManager ;
2020-07-11 13:09:32 +00:00
import android.app.ApplicationExitInfo ;
2019-12-06 07:50:46 +00:00
import android.app.Dialog ;
2021-09-27 14:57:17 +00:00
import android.app.Notification ;
2020-10-09 12:29:30 +00:00
import android.app.NotificationChannel ;
import android.app.NotificationManager ;
2019-05-12 17:14:34 +00:00
import android.app.usage.UsageStatsManager ;
2021-08-23 16:03:34 +00:00
import android.content.ContentResolver ;
2019-05-12 17:14:34 +00:00
import android.content.Context ;
2019-12-06 07:50:46 +00:00
import android.content.DialogInterface ;
2019-01-25 14:40:46 +00:00
import android.content.Intent ;
2019-05-12 17:14:34 +00:00
import android.content.SharedPreferences ;
2021-07-17 11:49:08 +00:00
import android.content.pm.ApplicationInfo ;
2021-02-10 17:24:45 +00:00
import android.content.pm.PackageInfo ;
import android.content.pm.PackageManager ;
2019-05-12 17:14:34 +00:00
import android.content.res.Configuration ;
2021-01-16 12:13:44 +00:00
import android.content.res.Resources ;
2020-06-16 05:29:55 +00:00
import android.database.sqlite.SQLiteFullException ;
2019-05-12 17:14:34 +00:00
import android.graphics.Point ;
import android.net.ConnectivityManager ;
2020-10-27 14:35:28 +00:00
import android.net.LinkProperties ;
2019-05-12 17:14:34 +00:00
import android.net.Network ;
import android.net.NetworkCapabilities ;
2019-10-22 06:55:27 +00:00
import android.net.NetworkInfo ;
2019-10-29 06:57:39 +00:00
import android.os.BadParcelableException ;
2019-05-12 17:14:34 +00:00
import android.os.Build ;
2019-01-25 14:40:46 +00:00
import android.os.Bundle ;
2019-10-12 11:09:14 +00:00
import android.os.DeadObjectException ;
2020-12-13 11:06:30 +00:00
import android.os.DeadSystemException ;
2019-07-22 07:18:03 +00:00
import android.os.Debug ;
2021-09-07 15:08:00 +00:00
import android.os.IBinder ;
2021-07-27 16:32:10 +00:00
import android.os.OperationCanceledException ;
2019-08-12 11:17:55 +00:00
import android.os.RemoteException ;
2020-04-20 06:07:41 +00:00
import android.os.TransactionTooLargeException ;
2021-08-23 16:03:34 +00:00
import android.provider.Settings ;
2019-01-25 14:40:46 +00:00
import android.text.TextUtils ;
2022-01-03 18:23:36 +00:00
import android.util.Printer ;
2019-05-12 17:14:34 +00:00
import android.view.Display ;
2020-09-10 16:37:39 +00:00
import android.view.InflateException ;
2021-10-17 05:26:38 +00:00
import android.view.LayoutInflater ;
import android.view.View ;
2019-05-12 17:14:34 +00:00
import android.view.WindowManager ;
2021-10-17 05:26:38 +00:00
import android.widget.TextView ;
2019-12-06 07:50:46 +00:00
import android.widget.Toast ;
2019-05-12 17:14:34 +00:00
2019-08-12 11:17:55 +00:00
import androidx.annotation.NonNull ;
2019-12-06 07:50:46 +00:00
import androidx.annotation.Nullable ;
2020-10-09 12:29:30 +00:00
import androidx.annotation.RequiresApi ;
2019-12-06 07:50:46 +00:00
import androidx.appcompat.app.AlertDialog ;
import androidx.fragment.app.FragmentManager ;
2019-05-12 17:14:34 +00:00
import androidx.preference.PreferenceManager ;
2019-01-25 14:40:46 +00:00
2019-08-12 11:07:14 +00:00
import com.bugsnag.android.BreadcrumbType ;
2019-05-10 06:53:45 +00:00
import com.bugsnag.android.Bugsnag ;
2019-08-12 11:17:55 +00:00
import com.bugsnag.android.Client ;
2020-05-22 17:50:46 +00:00
import com.bugsnag.android.ErrorTypes ;
import com.bugsnag.android.Event ;
import com.bugsnag.android.OnErrorCallback ;
import com.bugsnag.android.OnSessionCallback ;
import com.bugsnag.android.Session ;
2019-05-10 06:53:45 +00:00
import com.bugsnag.android.Severity ;
2019-12-06 07:50:46 +00:00
import com.sun.mail.iap.BadCommandException ;
import com.sun.mail.iap.ConnectionException ;
2019-08-12 11:17:55 +00:00
import com.sun.mail.iap.ProtocolException ;
2019-12-06 07:50:46 +00:00
import com.sun.mail.util.FolderClosedIOException ;
2019-05-10 06:53:45 +00:00
2019-05-12 17:14:34 +00:00
import org.json.JSONException ;
import org.json.JSONObject ;
import java.io.BufferedOutputStream ;
import java.io.BufferedReader ;
import java.io.File ;
2019-08-12 11:17:55 +00:00
import java.io.FileNotFoundException ;
2019-05-12 17:14:34 +00:00
import java.io.FileOutputStream ;
2019-08-12 11:17:55 +00:00
import java.io.FileWriter ;
2019-05-12 17:14:34 +00:00
import java.io.IOException ;
import java.io.InputStreamReader ;
import java.io.OutputStream ;
import java.io.UnsupportedEncodingException ;
2019-04-24 16:39:32 +00:00
import java.lang.reflect.Array ;
2021-06-20 18:40:08 +00:00
import java.net.InetAddress ;
import java.net.InterfaceAddress ;
import java.net.NetworkInterface ;
2019-12-06 08:00:31 +00:00
import java.net.SocketException ;
2020-07-10 08:07:53 +00:00
import java.nio.charset.StandardCharsets ;
2021-09-07 18:05:25 +00:00
import java.security.Provider ;
import java.security.Security ;
2020-02-07 08:58:33 +00:00
import java.security.cert.CertPathValidatorException ;
2019-05-12 17:14:34 +00:00
import java.text.DateFormat ;
2021-06-17 19:25:51 +00:00
import java.text.DateFormatSymbols ;
2020-08-30 11:35:21 +00:00
import java.text.SimpleDateFormat ;
2019-08-12 11:17:55 +00:00
import java.util.ArrayList ;
2019-09-24 15:05:33 +00:00
import java.util.Arrays ;
2020-04-03 06:59:22 +00:00
import java.util.Collections ;
2019-05-12 17:14:34 +00:00
import java.util.Date ;
2021-06-20 18:40:08 +00:00
import java.util.Enumeration ;
2020-05-22 17:50:46 +00:00
import java.util.HashMap ;
import java.util.HashSet ;
2019-05-12 17:14:34 +00:00
import java.util.List ;
2021-01-16 12:13:44 +00:00
import java.util.Locale ;
2019-05-12 17:14:34 +00:00
import java.util.Map ;
2019-01-25 14:40:46 +00:00
import java.util.Set ;
2019-08-12 11:17:55 +00:00
import java.util.UUID ;
import java.util.concurrent.TimeoutException ;
2019-01-25 14:40:46 +00:00
2019-05-12 17:14:34 +00:00
import javax.mail.Address ;
2019-12-06 08:00:31 +00:00
import javax.mail.AuthenticationFailedException ;
2019-12-06 07:50:46 +00:00
import javax.mail.FolderClosedException ;
import javax.mail.MessageRemovedException ;
2019-08-12 11:17:55 +00:00
import javax.mail.MessagingException ;
2019-06-29 06:52:15 +00:00
import javax.mail.Part ;
2019-12-09 07:37:08 +00:00
import javax.mail.StoreClosedException ;
2019-05-12 17:14:34 +00:00
import javax.mail.internet.InternetAddress ;
2020-07-10 09:08:12 +00:00
import javax.mail.internet.MimeUtility ;
2020-02-07 08:58:33 +00:00
import javax.net.ssl.SSLHandshakeException ;
2020-02-02 14:24:24 +00:00
import javax.net.ssl.SSLPeerUnverifiedException ;
2019-05-12 17:14:34 +00:00
2020-05-08 18:14:34 +00:00
import io.requery.android.database.CursorWindowAllocationException ;
2018-12-24 12:27:45 +00:00
public class Log {
2021-10-22 13:04:16 +00:00
private static Context ctx ;
2021-02-27 16:45:08 +00:00
private static int level = android . util . Log . INFO ;
2019-08-23 13:22:35 +00:00
private static final int MAX_CRASH_REPORTS = 5 ;
2019-08-12 11:33:39 +00:00
private static final String TAG = " fairemail " ;
2018-12-24 12:27:45 +00:00
2021-12-01 18:33:29 +00:00
static final String TOKEN_REFRESH_REQUIRED =
" Token refresh required. Is there a VPN based app running? " ;
2021-02-27 16:45:08 +00:00
public static void setLevel ( Context context ) {
SharedPreferences prefs = PreferenceManager . getDefaultSharedPreferences ( context ) ;
boolean debug = prefs . getBoolean ( " debug " , false ) ;
if ( debug )
level = android . util . Log . DEBUG ;
else
level = prefs . getInt ( " log_level " , getDefaultLogLevel ( ) ) ;
android . util . Log . d ( TAG , " Log level= " + level ) ;
}
public static int getDefaultLogLevel ( ) {
return ( BuildConfig . DEBUG ? android . util . Log . INFO : android . util . Log . WARN ) ;
2020-04-05 12:10:42 +00:00
}
2019-08-11 13:49:14 +00:00
public static int d ( String msg ) {
2021-02-27 16:45:08 +00:00
if ( level < = android . util . Log . DEBUG )
2019-08-11 13:49:14 +00:00
return android . util . Log . d ( TAG , msg ) ;
else
return 0 ;
}
2021-02-27 16:45:08 +00:00
public static int d ( String tag , String msg ) {
if ( level < = android . util . Log . DEBUG )
return android . util . Log . d ( tag , msg ) ;
else
return 0 ;
}
2018-12-24 12:27:45 +00:00
public static int i ( String msg ) {
2021-12-10 20:18:03 +00:00
if ( level < = android . util . Log . INFO | | BuildConfig . DEBUG )
2018-12-28 09:56:40 +00:00
return android . util . Log . i ( TAG , msg ) ;
else
return 0 ;
2018-12-24 12:27:45 +00:00
}
2021-02-27 16:45:08 +00:00
public static int i ( String tag , String msg ) {
2021-12-10 20:18:03 +00:00
if ( level < = android . util . Log . INFO | | BuildConfig . DEBUG )
2021-02-27 16:45:08 +00:00
return android . util . Log . i ( tag , msg ) ;
else
return 0 ;
}
2018-12-24 12:27:45 +00:00
public static int w ( String msg ) {
return android . util . Log . w ( TAG , msg ) ;
}
public static int e ( String msg ) {
2019-12-14 16:01:27 +00:00
if ( BuildConfig . BETA_RELEASE )
try {
2020-05-22 17:50:46 +00:00
Throwable ex = new Throwable ( msg ) ;
List < StackTraceElement > ss = new ArrayList < > ( Arrays . asList ( ex . getStackTrace ( ) ) ) ;
2019-12-14 16:01:27 +00:00
ss . remove ( 0 ) ;
2020-05-22 17:50:46 +00:00
ex . setStackTrace ( ss . toArray ( new StackTraceElement [ 0 ] ) ) ;
Bugsnag . notify ( ex , new OnErrorCallback ( ) {
2019-12-14 16:01:27 +00:00
@Override
2020-05-22 17:50:46 +00:00
public boolean onError ( @NonNull Event event ) {
event . setSeverity ( Severity . ERROR ) ;
return true ;
2019-12-14 16:01:27 +00:00
}
} ) ;
} catch ( Throwable ex ) {
ex . printStackTrace ( ) ;
}
2018-12-24 12:27:45 +00:00
return android . util . Log . e ( TAG , msg ) ;
}
2019-05-14 08:07:05 +00:00
public static int i ( Throwable ex ) {
2019-06-09 13:51:24 +00:00
return android . util . Log . i ( TAG , ex + " \ n " + android . util . Log . getStackTraceString ( ex ) ) ;
2019-05-14 08:07:05 +00:00
}
2018-12-24 12:27:45 +00:00
public static int w ( Throwable ex ) {
2019-05-15 19:20:18 +00:00
if ( BuildConfig . BETA_RELEASE )
2019-12-14 16:01:27 +00:00
try {
2021-07-30 19:41:53 +00:00
final StackTraceElement [ ] ste = new Throwable ( ) . getStackTrace ( ) ;
2020-05-22 17:50:46 +00:00
Bugsnag . notify ( ex , new OnErrorCallback ( ) {
@Override
public boolean onError ( @NonNull Event event ) {
event . setSeverity ( Severity . INFO ) ;
2021-07-30 19:41:53 +00:00
if ( ste . length > 1 )
event . addMetadata ( " extra " , " caller " , ste [ 1 ] . toString ( ) ) ;
2020-05-22 17:50:46 +00:00
return true ;
}
} ) ;
2019-12-14 16:01:27 +00:00
} catch ( Throwable ex1 ) {
ex1 . printStackTrace ( ) ;
}
2018-12-24 12:27:45 +00:00
return android . util . Log . w ( TAG , ex + " \ n " + android . util . Log . getStackTraceString ( ex ) ) ;
}
public static int e ( Throwable ex ) {
2019-05-15 19:20:18 +00:00
if ( BuildConfig . BETA_RELEASE )
2019-12-14 16:01:27 +00:00
try {
2021-07-30 19:41:53 +00:00
final StackTraceElement [ ] ste = new Throwable ( ) . getStackTrace ( ) ;
2020-05-22 17:50:46 +00:00
Bugsnag . notify ( ex , new OnErrorCallback ( ) {
@Override
public boolean onError ( @NonNull Event event ) {
event . setSeverity ( Severity . WARNING ) ;
2021-07-30 19:41:53 +00:00
if ( ste . length > 1 )
event . addMetadata ( " extra " , " caller " , ste [ 1 ] . toString ( ) ) ;
2020-05-22 17:50:46 +00:00
return true ;
}
} ) ;
2019-12-14 16:01:27 +00:00
} catch ( Throwable ex1 ) {
ex1 . printStackTrace ( ) ;
}
2018-12-24 12:27:45 +00:00
return android . util . Log . e ( TAG , ex + " \ n " + android . util . Log . getStackTraceString ( ex ) ) ;
}
2020-04-15 11:42:53 +00:00
public static int i ( String prefix , Throwable ex ) {
return android . util . Log . i ( TAG , prefix + " " + ex + " \ n " + android . util . Log . getStackTraceString ( ex ) ) ;
}
2018-12-24 12:27:45 +00:00
public static int w ( String prefix , Throwable ex ) {
2019-05-15 19:20:18 +00:00
if ( BuildConfig . BETA_RELEASE )
2019-12-14 16:01:27 +00:00
try {
2020-05-22 17:50:46 +00:00
Bugsnag . notify ( ex , new OnErrorCallback ( ) {
@Override
public boolean onError ( @NonNull Event event ) {
event . setSeverity ( Severity . INFO ) ;
return true ;
}
} ) ;
2019-12-14 16:01:27 +00:00
} catch ( Throwable ex1 ) {
ex1 . printStackTrace ( ) ;
}
2018-12-24 12:27:45 +00:00
return android . util . Log . w ( TAG , prefix + " " + ex + " \ n " + android . util . Log . getStackTraceString ( ex ) ) ;
}
public static int e ( String prefix , Throwable ex ) {
2019-05-15 19:20:18 +00:00
if ( BuildConfig . BETA_RELEASE )
2019-12-14 16:01:27 +00:00
try {
2020-05-22 17:50:46 +00:00
Bugsnag . notify ( ex , new OnErrorCallback ( ) {
@Override
public boolean onError ( @NonNull Event event ) {
event . setSeverity ( Severity . WARNING ) ;
return true ;
}
} ) ;
2019-12-14 16:01:27 +00:00
} catch ( Throwable ex1 ) {
ex1 . printStackTrace ( ) ;
}
2018-12-24 12:27:45 +00:00
return android . util . Log . e ( TAG , prefix + " " + ex + " \ n " + android . util . Log . getStackTraceString ( ex ) ) ;
}
2019-01-25 14:40:46 +00:00
2021-10-22 13:04:16 +00:00
public static void persist ( String message ) {
if ( ctx = = null )
Log . e ( message ) ;
else
EntityLog . log ( ctx , message ) ;
}
2019-08-12 11:17:55 +00:00
static void setCrashReporting ( boolean enabled ) {
2019-12-14 16:01:27 +00:00
try {
if ( enabled )
Bugsnag . startSession ( ) ;
} catch ( Throwable ex ) {
ex . printStackTrace ( ) ;
}
2019-08-12 11:17:55 +00:00
}
2021-07-27 14:17:15 +00:00
public static void breadcrumb ( String name , String key , String value ) {
2021-05-14 17:20:01 +00:00
Map < String , String > crumb = new HashMap < > ( ) ;
crumb . put ( key , value ) ;
breadcrumb ( name , crumb ) ;
}
2021-07-27 14:17:15 +00:00
public static void breadcrumb ( String name , Map < String , String > crumb ) {
2019-12-14 16:01:27 +00:00
try {
2021-07-27 14:17:15 +00:00
StringBuilder sb = new StringBuilder ( ) ;
sb . append ( " Breadcrumb " ) . append ( name ) ;
2020-05-22 17:50:46 +00:00
Map < String , Object > ocrumb = new HashMap < > ( ) ;
2021-07-27 14:17:15 +00:00
for ( String key : crumb . keySet ( ) ) {
String val = crumb . get ( key ) ;
sb . append ( ' ' ) . append ( key ) . append ( '=' ) . append ( val ) ;
ocrumb . put ( key , val ) ;
}
2021-09-16 06:13:34 +00:00
Log . i ( sb . toString ( ) ) ;
2020-05-22 17:50:46 +00:00
Bugsnag . leaveBreadcrumb ( name , ocrumb , BreadcrumbType . LOG ) ;
2019-12-14 16:01:27 +00:00
} catch ( Throwable ex ) {
ex . printStackTrace ( ) ;
}
2019-08-12 11:17:55 +00:00
}
2020-04-05 12:10:42 +00:00
static void setup ( Context context ) {
2021-10-22 13:04:16 +00:00
ctx = context ;
2021-02-27 16:45:08 +00:00
setLevel ( context ) ;
2020-04-05 12:10:42 +00:00
setupBugsnag ( context ) ;
}
2020-05-28 18:49:59 +00:00
private static void setupBugsnag ( final Context context ) {
2021-01-27 16:58:16 +00:00
try {
2021-02-27 15:00:31 +00:00
Log . i ( " Configuring Bugsnag " ) ;
2021-01-27 16:58:16 +00:00
// https://docs.bugsnag.com/platforms/android/sdk/
com . bugsnag . android . Configuration config =
new com . bugsnag . android . Configuration ( " 9d2d57476a0614974449a3ec33f2604a " ) ;
if ( BuildConfig . DEBUG )
config . setReleaseStage ( " debug " ) ;
else {
String type ;
if ( Helper . hasValidFingerprint ( context ) ) {
if ( BuildConfig . PLAY_STORE_RELEASE )
type = " play " ;
2021-06-30 09:57:15 +00:00
else if ( BuildConfig . AMAZON_RELEASE )
type = " amazon " ;
2021-01-27 16:58:16 +00:00
else
type = " full " ;
} else {
if ( BuildConfig . APPLICATION_ID . startsWith ( " eu.faircode.email " ) )
type = " other " ;
else
type = " clone " ;
}
config . setReleaseStage ( type + ( BuildConfig . BETA_RELEASE ? " /beta " : " " ) ) ;
2020-03-28 08:39:02 +00:00
}
2019-08-12 11:17:55 +00:00
2021-01-27 16:58:16 +00:00
config . setAutoTrackSessions ( false ) ;
2019-08-12 11:17:55 +00:00
2021-01-27 16:58:16 +00:00
ErrorTypes etypes = new ErrorTypes ( ) ;
etypes . setAnrs ( BuildConfig . DEBUG ) ;
etypes . setNdkCrashes ( false ) ;
config . setEnabledErrorTypes ( etypes ) ;
2021-12-08 13:50:57 +00:00
config . setMaxBreadcrumbs ( BuildConfig . PLAY_STORE_RELEASE ? 50 : 100 ) ;
2019-08-12 11:17:55 +00:00
2021-01-27 16:58:16 +00:00
Set < String > ignore = new HashSet < > ( ) ;
2019-08-12 11:17:55 +00:00
2021-01-27 16:58:16 +00:00
ignore . add ( " com.sun.mail.util.MailConnectException " ) ;
2019-08-12 11:17:55 +00:00
2021-01-27 16:58:16 +00:00
ignore . add ( " android.accounts.AuthenticatorException " ) ;
ignore . add ( " android.accounts.OperationCanceledException " ) ;
ignore . add ( " android.app.RemoteServiceException " ) ;
2019-08-12 11:17:55 +00:00
2021-01-27 16:58:16 +00:00
ignore . add ( " java.lang.NoClassDefFoundError " ) ;
ignore . add ( " java.lang.UnsatisfiedLinkError " ) ;
2019-08-12 11:17:55 +00:00
2021-01-27 16:58:16 +00:00
ignore . add ( " java.nio.charset.MalformedInputException " ) ;
2019-08-12 11:17:55 +00:00
2021-01-27 16:58:16 +00:00
ignore . add ( " java.net.ConnectException " ) ;
ignore . add ( " java.net.SocketException " ) ;
ignore . add ( " java.net.SocketTimeoutException " ) ;
ignore . add ( " java.net.UnknownHostException " ) ;
2019-08-12 11:17:55 +00:00
2021-01-27 16:58:16 +00:00
ignore . add ( " javax.mail.AuthenticationFailedException " ) ;
ignore . add ( " javax.mail.internet.AddressException " ) ;
ignore . add ( " javax.mail.internet.ParseException " ) ;
ignore . add ( " javax.mail.MessageRemovedException " ) ;
ignore . add ( " javax.mail.FolderNotFoundException " ) ;
ignore . add ( " javax.mail.ReadOnlyFolderException " ) ;
ignore . add ( " javax.mail.FolderClosedException " ) ;
ignore . add ( " com.sun.mail.util.FolderClosedIOException " ) ;
ignore . add ( " javax.mail.StoreClosedException " ) ;
2019-08-12 11:17:55 +00:00
2021-01-27 16:58:16 +00:00
ignore . add ( " org.xmlpull.v1.XmlPullParserException " ) ;
2019-08-12 11:17:55 +00:00
2021-01-27 16:58:16 +00:00
config . setDiscardClasses ( ignore ) ;
2019-08-12 11:17:55 +00:00
2021-01-27 16:58:16 +00:00
final SharedPreferences prefs = PreferenceManager . getDefaultSharedPreferences ( context ) ;
ActivityManager am = ( ActivityManager ) context . getSystemService ( Context . ACTIVITY_SERVICE ) ;
2019-08-12 11:17:55 +00:00
2021-01-27 16:58:16 +00:00
String no_internet = context . getString ( R . string . title_no_internet ) ;
2020-02-01 14:52:53 +00:00
2021-01-27 16:58:16 +00:00
String installer = context . getPackageManager ( ) . getInstallerPackageName ( BuildConfig . APPLICATION_ID ) ;
2021-10-04 06:47:06 +00:00
config . addMetadata ( " extra " , " revision " , BuildConfig . REVISION ) ;
2021-01-27 16:58:16 +00:00
config . addMetadata ( " extra " , " installer " , installer = = null ? " - " : installer ) ;
config . addMetadata ( " extra " , " installed " , new Date ( Helper . getInstallTime ( context ) ) . toString ( ) ) ;
config . addMetadata ( " extra " , " fingerprint " , Helper . hasValidFingerprint ( context ) ) ;
config . addMetadata ( " extra " , " memory_class " , am . getMemoryClass ( ) ) ;
config . addMetadata ( " extra " , " memory_class_large " , am . getLargeMemoryClass ( ) ) ;
2021-11-03 07:01:23 +00:00
config . addMetadata ( " extra " , " build_host " , Build . HOST ) ;
config . addMetadata ( " extra " , " build_time " , new Date ( Build . TIME ) ) ;
2020-05-22 17:50:46 +00:00
2021-01-27 16:58:16 +00:00
config . addOnSession ( new OnSessionCallback ( ) {
@Override
public boolean onSession ( @NonNull Session session ) {
// opt-in
2022-01-09 13:48:37 +00:00
return prefs . getBoolean ( " crash_reports " , false ) | | BuildConfig . TEST_RELEASE ;
2020-05-22 17:50:46 +00:00
}
2021-01-27 16:58:16 +00:00
} ) ;
config . addOnError ( new OnErrorCallback ( ) {
@Override
public boolean onError ( @NonNull Event event ) {
// opt-in
boolean crash_reports = prefs . getBoolean ( " crash_reports " , false ) ;
2022-01-09 13:48:37 +00:00
if ( ! crash_reports & & ! BuildConfig . TEST_RELEASE )
2021-01-27 16:58:16 +00:00
return false ;
Throwable ex = event . getOriginalError ( ) ;
boolean should = shouldNotify ( ex ) ;
if ( should ) {
2021-04-25 14:27:28 +00:00
event . addMetadata ( " extra " , " pid " , Integer . toString ( android . os . Process . myPid ( ) ) ) ;
2021-01-27 16:58:16 +00:00
event . addMetadata ( " extra " , " thread " , Thread . currentThread ( ) . getName ( ) + " : " + Thread . currentThread ( ) . getId ( ) ) ;
event . addMetadata ( " extra " , " memory_free " , getFreeMemMb ( ) ) ;
event . addMetadata ( " extra " , " memory_available " , getAvailableMb ( ) ) ;
2021-08-31 05:40:08 +00:00
event . addMetadata ( " extra " , " native_allocated " , Debug . getNativeHeapAllocatedSize ( ) / 1024L / 1024L ) ;
event . addMetadata ( " extra " , " native_size " , Debug . getNativeHeapSize ( ) / 1024L / 1024L ) ;
2021-01-27 16:58:16 +00:00
Boolean ignoringOptimizations = Helper . isIgnoringOptimizations ( context ) ;
event . addMetadata ( " extra " , " optimizing " , ( ignoringOptimizations ! = null & & ! ignoringOptimizations ) ) ;
String theme = prefs . getString ( " theme " , " blue_orange_system " ) ;
event . addMetadata ( " extra " , " theme " , theme ) ;
event . addMetadata ( " extra " , " package " , BuildConfig . APPLICATION_ID ) ;
}
2020-05-22 17:50:46 +00:00
2021-01-27 16:58:16 +00:00
return should ;
}
2019-08-12 11:17:55 +00:00
2021-01-27 16:58:16 +00:00
private boolean shouldNotify ( Throwable ex ) {
if ( ex instanceof MessagingException & &
( ex . getCause ( ) instanceof IOException | |
ex . getCause ( ) instanceof ProtocolException ) )
// IOException includes SocketException, SocketTimeoutException
// ProtocolException includes ConnectionException
return false ;
if ( ex instanceof MessagingException & &
( " connection failure " . equals ( ex . getMessage ( ) ) | |
" failed to create new store connection " . equals ( ex . getMessage ( ) ) | |
" Failed to fetch headers " . equals ( ex . getMessage ( ) ) | |
" Failed to load IMAP envelope " . equals ( ex . getMessage ( ) ) | |
" Unable to load BODYSTRUCTURE " . equals ( ex . getMessage ( ) ) ) )
return false ;
if ( ex instanceof IllegalStateException & &
( no_internet . equals ( ex . getMessage ( ) ) | |
2021-12-01 18:33:29 +00:00
TOKEN_REFRESH_REQUIRED . equals ( ex . getMessage ( ) ) | |
2021-01-27 16:58:16 +00:00
" Not connected " . equals ( ex . getMessage ( ) ) | |
" This operation is not allowed on a closed folder " . equals ( ex . getMessage ( ) ) ) )
return false ;
if ( ex instanceof FileNotFoundException & &
ex . getMessage ( ) ! = null & &
( ex . getMessage ( ) . startsWith ( " Download image failed " ) | |
ex . getMessage ( ) . startsWith ( " http:// " ) | |
ex . getMessage ( ) . startsWith ( " https:// " ) | |
ex . getMessage ( ) . startsWith ( " content:// " ) ) )
return false ;
if ( ex instanceof IOException & &
ex . getCause ( ) instanceof MessageRemovedException )
return false ;
if ( ex instanceof IOException & &
ex . getMessage ( ) ! = null & &
( ex . getMessage ( ) . startsWith ( " HTTP status= " ) | |
" NetworkError " . equals ( ex . getMessage ( ) ) | | // account manager
" Resetting to invalid mark " . equals ( ex . getMessage ( ) ) | |
" Mark has been invalidated. " . equals ( ex . getMessage ( ) ) ) )
return false ;
if ( ex instanceof SSLPeerUnverifiedException | |
ex instanceof EmailService . UntrustedException )
return false ;
if ( ex instanceof SSLHandshakeException & &
ex . getCause ( ) instanceof CertPathValidatorException )
return false ; // checkUpdate!
if ( ex instanceof RuntimeException & &
" Illegal meta data value: the child service doesn't exist " . equals ( ex . getMessage ( ) ) )
return false ;
2021-01-31 11:25:10 +00:00
if ( isDead ( ex ) )
return false ;
2021-01-27 16:58:16 +00:00
// Rate limit
int count = prefs . getInt ( " crash_report_count " , 0 ) + 1 ;
prefs . edit ( ) . putInt ( " crash_report_count " , count ) . apply ( ) ;
return ( count < = MAX_CRASH_REPORTS ) ;
}
} ) ;
2019-10-28 17:46:53 +00:00
2021-01-27 16:58:16 +00:00
Bugsnag . start ( context , config ) ;
2019-10-28 17:46:53 +00:00
2021-01-27 16:58:16 +00:00
Client client = Bugsnag . getClient ( ) ;
2019-10-28 17:46:53 +00:00
2021-01-27 16:58:16 +00:00
String uuid = prefs . getString ( " uuid " , null ) ;
if ( uuid = = null ) {
uuid = UUID . randomUUID ( ) . toString ( ) ;
prefs . edit ( ) . putString ( " uuid " , uuid ) . apply ( ) ;
}
Log . i ( " uuid= " + uuid ) ;
client . setUser ( uuid , null , null ) ;
2019-10-28 17:46:53 +00:00
2022-01-09 13:48:37 +00:00
if ( prefs . getBoolean ( " crash_reports " , false ) | | BuildConfig . TEST_RELEASE )
2021-01-27 16:58:16 +00:00
Bugsnag . startSession ( ) ;
} catch ( Throwable ex ) {
Log . e ( ex ) ;
/ *
java . lang . AssertionError : No NameTypeIndex match for SHORT_DAYLIGHT
at android . icu . impl . TimeZoneNamesImpl$ZNames . getNameTypeIndex ( TimeZoneNamesImpl . java : 724 )
at android . icu . impl . TimeZoneNamesImpl$ZNames . getName ( TimeZoneNamesImpl . java : 790 )
at android . icu . impl . TimeZoneNamesImpl . getTimeZoneDisplayName ( TimeZoneNamesImpl . java : 183 )
at android . icu . text . TimeZoneNames . getDisplayName ( TimeZoneNames . java : 261 )
at java . util . TimeZone . getDisplayName ( TimeZone . java : 405 )
at java . util . Date . toString ( Date . java : 1066 )
* /
}
2019-08-12 11:07:14 +00:00
}
2019-05-15 19:20:18 +00:00
static void logExtras ( Intent intent ) {
2019-01-25 14:40:46 +00:00
if ( intent ! = null )
logBundle ( intent . getExtras ( ) ) ;
}
2019-05-15 19:20:18 +00:00
static void logBundle ( Bundle data ) {
2019-10-01 07:19:44 +00:00
for ( String extra : getExtras ( data ) )
i ( extra ) ;
}
static List < String > getExtras ( Bundle data ) {
List < String > result = new ArrayList < > ( ) ;
if ( data = = null )
return result ;
2019-10-29 06:57:39 +00:00
try {
Set < String > keys = data . keySet ( ) ;
for ( String key : keys ) {
Object v = data . get ( key ) ;
Object value = v ;
2021-12-06 07:50:59 +00:00
int length = - 1 ;
2019-10-29 06:57:39 +00:00
if ( v ! = null & & v . getClass ( ) . isArray ( ) ) {
2021-12-06 07:50:59 +00:00
length = Array . getLength ( v ) ;
String [ ] elements = new String [ Math . min ( length , 10 ) ] ;
for ( int i = 0 ; i < elements . length ; i + + ) {
Object element = Array . get ( v , i ) ;
if ( element instanceof Long )
elements [ i ] = element + " (0x " + Long . toHexString ( ( Long ) element ) + " ) " ;
else
elements [ i ] = ( element = = null ? " <null> " : printableString ( element . toString ( ) ) ) ;
}
value = TextUtils . join ( " , " , elements ) ;
if ( length > 10 )
value + = " , ... " ;
value = " [ " + value + " ] " ;
2019-10-29 06:57:39 +00:00
} else if ( v instanceof Long )
2021-12-06 07:50:59 +00:00
value = v + " (0x " + Long . toHexString ( ( Long ) v ) + " ) " ;
else if ( v instanceof Bundle )
value = " { " + TextUtils . join ( " " , getExtras ( ( Bundle ) v ) ) + " } " ;
2019-10-01 07:19:44 +00:00
2021-12-06 07:50:59 +00:00
result . add ( key + " = " + value + ( value = = null ? " " :
" ( " + v . getClass ( ) . getSimpleName ( ) + ( length < 0 ? " " : " : " + length ) + " ) " ) ) ;
2019-10-29 06:57:39 +00:00
}
2021-12-17 13:30:28 +00:00
} catch ( Throwable ex ) {
2019-10-29 06:57:39 +00:00
// android.os.BadParcelableException: ClassNotFoundException when unmarshalling: ...
2021-12-17 13:30:28 +00:00
// java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1172374955, result=0, data=Intent { (has extras) }} to activity {eu.faircode.email/eu.faircode.email.ActivityCompose}: java.lang.RuntimeException: Parcelable encountered ClassNotFoundException reading a Serializable object (name = com.lyrebirdstudio.imagecameralib.utils.ImageCameraLibReturnTypes)
// at android.app.ActivityThread.deliverResults(ActivityThread.java:4382)
// at android.app.ActivityThread.handleSendResult(ActivityThread.java:4426)
// at android.app.ActivityThread.-wrap20(Unknown)
// at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1685)
// at android.os.Handler.dispatchMessage(Handler.java:106)
// at android.os.Looper.loop(Looper.java:164)
// at android.app.ActivityThread.main(ActivityThread.java:6626)
// at java.lang.reflect.Method.invoke(Method.java:-2)
// at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
// at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:811)
//
// Caused by: java.lang.RuntimeException: Parcelable encountered ClassNotFoundException reading a Serializable object (name = com.lyrebirdstudio.imagecameralib.utils.ImageCameraLibReturnTypes)
// at android.os.Parcel.readSerializable(Parcel.java:3019)
// at android.os.Parcel.readValue(Parcel.java:2805)
// at android.os.Parcel.readArrayMapInternal(Parcel.java:3123)
// at android.os.BaseBundle.initializeFromParcelLocked(BaseBundle.java:273)
// at android.os.BaseBundle.unparcel(BaseBundle.java:226)
// at android.os.BaseBundle.keySet(BaseBundle.java:520)
// at eu.faircode.email.Log.getExtras(Log:565)
// at eu.faircode.email.Log.logBundle(Log:555)
// at eu.faircode.email.Log.logExtras(Log:551)
// at eu.faircode.email.ActivityBase.onActivityResult(ActivityBase:376)
// at android.app.Activity.dispatchActivityResult(Activity.java:7305)
// at android.app.ActivityThread.deliverResults(ActivityThread.java:4378)
// at android.app.ActivityThread.handleSendResult(ActivityThread.java:4426)
// at android.app.ActivityThread.-wrap20(Unknown)
// at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1685)
// at android.os.Handler.dispatchMessage(Handler.java:106)
// at android.os.Looper.loop(Looper.java:164)
// at android.app.ActivityThread.main(ActivityThread.java:6626)
// at java.lang.reflect.Method.invoke(Method.java:-2)
// at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
// at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:811)
//
// Caused by: java.lang.ClassNotFoundException: com.lyrebirdstudio.imagecameralib.utils.ImageCameraLibReturnTypes
//
// Caused by: java.lang.ClassNotFoundException: Didn't find class "com.lyrebirdstudio.imagecameralib.utils.ImageCameraLibReturnTypes" on path: DexPathList[[zip file "/data/app/eu.faircode.email-b4dvFM1MrZ5iBeNXAXRJhQ==/base.apk"],nativeLibraryDirectories=[/data/app/eu.faircode.email-b4dvFM1MrZ5iBeNXAXRJhQ==/lib/arm, /data/app/eu.faircode.email-b4dvFM1MrZ5iBeNXAXRJhQ==/base.apk!/lib/armeabi-v7a, /system/lib, /system/vendor/lib]]
2019-10-29 06:57:39 +00:00
Log . e ( ex ) ;
2019-01-25 14:40:46 +00:00
}
2019-10-01 07:19:44 +00:00
return result ;
2019-01-25 14:40:46 +00:00
}
2019-05-12 17:14:34 +00:00
2021-05-22 06:08:18 +00:00
static String printableString ( String value ) {
2021-05-21 18:38:58 +00:00
StringBuilder result = new StringBuilder ( ) ;
for ( int i = 0 ; i < value . length ( ) ; i + + ) {
char kar = value . charAt ( i ) ;
if ( kar = = '\n' )
result . append ( '|' ) ;
else if ( kar = = ' ' )
result . append ( '_' ) ;
else if ( ! Helper . isPrintableChar ( kar ) )
result . append ( '{' ) . append ( Integer . toHexString ( kar ) ) . append ( '}' ) ;
else
result . append ( kar ) ;
}
return result . toString ( ) ;
}
2019-08-12 11:17:55 +00:00
static void logMemory ( Context context , String message ) {
ActivityManager . MemoryInfo mi = new ActivityManager . MemoryInfo ( ) ;
ActivityManager activityManager = ( ActivityManager ) context . getSystemService ( Context . ACTIVITY_SERVICE ) ;
activityManager . getMemoryInfo ( mi ) ;
int mb = Math . round ( mi . availMem / 0x100000L ) ;
int perc = Math . round ( mi . availMem / ( float ) mi . totalMem * 100 . 0f ) ;
Log . i ( message + " " + mb + " MB " + " " + perc + " % " ) ;
}
2019-08-12 14:18:41 +00:00
static boolean isOwnFault ( Throwable ex ) {
2021-05-28 18:22:01 +00:00
if ( ! Helper . isSupportedDevice ( ) )
2019-09-02 12:52:49 +00:00
return false ;
2020-11-20 08:35:53 +00:00
if ( ex instanceof OutOfMemoryError | |
ex . getCause ( ) instanceof OutOfMemoryError )
2019-08-12 11:17:55 +00:00
return false ;
if ( ex instanceof RemoteException )
return false ;
2020-03-09 12:07:22 +00:00
if ( ex instanceof UnsatisfiedLinkError | |
ex . getCause ( ) instanceof UnsatisfiedLinkError )
2020-03-25 09:05:51 +00:00
/ *
java . lang . UnsatisfiedLinkError : dlopen failed : couldn ' t map " /mnt/asec/eu.faircode.email-1/base.apk!/lib/arm64-v8a/libsqlite3x.so " segment 0 : Permission denied
at java . lang . Runtime . loadLibrary0 ( Runtime . java : 1016 )
at java . lang . System . loadLibrary ( System . java : 1657 )
at io . requery . android . database . sqlite . SQLiteDatabase . < clinit > ( SourceFile : 91 )
* /
2020-03-08 17:12:21 +00:00
return false ;
2020-04-01 12:38:49 +00:00
if ( ex instanceof InternalError & &
" Thread starting during runtime shutdown " . equals ( ex . getMessage ( ) ) )
/ *
java . lang . InternalError : Thread starting during runtime shutdown
at java . lang . Thread . nativeCreate ( Native Method )
at java . lang . Thread . start ( Thread . java : 1063 )
at java . util . concurrent . ThreadPoolExecutor . addWorker ( ThreadPoolExecutor . java : 921 )
at java . util . concurrent . ThreadPoolExecutor . processWorkerExit ( ThreadPoolExecutor . java : 989 )
at java . util . concurrent . ThreadPoolExecutor . runWorker ( ThreadPoolExecutor . java : 1131 )
at java . util . concurrent . ThreadPoolExecutor$Worker . run ( ThreadPoolExecutor . java : 588 )
at java . lang . Thread . run ( Thread . java : 818 )
* /
return false ;
2020-01-23 11:46:11 +00:00
if ( " android.app.RemoteServiceException " . equals ( ex . getClass ( ) . getName ( ) ) )
2020-03-25 09:05:51 +00:00
/ *
android . app . RemoteServiceException : Bad notification for startForeground : java . util . ConcurrentModificationException
2020-08-06 11:52:27 +00:00
at android . app . ActivityThread$H . handleMessage ( ActivityThread . java : 2204 )
2020-03-25 09:05:51 +00:00
* /
2020-01-23 11:46:11 +00:00
return false ;
2020-04-10 14:15:30 +00:00
if ( " android.view.WindowManager$BadTokenException " . equals ( ex . getClass ( ) . getName ( ) ) )
/ *
android . view . WindowManager$BadTokenException : Unable to add window - - token android . os . BinderProxy @e9084db is not valid ; is your activity running ?
at android . view . ViewRootImpl . setView ( ViewRootImpl . java : 827 )
at android . view . WindowManagerGlobal . addView ( WindowManagerGlobal . java : 356 )
at android . view . WindowManagerImpl . addView ( WindowManagerImpl . java : 93 )
at android . app . ActivityThread . handleResumeActivity ( ActivityThread . java : 4084 )
at android . app . servertransaction . ResumeActivityItem . execute ( ResumeActivityItem . java : 51 )
at android . app . servertransaction . TransactionExecutor . executeLifecycleState ( TransactionExecutor . java : 145 )
at android . app . servertransaction . TransactionExecutor . execute ( TransactionExecutor . java : 70 )
at android . app . ActivityThread$H . handleMessage ( ActivityThread . java : 1976 )
* /
return false ;
2019-08-12 11:17:55 +00:00
if ( ex instanceof NoSuchMethodError )
2020-03-25 09:05:51 +00:00
/ *
java . lang . NoSuchMethodError : No direct method ( ) V in class Landroid / security / IKeyChainService$Stub ; or its super classes ( declaration of ' android . security . IKeyChainService$Stub ' appears in / system / framework / framework . jar ! classes2 . dex )
2020-08-06 11:52:27 +00:00
at com . android . keychain . KeyChainService$1 . ( KeyChainService . java : 95 )
at com . android . keychain . KeyChainService . ( KeyChainService . java : 95 )
at java . lang . Class . newInstance ( Native Method )
at android . app . AppComponentFactory . instantiateService ( AppComponentFactory . java : 103 )
2020-03-25 09:05:51 +00:00
* /
2019-08-12 11:17:55 +00:00
return false ;
2019-09-03 06:18:30 +00:00
if ( ex instanceof IllegalStateException & &
" Drag shadow dimensions must be positive " . equals ( ex . getMessage ( ) ) )
/ *
Android 9 only
java . lang . IllegalStateException : Drag shadow dimensions must be positive
java . lang . IllegalStateException : Drag shadow dimensions must be positive
2020-08-06 11:52:27 +00:00
at android . view . View . startDragAndDrop ( View . java : 24027 )
at android . widget . Editor . startDragAndDrop ( Editor . java : 1165 )
at android . widget . Editor . performLongClick ( Editor . java : 1191 )
at android . widget . TextView . performLongClick ( TextView . java : 11346 )
at android . view . View . performLongClick ( View . java : 6653 )
at android . view . View$CheckForLongPress . run ( View . java : 25855 )
at android . os . Handler . handleCallback ( Handler . java : 873 )
2019-09-03 06:18:30 +00:00
* /
return false ;
2020-06-26 19:44:52 +00:00
if ( ex instanceof IllegalStateException & &
" Results have already been set " . equals ( ex . getMessage ( ) ) )
/ *
Play billing ?
java . lang . IllegalStateException : Results have already been set
2020-08-06 11:52:27 +00:00
at Gu . a ( Unknown : 8 )
at Fq . a ( Unknown : 29 )
at Fk . b ( Unknown : 17 )
at Fk . a ( Unknown : 12 )
at Fk . b ( Unknown : 5 )
at Ex . a ( Unknown : 3 )
at Ep . b ( Unknown : 9 )
at Ep . a ( Unknown : 76 )
at Ep . a ( Unknown : 16 )
at GH . a ( Unknown : 2 )
at Gz . a ( Unknown : 48 )
at GC . handleMessage ( Unknown : 6 )
at android . os . Handler . dispatchMessage ( Handler . java : 108 )
at android . os . Looper . loop ( Looper . java : 166 )
at android . os . HandlerThread . run ( HandlerThread . java : 65 )
2020-06-26 19:44:52 +00:00
* /
return false ;
2020-03-19 16:54:17 +00:00
if ( ex instanceof IllegalArgumentException & &
ex . getCause ( ) instanceof RemoteException )
/ *
java . lang . IllegalArgumentException
at android . os . Parcel . createException ( Parcel . java : 1954 )
at android . os . Parcel . readException ( Parcel . java : 1918 )
at android . os . Parcel . readException ( Parcel . java : 1868 )
at android . view . IWindowSession$Stub$Proxy . addToDisplay ( IWindowSession . java : 826 )
at android . view . ViewRootImpl . setView ( ViewRootImpl . java : 758 )
at android . view . WindowManagerGlobal . addView ( WindowManagerGlobal . java : 356 )
at android . view . WindowManagerImpl . addView ( WindowManagerImpl . java : 93 )
at android . app . ActivityThread . handleResumeActivity ( ActivityThread . java : 3906 )
at android . app . servertransaction . ResumeActivityItem . execute ( ResumeActivityItem . java : 51 )
at android . app . servertransaction . TransactionExecutor . executeLifecycleState ( TransactionExecutor . java : 145 )
at android . app . servertransaction . TransactionExecutor . execute ( TransactionExecutor . java : 70 )
at android . app . ActivityThread$H . handleMessage ( ActivityThread . java : 1816 )
at android . os . Handler . dispatchMessage ( Handler . java : 106 )
at android . os . Looper . loop ( Looper . java : 193 )
at android . app . ActivityThread . main ( ActivityThread . java : 6718 )
at java . lang . reflect . Method . invoke ( Native Method )
at com . android . internal . os . RuntimeInit$MethodAndArgsCaller . run ( RuntimeInit . java : 491 )
at com . android . internal . os . ZygoteInit . main ( ZygoteInit . java : 858 )
Caused by : android . os . RemoteException : Remote stack trace :
at android . view . SurfaceControl . nativeCreate ( Native Method )
at android . view . SurfaceControl . < init > ( SurfaceControl . java : 630 )
at android . view . SurfaceControl . < init > ( SurfaceControl . java : 60 )
at android . view . SurfaceControl$Builder . build ( SurfaceControl . java : 386 )
at com . android . server . wm . WindowContainer . onParentSet ( WindowContainer . java : 184 )
* /
return false ;
2019-09-19 08:32:55 +00:00
if ( ex instanceof IllegalArgumentException & &
ex . getMessage ( ) ! = null & &
ex . getMessage ( ) . startsWith ( " Tmp detached view should be removed from RecyclerView before it can be recycled " ) )
/ *
Android 9 only ?
java . lang . IllegalArgumentException : Tmp detached view should be removed from RecyclerView before it can be recycled : ViewHolder { e3b70bd position = 0 id = 1 , oldPos = - 1 , pLpos : - 1 update tmpDetached no parent } androidx . recyclerview . widget . RecyclerView { f0fe5b1 VFED . . . . . . . . . . . ID 0 , 0 - 641 , 456 # 7f090293 app : id / rvAccount } , adapter : eu . faircode . email . AdapterNavAccount @9a6ea96 , layout : androidx . recyclerview . widget . LinearLayoutManager @d8fc617 , context : eu . faircode . email . ActivityView @82a6ec4
at androidx . recyclerview . widget . RecyclerView$Recycler . recycleViewHolderInternal ( SourceFile : 6435 )
at androidx . recyclerview . widget . RecyclerView . removeAnimatingView ( SourceFile : 1456 )
at androidx . recyclerview . widget . RecyclerView$ItemAnimatorRestoreListener . onAnimationFinished ( SourceFile : 12690 )
at androidx . recyclerview . widget . RecyclerView$ItemAnimator . dispatchAnimationFinished ( SourceFile : 13190 )
at androidx . recyclerview . widget . SimpleItemAnimator . dispatchChangeFinished ( SourceFile : 317 )
at androidx . recyclerview . widget . DefaultItemAnimator$8 . onAnimationEnd ( SourceFile : 391 )
at android . view . ViewPropertyAnimator$AnimatorEventListener . onAnimationEnd ( ViewPropertyAnimator . java : 1122 )
* /
return false ;
2020-07-09 06:19:34 +00:00
if ( ex instanceof IllegalArgumentException & &
" page introduces incorrect tiling " . equals ( ex . getMessage ( ) ) )
/ *
java . lang . IllegalArgumentException : page introduces incorrect tiling
at androidx . paging . PagedStorage . insertPage ( SourceFile : 545 )
at androidx . paging . PagedStorage . tryInsertPageAndTrim ( SourceFile : 504 )
at androidx . paging . TiledPagedList$1 . onPageResult ( SourceFile : 60 )
at androidx . paging . DataSource$LoadCallbackHelper$1 . run ( SourceFile : 324 )
at android . os . Handler . handleCallback ( Handler . java : 789 )
* /
return false ;
2021-05-26 17:28:49 +00:00
if ( ex instanceof IllegalArgumentException & &
" Can't interpolate between two incompatible pathData " . equals ( ex . getMessage ( ) ) )
/ *
java . lang . IllegalArgumentException : Can ' t interpolate between two incompatible pathData
at android . animation . AnimatorInflater$PathDataEvaluator . evaluate ( AnimatorInflater . java : 265 )
at android . animation . AnimatorInflater$PathDataEvaluator . evaluate ( AnimatorInflater . java : 262 )
at android . animation . KeyframeSet . getValue ( KeyframeSet . java : 210 )
at android . animation . PropertyValuesHolder . calculateValue ( PropertyValuesHolder . java : 1018 )
at android . animation . ValueAnimator . animateValue ( ValueAnimator . java : 1341 )
at android . animation . ObjectAnimator . animateValue ( ObjectAnimator . java : 986 )
at android . animation . ValueAnimator . animateBasedOnTime ( ValueAnimator . java : 1258 )
at android . animation . ValueAnimator . doAnimationFrame ( ValueAnimator . java : 1306 )
at android . animation . AnimationHandler . doAnimationFrame ( AnimationHandler . java : 146 )
at android . animation . AnimationHandler . - wrap2 ( AnimationHandler . java )
at android . animation . AnimationHandler$1 . doFrame ( AnimationHandler . java : 54 )
at android . view . Choreographer$CallbackRecord . run ( Choreographer . java : 925 )
at android . view . Choreographer . doCallbacks ( Choreographer . java : 702 )
at android . view . Choreographer . doFrame ( Choreographer . java : 635 )
at android . view . Choreographer$FrameDisplayEventReceiver . run ( Choreographer . java : 913 )
at android . os . Handler . handleCallback ( Handler . java : 751 )
* /
return false ;
2020-06-21 11:00:49 +00:00
if ( ex instanceof IllegalMonitorStateException )
/ *
java . lang . IllegalMonitorStateException
at java . util . concurrent . locks . AbstractQueuedSynchronizer$ConditionObject . signal ( AbstractQueuedSynchronizer . java : 1959 )
at java . util . concurrent . ScheduledThreadPoolExecutor$DelayedWorkQueue . take ( ScheduledThreadPoolExecutor . java : 1142 )
at java . util . concurrent . ScheduledThreadPoolExecutor$DelayedWorkQueue . take ( ScheduledThreadPoolExecutor . java : 849 )
at java . util . concurrent . ThreadPoolExecutor . getTask ( ThreadPoolExecutor . java : 1092 )
at java . util . concurrent . ThreadPoolExecutor . runWorker ( ThreadPoolExecutor . java : 1152 )
at java . util . concurrent . ThreadPoolExecutor$Worker . run ( ThreadPoolExecutor . java : 641 )
at java . lang . Thread . run ( Thread . java : 764 )
* /
return false ;
2020-04-20 06:07:41 +00:00
if ( ex instanceof RuntimeException & &
ex . getCause ( ) instanceof TransactionTooLargeException )
// Some Android versions (Samsung) send images as clip data
return false ;
2019-12-05 12:25:59 +00:00
if ( ex instanceof RuntimeException & &
ex . getMessage ( ) ! = null & &
2021-01-31 11:25:10 +00:00
( ex . getMessage ( ) . startsWith ( " Could not get application info " ) | |
2020-03-25 09:05:51 +00:00
ex . getMessage ( ) . startsWith ( " Unable to create service " ) | |
2020-04-18 17:29:58 +00:00
ex . getMessage ( ) . startsWith ( " Unable to start service " ) | |
2020-04-16 06:19:13 +00:00
ex . getMessage ( ) . startsWith ( " Unable to resume activity " ) | |
2020-03-25 09:47:08 +00:00
ex . getMessage ( ) . startsWith ( " Failure delivering result " ) ) )
2019-12-05 12:25:59 +00:00
return false ;
2020-03-25 09:05:51 +00:00
/ *
2020-08-06 11:52:27 +00:00
java . lang . RuntimeException : Unable to unbind to service androidx . work . impl . background . systemjob . SystemJobService @291a412 with Intent { cmp = eu . faircode . email / androidx . work . impl . background . systemjob . SystemJobService } : java . lang . RuntimeException : android . os . DeadSystemException
at android . app . ActivityThread . handleUnbindService ( ActivityThread . java : 4352 )
2019-12-05 12:25:59 +00:00
java . lang . RuntimeException : Could not get application info .
2020-08-06 11:52:27 +00:00
at CH0 . a ( PG : 11 )
at org . chromium . content . browser . ChildProcessLauncherHelperImpl . a ( PG : 34 )
at Fn2 . run ( PG : 5 )
at android . os . Handler . handleCallback ( Handler . java : 874 )
at android . os . Handler . dispatchMessage ( Handler . java : 100 )
at android . os . Looper . loop ( Looper . java : 198 )
at android . os . HandlerThread . run ( HandlerThread . java : 65 )
2020-03-06 07:12:33 +00:00
java . lang . RuntimeException : Unable to create service eu . faircode . email . ServiceSynchronize : java . lang . NullPointerException : Attempt to invoke interface method ' java . util . List android . os . IUserManager . getProfiles ( int , boolean ) ' on a null object reference
at android . app . ActivityThread . handleCreateService ( ActivityThread . java : 2739 )
2020-03-25 09:05:51 +00:00
java . lang . RuntimeException : Failure delivering result ResultInfo { who = @android : autoFillAuth : , request = 2162688 , result = - 1 , data = Intent { ( has extras ) } } to activity { eu . faircode . email / eu . faircode . email . ActivitySetup } : java . lang . NullPointerException : Attempt to invoke interface method ' java . lang . Object java . util . List . get ( int ) ' on a null object reference
at android . app . ActivityThread . deliverResults ( ActivityThread . java : 4469 )
at android . app . ActivityThread . handleSendResult ( ActivityThread . java : 4511 )
at android . app . servertransaction . ActivityResultItem . execute ( ActivityResultItem . java : 49 )
at android . app . servertransaction . TransactionExecutor . executeCallbacks ( TransactionExecutor . java : 108 )
at android . app . servertransaction . TransactionExecutor . execute ( TransactionExecutor . java : 68 )
at android . app . ActivityThread$H . handleMessage ( ActivityThread . java : 1821 )
at android . os . Handler . dispatchMessage ( Handler . java : 106 )
at android . os . Looper . loop ( Looper . java : 193 )
at android . app . ActivityThread . main ( ActivityThread . java : 6874 )
at java . lang . reflect . Method . invoke ( Native Method )
at com . android . internal . os . RuntimeInit$MethodAndArgsCaller . run ( RuntimeInit . java : 493 )
at com . android . internal . os . ZygoteInit . main ( ZygoteInit . java : 861 )
Caused by : java . lang . NullPointerException : Attempt to invoke interface method ' java . lang . Object java . util . List . get ( int ) ' on a null object reference
at android . os . Parcel . createException ( Parcel . java : 1956 )
at android . os . Parcel . readException ( Parcel . java : 1918 )
at android . os . Parcel . readException ( Parcel . java : 1868 )
at android . view . autofill . IAutoFillManager$Stub$Proxy . setAuthenticationResult ( IAutoFillManager . java : 729 )
at android . view . autofill . AutofillManager . onAuthenticationResult ( AutofillManager . java : 1474 )
at android . app . Activity . dispatchActivityResult ( Activity . java : 7497 )
at android . app . ActivityThread . deliverResults ( ActivityThread . java : 4462 )
. . . 11 more
Caused by : android . os . RemoteException : Remote stack trace :
at com . android . server . autofill . Session . setAuthenticationResultLocked ( Session . java : 1005 )
at com . android . server . autofill . AutofillManagerServiceImpl . setAuthenticationResultLocked ( AutofillManagerServiceImpl . java : 325 )
at com . android . server . autofill . AutofillManagerService$AutoFillManagerServiceStub . setAuthenticationResult ( AutofillManagerService . java : 863 )
at android . view . autofill . IAutoFillManager$Stub . onTransact ( IAutoFillManager . java : 289 )
at android . os . Binder . execTransact ( Binder . java : 731 )
* /
2019-12-05 12:25:59 +00:00
2020-03-01 19:43:27 +00:00
if ( ex instanceof RuntimeException & &
" InputChannel is not initialized. " . equals ( ex . getMessage ( ) ) )
return false ;
2020-03-25 09:05:51 +00:00
/ *
2020-03-01 19:43:27 +00:00
java . lang . RuntimeException : InputChannel is not initialized .
at android . view . InputEventReceiver . nativeInit ( Native Method )
at android . view . InputEventReceiver . < init > ( InputEventReceiver . java : 72 )
at android . view . ViewRootImpl$WindowInputEventReceiver . < init > ( ViewRootImpl . java : 7612 )
at android . view . ViewRootImpl . setView ( ViewRootImpl . java : 957 )
at android . view . WindowManagerGlobal . addView ( WindowManagerGlobal . java : 387 )
at android . view . WindowManagerImpl . addView ( WindowManagerImpl . java : 96 )
at android . widget . Toast$TN . handleShow ( Toast . java : 514 )
at android . widget . Toast$TN$1 . handleMessage ( Toast . java : 417 )
at android . os . Handler . dispatchMessage ( Handler . java : 107 )
at android . os . Looper . loop ( Looper . java : 214 )
at android . app . ActivityThread . main ( ActivityThread . java : 7397 )
2020-03-25 09:05:51 +00:00
* /
2020-03-01 19:43:27 +00:00
2019-08-12 11:17:55 +00:00
if ( ex . getMessage ( ) ! = null & &
( ex . getMessage ( ) . startsWith ( " Bad notification posted " ) | |
ex . getMessage ( ) . contains ( " ActivityRecord not found " ) | |
2019-09-23 06:31:04 +00:00
ex . getMessage ( ) . startsWith ( " Unable to create layer " ) | |
2019-11-10 08:26:39 +00:00
ex . getMessage ( ) . startsWith ( " Illegal meta data value " ) | |
2019-11-17 11:49:54 +00:00
ex . getMessage ( ) . startsWith ( " Context.startForegroundService " ) | |
ex . getMessage ( ) . startsWith ( " PARAGRAPH span must start at paragraph boundary " ) ) )
2019-08-12 11:17:55 +00:00
return false ;
if ( ex instanceof TimeoutException & &
ex . getMessage ( ) ! = null & &
2019-09-19 08:32:55 +00:00
ex . getMessage ( ) . contains ( " finalize " ) )
2019-08-12 11:17:55 +00:00
return false ;
2020-06-04 05:27:18 +00:00
if ( ex instanceof CursorWindowAllocationException | |
" android.database.CursorWindowAllocationException " . equals ( ex . getClass ( ) . getName ( ) ) )
/ *
android . database . CursorWindowAllocationException : Could not allocate CursorWindow ' / data / user / 0 / eu . faircode . email / no_backup / androidx . work . workdb ' of size 2097152 due to error - 12 .
2020-08-06 11:52:27 +00:00
at android . database . CursorWindow . nativeCreate ( Native Method )
at android . database . CursorWindow . < init > ( CursorWindow . java : 139 )
at android . database . CursorWindow . < init > ( CursorWindow . java : 120 )
at android . database . AbstractWindowedCursor . clearOrCreateWindow ( AbstractWindowedCursor . java : 202 )
at android . database . sqlite . SQLiteCursor . fillWindow ( SQLiteCursor . java : 147 )
at android . database . sqlite . SQLiteCursor . getCount ( SQLiteCursor . java : 140 )
at android . database . AbstractCursor . moveToPosition ( AbstractCursor . java : 232 )
at android . database . AbstractCursor . moveToNext ( AbstractCursor . java : 281 )
at androidx . room . InvalidationTracker$1 . checkUpdatedTable ( SourceFile : 417 )
at androidx . room . InvalidationTracker$1 . run ( SourceFile : 388 )
at androidx . work . impl . utils . SerialExecutor$Task . run ( SourceFile : 91 )
2020-06-04 05:27:18 +00:00
* /
return false ;
2021-05-12 05:44:38 +00:00
if ( ex instanceof RuntimeException & &
ex . getCause ( ) instanceof CursorWindowAllocationException )
/ *
java . lang . RuntimeException : Exception while computing database live data .
at androidx . room . RoomTrackingLiveData$1 . run ( SourceFile : 10 )
at java . util . concurrent . ThreadPoolExecutor . runWorker ( ThreadPoolExecutor . java : 1167 )
at java . util . concurrent . ThreadPoolExecutor$Worker . run ( ThreadPoolExecutor . java : 641 )
at java . lang . Thread . run ( Thread . java : 764 )
Caused by : io . requery . android . database . CursorWindowAllocationException : Cursor window allocation of 2048 kb failed .
at io . requery . android . database . CursorWindow . < init > ( SourceFile : 7 )
at io . requery . android . database . CursorWindow . < init > ( SourceFile : 1 )
at io . requery . android . database . AbstractWindowedCursor . clearOrCreateWindow ( SourceFile : 2 )
at io . requery . android . database . sqlite . SQLiteCursor . fillWindow ( SourceFile : 1 )
at io . requery . android . database . sqlite . SQLiteCursor . getCount ( SourceFile : 2 )
at eu . faircode . email . DaoAttachment_Impl$14 . call ( SourceFile : 16 )
at eu . faircode . email . DaoAttachment_Impl$14 . call ( SourceFile : 1 )
at androidx . room . RoomTrackingLiveData$1 . run ( SourceFile : 7 )
* /
return false ;
2020-06-16 05:29:55 +00:00
if ( ex instanceof SQLiteFullException ) // database or disk is full (code 13 SQLITE_FULL)
return false ;
2020-06-04 05:27:18 +00:00
if ( " android.util.SuperNotCalledException " . equals ( ex . getClass ( ) . getName ( ) ) )
/ *
android . util . SuperNotCalledException : Activity { eu . faircode . email / eu . faircode . email . ActivityView } did not call through to super . onResume ( )
at android . app . Activity . performResume ( Activity . java : 7304 )
at android . app . ActivityThread . performNewIntents ( ActivityThread . java : 3165 )
at android . app . ActivityThread . handleNewIntent ( ActivityThread . java : 3180 )
at android . app . servertransaction . NewIntentItem . execute ( NewIntentItem . java : 49 )
* /
2020-05-08 18:14:34 +00:00
return false ;
2020-06-05 09:04:18 +00:00
if ( " android.view.WindowManager$InvalidDisplayException " . equals ( ex . getClass ( ) . getName ( ) ) )
/ *
android . view . WindowManager$InvalidDisplayException : Unable to add window android . view . ViewRootImpl$W @d7b5a0b - - the specified display can not be found
at android . view . ViewRootImpl . setView ( ViewRootImpl . java : 854 )
at android . view . WindowManagerGlobal . addView ( WindowManagerGlobal . java : 356 )
at android . view . WindowManagerImpl . addView ( WindowManagerImpl . java : 93 )
at android . widget . PopupWindow . invokePopup ( PopupWindow . java : 1492 )
at android . widget . PopupWindow . showAsDropDown ( PopupWindow . java : 1342 )
at androidx . appcompat . widget . AppCompatPopupWindow . showAsDropDown ( SourceFile : 77 )
at androidx . core . widget . PopupWindowCompat . showAsDropDown ( SourceFile : 69 )
at androidx . appcompat . widget . ListPopupWindow . show ( SourceFile : 754 )
at androidx . appcompat . view . menu . CascadingMenuPopup . showMenu ( SourceFile : 486 )
at androidx . appcompat . view . menu . CascadingMenuPopup . show ( SourceFile : 265 )
at androidx . appcompat . view . menu . MenuPopupHelper . showPopup ( SourceFile : 290 )
at androidx . appcompat . view . menu . MenuPopupHelper . tryShow ( SourceFile : 177 )
at androidx . appcompat . widget . ActionMenuPresenter$OpenOverflowRunnable . run ( SourceFile : 792 )
* /
return false ;
2020-08-07 16:26:30 +00:00
StackTraceElement [ ] stack = ex . getStackTrace ( ) ;
2020-11-18 13:27:21 +00:00
if ( ex instanceof IndexOutOfBoundsException & &
stack . length > 0 & &
2020-08-14 07:21:10 +00:00
" android.text.TextLine " . equals ( stack [ 0 ] . getClassName ( ) ) & &
" measure " . equals ( stack [ 0 ] . getMethodName ( ) ) )
2020-08-07 16:26:30 +00:00
/ *
java . lang . IndexOutOfBoundsException : offset ( 21 ) should be less than line limit ( 20 )
at android . text . TextLine . measure ( Unknown Source : 233 )
at android . text . Layout . getHorizontal ( Unknown Source : 104 )
at android . text . Layout . getHorizontal ( Unknown Source : 4 )
at android . text . Layout . getPrimaryHorizontal ( Unknown Source : 4 )
at android . text . Layout . getPrimaryHorizontal ( Unknown Source : 1 )
at android . widget . Editor$ActionPinnedPopupWindow . computeLocalPosition ( Unknown Source : 275 )
at android . widget . Editor$PinnedPopupWindow . show ( Unknown Source : 15 )
at android . widget . Editor$ActionPinnedPopupWindow . show ( Unknown Source : 3 )
at android . widget . Editor$EmailAddPopupWindow . show ( Unknown Source : 92 )
at android . widget . Editor$1 . run ( Unknown Source : 6 )
at android . os . Handler . handleCallback ( Unknown Source : 2 )
* /
return false ;
2020-11-18 13:27:21 +00:00
if ( ex instanceof IllegalArgumentException & &
stack . length > 0 & &
2020-08-14 07:21:10 +00:00
" android.os.Parcel " . equals ( stack [ 0 ] . getClassName ( ) ) & &
( " createException " . equals ( stack [ 0 ] . getMethodName ( ) ) | |
" readException " . equals ( stack [ 0 ] . getMethodName ( ) ) ) )
2020-08-09 06:16:45 +00:00
/ *
java . lang . IllegalArgumentException
at android . os . Parcel . createException ( Parcel . java : 1954 )
at android . os . Parcel . readException ( Parcel . java : 1918 )
at android . os . Parcel . readException ( Parcel . java : 1868 )
at android . view . IWindowSession$Stub$Proxy . addToDisplay ( IWindowSession . java : 826 )
at android . view . ViewRootImpl . setView ( ViewRootImpl . java : 758 )
at android . view . WindowManagerGlobal . addView ( WindowManagerGlobal . java : 356 )
at android . view . WindowManagerImpl . addView ( WindowManagerImpl . java : 93 )
at android . app . ActivityThread . handleResumeActivity ( ActivityThread . java : 3906 )
java . lang . NullPointerException : Attempt to invoke virtual method ' int com . android . server . job . controllers . JobStatus . getUid ( ) ' on a null object reference
at android . os . Parcel . readException ( Parcel . java : 1605 )
at android . os . Parcel . readException ( Parcel . java : 1552 )
at android . app . job . IJobCallback$Stub$Proxy . jobFinished ( IJobCallback . java : 167 )
at android . app . job . JobService$JobHandler . handleMessage ( JobService . java : 147 )
at android . os . Handler . dispatchMessage ( Handler . java : 102 )
* /
return false ;
2020-11-18 13:27:21 +00:00
if ( ex instanceof NullPointerException & &
stack . length > 0 & &
2020-08-14 07:21:10 +00:00
" android.hardware.biometrics.BiometricPrompt " . equals ( stack [ 0 ] . getClassName ( ) ) )
2020-08-14 06:22:26 +00:00
/ *
java . lang . NullPointerException : Attempt to invoke virtual method ' java . lang . String android . hardware . fingerprint . FingerprintManager . getErrorString ( int , int ) ' on a null object reference
at android . hardware . biometrics . BiometricPrompt . lambda$sendError$0 ( BiometricPrompt . java : 490 )
at android . hardware . biometrics . - $$Lambda$BiometricPrompt$HqBGXtBUWNc - v8NoHYsj2gLfaRw . run ( Unknown Source : 6 )
at android . os . Handler . handleCallback ( Handler . java : 873 )
* /
return false ;
2020-11-18 13:27:21 +00:00
if ( ex instanceof NullPointerException & &
stack . length > 0 & &
" android.graphics.Rect " . equals ( stack [ 0 ] . getClassName ( ) ) & &
" set " . equals ( stack [ 0 ] . getMethodName ( ) ) )
/ *
java . lang . NullPointerException : Attempt to read from field ' int android . graphics . Rect . left ' on a null object reference
at android . graphics . Rect . set ( Rect . java : 371 )
at android . view . InsetsState . readFromParcel ( InsetsState . java : 453 )
at android . view . IWindowSession$Stub$Proxy . addToDisplay ( IWindowSession . java : 1264 )
at android . view . ViewRootImpl . setView ( ViewRootImpl . java : 865 )
at android . view . WindowManagerGlobal . addView ( WindowManagerGlobal . java : 387 )
at android . view . WindowManagerImpl . addView ( WindowManagerImpl . java : 96 )
at android . app . ActivityThread . handleResumeActivity ( ActivityThread . java : 4297 )
* /
return false ;
2021-02-03 08:26:12 +00:00
if ( ex instanceof NullPointerException & &
stack . length > 0 & &
" android.app.ActivityThread " . equals ( stack [ 0 ] . getClassName ( ) ) & &
" handleStopActivity " . equals ( stack [ 0 ] . getMethodName ( ) ) )
/ *
Android : 6 . 0 . 1
java . lang . NullPointerException : Attempt to read from field ' android . app . Activity android . app . ActivityThread$ActivityClientRecord . activity ' on a null object reference
at android . app . ActivityThread . handleStopActivity ( ActivityThread . java : 4766 )
at android . app . ActivityThread . access$1400 ( ActivityThread . java : 221 )
at android . app . ActivityThread$H . handleMessage ( ActivityThread . java : 1823 )
at android . os . Handler . dispatchMessage ( Handler . java : 102 )
at android . os . Looper . loop ( Looper . java : 158 )
at android . app . ActivityThread . main ( ActivityThread . java : 7224 )
* /
return false ;
2021-12-29 16:47:07 +00:00
if ( ex instanceof NullPointerException & &
ex . getCause ( ) instanceof RemoteException )
/ *
java . lang . NullPointerException : Attempt to invoke virtual method ' boolean com . android . server . autofill . RemoteFillService$PendingRequest . cancel ( ) ' on a null object reference
at android . os . Parcel . createException ( Parcel . java : 1956 )
at android . os . Parcel . readException ( Parcel . java : 1918 )
at android . os . Parcel . readException ( Parcel . java : 1868 )
at android . app . IActivityManager$Stub$Proxy . reportAssistContextExtras ( IActivityManager . java : 7079 )
at android . app . ActivityThread . handleRequestAssistContextExtras ( ActivityThread . java : 3338 )
at android . app . ActivityThread$H . handleMessage ( ActivityThread . java : 1839 )
at android . os . Handler . dispatchMessage ( Handler . java : 106 )
at android . os . Looper . loop ( Looper . java : 193 )
at android . app . ActivityThread . main ( ActivityThread . java : 6971 )
at java . lang . reflect . Method . invoke ( Native Method )
at com . android . internal . os . RuntimeInit$MethodAndArgsCaller . run ( RuntimeInit . java : 493 )
at com . android . internal . os . ZygoteInit . main ( ZygoteInit . java : 865 )
Caused by : android . os . RemoteException : Remote stack trace :
at com . android . server . autofill . RemoteFillService . cancelCurrentRequest ( RemoteFillService . java : 177 )
at com . android . server . autofill . Session . cancelCurrentRequestLocked ( Session . java : 465 )
at com . android . server . autofill . Session . access$1000 ( Session . java : 118 )
at com . android . server . autofill . Session$1 . onHandleAssistData ( Session . java : 322 )
at com . android . server . am . ActivityManagerService . reportAssistContextExtras ( ActivityManagerService . java : 14510 )
* /
return false ;
2020-11-18 13:27:21 +00:00
if ( ex instanceof IndexOutOfBoundsException & &
stack . length > 0 & &
" android.text.SpannableStringInternal " . equals ( stack [ 0 ] . getClassName ( ) ) & &
" checkRange " . equals ( stack [ 0 ] . getMethodName ( ) ) )
2020-08-14 07:17:34 +00:00
/ *
java . lang . IndexOutOfBoundsException : setSpan ( - 1 . . . - 1 ) starts before 0
at android . text . SpannableStringInternal . checkRange ( SpannableStringInternal . java : 478 )
at android . text . SpannableStringInternal . setSpan ( SpannableStringInternal . java : 189 )
at android . text . SpannableStringInternal . setSpan ( SpannableStringInternal . java : 178 )
at android . text . SpannableString . setSpan ( SpannableString . java : 60 )
at android . text . Selection . setSelection ( Selection . java : 93 )
at android . text . Selection . setSelection ( Selection . java : 77 )
at android . widget . Editor$SelectionHandleView . updateSelection ( Editor . java : 5281 )
at android . widget . Editor$HandleView . positionAtCursorOffset ( Editor . java : 4676 )
at android . widget . Editor$SelectionHandleView . positionAtCursorOffset ( Editor . java : 5466 )
at android . widget . Editor$SelectionHandleView . positionAndAdjustForCrossingHandles ( Editor . java : 5528 )
at android . widget . Editor$SelectionHandleView . updatePosition ( Editor . java : 5458 )
at android . widget . Editor$HandleView . onTouchEvent ( Editor . java : 4989 )
at android . widget . Editor$SelectionHandleView . onTouchEvent ( Editor . java : 5472 )
at android . view . View . dispatchTouchEvent ( View . java : 12545 )
at android . view . ViewGroup . dispatchTransformedTouchEvent ( ViewGroup . java : 3083 )
at android . view . ViewGroup . dispatchTouchEvent ( ViewGroup . java : 2741 )
at android . widget . PopupWindow$PopupDecorView . dispatchTouchEvent ( PopupWindow . java : 2407 )
at android . view . View . dispatchPointerEvent ( View . java : 12789 )
* /
return false ;
2020-11-09 10:42:35 +00:00
if ( ex instanceof IndexOutOfBoundsException ) {
for ( StackTraceElement ste : stack )
if ( " android.widget.NumberPicker$SetSelectionCommand " . equals ( ste . getClassName ( ) ) & &
" run " . equals ( ste . getMethodName ( ) ) )
return false ;
/ *
java . lang . IndexOutOfBoundsException : setSpan ( 2 . . . 2 ) ends beyond length 0
at android . text . SpannableStringBuilder . checkRange ( SpannableStringBuilder . java : 1265 )
at android . text . SpannableStringBuilder . setSpan ( SpannableStringBuilder . java : 684 )
at android . text . SpannableStringBuilder . setSpan ( SpannableStringBuilder . java : 677 )
at android . text . Selection . setSelection ( Selection . java : 76 )
at android . widget . TextView . semSetSelection ( TextView . java : 11550 )
at android . widget . EditText . setSelection ( EditText . java : 118 )
at android . widget . NumberPicker$SetSelectionCommand . run ( NumberPicker . java : 2246 )
at android . os . Handler . handleCallback ( Handler . java : 751 )
* /
}
2021-02-22 09:26:39 +00:00
if ( ex instanceof IndexOutOfBoundsException ) {
for ( StackTraceElement ste : stack )
if ( " android.graphics.Paint " . equals ( ste . getClassName ( ) ) & &
" getTextRunCursor " . equals ( ste . getMethodName ( ) ) )
return false ;
/ *
Android 6 . 0 . 1
java . lang . IndexOutOfBoundsException
at android . graphics . Paint . getTextRunCursor ( Paint . java : 2160 )
at android . graphics . Paint . getTextRunCursor ( Paint . java : 2112 )
at android . widget . Editor . getNextCursorOffset ( Editor . java : 924 )
at android . widget . Editor . access$4700 ( Editor . java : 126 )
at android . widget . Editor$SelectionEndHandleView . positionAndAdjustForCrossingHandles ( Editor . java : 4708 )
at android . widget . Editor$SelectionEndHandleView . updatePosition ( Editor . java : 4692 )
at android . widget . Editor$HandleView . onTouchEvent ( Editor . java : 4012 )
at android . widget . Editor$SelectionEndHandleView . onTouchEvent ( Editor . java : 4726 )
at android . view . View . dispatchTouchEvent ( View . java : 9377 )
at android . view . ViewGroup . dispatchTransformedTouchEvent ( ViewGroup . java : 2554 )
at android . view . ViewGroup . dispatchTouchEvent ( ViewGroup . java : 2255 )
at android . widget . PopupWindow$PopupDecorView . dispatchTouchEvent ( PopupWindow . java : 2015 )
at android . view . View . dispatchPointerEvent ( View . java : 9597 )
at android . view . ViewRootImpl$ViewPostImeInputStage . processPointerEvent ( ViewRootImpl . java : 4234 )
at android . view . ViewRootImpl$ViewPostImeInputStage . onProcess ( ViewRootImpl . java : 4100 )
at android . view . ViewRootImpl$InputStage . deliver ( ViewRootImpl . java : 3646 )
at android . view . ViewRootImpl$InputStage . onDeliverToNext ( ViewRootImpl . java : 3699 )
at android . view . ViewRootImpl$InputStage . forward ( ViewRootImpl . java : 3665 )
at android . view . ViewRootImpl$AsyncInputStage . forward ( ViewRootImpl . java : 3791 )
at android . view . ViewRootImpl$InputStage . apply ( ViewRootImpl . java : 3673 )
at android . view . ViewRootImpl$AsyncInputStage . apply ( ViewRootImpl . java : 3848 )
at android . view . ViewRootImpl$InputStage . deliver ( ViewRootImpl . java : 3646 )
at android . view . ViewRootImpl$InputStage . onDeliverToNext ( ViewRootImpl . java : 3699 )
at android . view . ViewRootImpl$InputStage . forward ( ViewRootImpl . java : 3665 )
at android . view . ViewRootImpl$InputStage . apply ( ViewRootImpl . java : 3673 )
at android . view . ViewRootImpl$InputStage . deliver ( ViewRootImpl . java : 3646 )
at android . view . ViewRootImpl . deliverInputEvent ( ViewRootImpl . java : 5926 )
at android . view . ViewRootImpl . doProcessInputEvents ( ViewRootImpl . java : 5900 )
at android . view . ViewRootImpl . enqueueInputEvent ( ViewRootImpl . java : 5861 )
at android . view . ViewRootImpl$WindowInputEventReceiver . onInputEvent ( ViewRootImpl . java : 6029 )
at android . view . InputEventReceiver . dispatchInputEvent ( InputEventReceiver . java : 185 )
at android . view . InputEventReceiver . nativeConsumeBatchedInputEvents ( Native Method )
at android . view . InputEventReceiver . consumeBatchedInputEvents ( InputEventReceiver . java : 176 )
at android . view . ViewRootImpl . doConsumeBatchedInput ( ViewRootImpl . java : 6000 )
at android . view . ViewRootImpl$ConsumeBatchedInputRunnable . run ( ViewRootImpl . java : 6052 )
at android . view . Choreographer$CallbackRecord . run ( Choreographer . java : 858 )
at android . view . Choreographer . doCallbacks ( Choreographer . java : 670 )
at android . view . Choreographer . doFrame ( Choreographer . java : 600 )
at android . view . Choreographer$FrameDisplayEventReceiver . run ( Choreographer . java : 844 )
at android . os . Handler . handleCallback ( Handler . java : 739 )
* /
}
2021-05-25 13:16:19 +00:00
if ( ex instanceof StringIndexOutOfBoundsException ) {
for ( StackTraceElement ste : stack )
if ( " android.widget.Editor$SuggestionsPopupWindow " . equals ( ste . getClassName ( ) ) & &
" highlightTextDifferences " . equals ( ste . getMethodName ( ) ) )
return false ;
/ *
Android 7 . 0 Samsung
java . lang . StringIndexOutOfBoundsException : length = 175 ; regionStart = 174 ; regionLength = 7
at java . lang . String . substring ( String . java : 1931 )
at android . widget . Editor$SuggestionsPopupWindow . highlightTextDifferences ( Editor . java : 4002 )
at android . widget . Editor$SuggestionsPopupWindow . updateSuggestions ( Editor . java : 3933 )
at android . widget . Editor$SuggestionsPopupWindow . show ( Editor . java : 3836 )
at android . widget . Editor . replace ( Editor . java : 428 )
at android . widget . Editor$3 . run ( Editor . java : 2362 )
at android . os . Handler . handleCallback ( Handler . java : 751 )
at android . os . Handler . dispatchMessage ( Handler . java : 95 )
at android . os . Looper . loop ( Looper . java : 154 )
at android . app . ActivityThread . main ( ActivityThread . java : 6780 )
at java . lang . reflect . Method . invoke ( Native Method )
at com . android . internal . os . ZygoteInit$MethodAndArgsCaller . run ( ZygoteInit . java : 1500 )
at com . android . internal . os . ZygoteInit . main ( ZygoteInit . java : 1390 )
* /
}
2020-11-18 13:27:21 +00:00
if ( ex instanceof IllegalArgumentException & &
stack . length > 0 & &
2020-09-26 05:53:56 +00:00
" android.text.method.WordIterator " . equals ( stack [ 0 ] . getClassName ( ) ) & &
" checkOffsetIsValid " . equals ( stack [ 0 ] . getMethodName ( ) ) )
/ *
https : //issuetracker.google.com/issues/37068143
2020-09-26 08:22:23 +00:00
https : //android.googlesource.com/platform/frameworks/base/+/refs/heads/marshmallow-release/core/java/android/text/method/WordIterator.java
2020-09-26 05:53:56 +00:00
java . lang . IllegalArgumentException : Invalid offset : - 1 . Valid range is [ 0 , 1673 ]
at android . text . method . WordIterator . checkOffsetIsValid ( WordIterator . java : 380 )
at android . text . method . WordIterator . isBoundary ( WordIterator . java : 101 )
at android . widget . Editor$SelectionStartHandleView . positionAtCursorOffset ( Editor . java : 4287 )
at android . widget . Editor$HandleView . updatePosition ( Editor . java : 3735 )
at android . widget . Editor$PositionListener . onPreDraw ( Editor . java : 2512 )
at android . view . ViewTreeObserver . dispatchOnPreDraw ( ViewTreeObserver . java : 944 )
at android . view . ViewRootImpl . performTraversals ( ViewRootImpl . java : 2412 )
at android . view . ViewRootImpl . doTraversal ( ViewRootImpl . java : 1321 )
at android . view . ViewRootImpl$TraversalRunnable . run ( ViewRootImpl . java : 6763 )
at android . view . Choreographer$CallbackRecord . run ( Choreographer . java : 894 )
at android . view . Choreographer . doCallbacks ( Choreographer . java : 696 )
at android . view . Choreographer . doFrame ( Choreographer . java : 631 )
at android . view . Choreographer$FrameDisplayEventReceiver . run ( Choreographer . java : 880 )
at android . os . Handler . handleCallback ( Handler . java : 815 )
* /
return false ;
2021-05-24 09:11:57 +00:00
if ( ex instanceof IllegalArgumentException & & ex . getCause ( ) ! = null ) {
for ( StackTraceElement ste : ex . getCause ( ) . getStackTrace ( ) )
if ( " android.view.textclassifier.TextClassifierImpl " . equals ( ste . getClassName ( ) ) & &
" validateInput " . equals ( ste . getMethodName ( ) ) )
2021-06-01 05:52:30 +00:00
return true ;
2021-05-24 09:11:57 +00:00
/ *
java . lang . RuntimeException : An error occurred while executing doInBackground ( )
at android . os . AsyncTask$3 . done ( AsyncTask . java : 353 )
at java . util . concurrent . FutureTask . finishCompletion ( FutureTask . java : 383 )
at java . util . concurrent . FutureTask . setException ( FutureTask . java : 252 )
at java . util . concurrent . FutureTask . run ( FutureTask . java : 271 )
at android . os . AsyncTask$SerialExecutor$1 . run ( AsyncTask . java : 245 )
at java . util . concurrent . ThreadPoolExecutor . runWorker ( ThreadPoolExecutor . java : 1162 )
at java . util . concurrent . ThreadPoolExecutor$Worker . run ( ThreadPoolExecutor . java : 636 )
at java . lang . Thread . run ( Thread . java : 764 )
Caused by : java . lang . IllegalArgumentException
at com . android . internal . util . Preconditions . checkArgument ( Preconditions . java : 33 )
at android . view . textclassifier . TextClassifierImpl . validateInput ( TextClassifierImpl . java : 484 )
at android . view . textclassifier . TextClassifierImpl . classifyText ( TextClassifierImpl . java : 144 )
at android . widget . SelectionActionModeHelper$TextClassificationHelper . classifyText ( SelectionActionModeHelper . java : 465 )
at android . widget . SelectionActionModeHelper . - android_widget_SelectionActionModeHelper - mthref - 1 ( SelectionActionModeHelper . java : 83 )
at android . widget . - $Lambda$tTszxdFZ0V9nXhnBpPsqeBMO0fw$5 . $m$0 ( Unknown : 4 )
at android . widget . - $Lambda$tTszxdFZ0V9nXhnBpPsqeBMO0fw$5 . get ( Unknown )
at android . widget . SelectionActionModeHelper$TextClassificationAsyncTask . doInBackground ( SelectionActionModeHelper . java : 366 )
at android . widget . SelectionActionModeHelper$TextClassificationAsyncTask . doInBackground ( SelectionActionModeHelper . java : 361 )
at android . os . AsyncTask$2 . call ( AsyncTask . java : 333 )
at java . util . concurrent . FutureTask . run ( FutureTask . java : 266 )
at android . os . AsyncTask$SerialExecutor$1 . run ( AsyncTask . java : 245 )
at java . util . concurrent . ThreadPoolExecutor . runWorker ( ThreadPoolExecutor . java : 1162 )
at java . util . concurrent . ThreadPoolExecutor$Worker . run ( ThreadPoolExecutor . java : 636 )
at java . lang . Thread . run ( Thread . java : 764 )
* /
}
2020-11-18 13:27:21 +00:00
if ( ex instanceof NullPointerException & &
stack . length > 0 & &
2020-10-10 05:40:41 +00:00
" view.AccessibilityInteractionController " . equals ( stack [ 0 ] . getClassName ( ) ) & &
" applyAppScaleAndMagnificationSpecIfNeeded " . equals ( stack [ 0 ] . getMethodName ( ) ) )
/ *
java . lang . NullPointerException : Attempt to invoke virtual method ' void android . graphics . RectF . scale ( float ) ' on a null object reference
at android . view . AccessibilityInteractionController . applyAppScaleAndMagnificationSpecIfNeeded ( AccessibilityInteractionController . java : 872 )
at android . view . AccessibilityInteractionController . applyAppScaleAndMagnificationSpecIfNeeded ( AccessibilityInteractionController . java : 796 )
at android . view . AccessibilityInteractionController . updateInfosForViewportAndReturnFindNodeResult ( AccessibilityInteractionController . java : 924 )
at android . view . AccessibilityInteractionController . findAccessibilityNodeInfoByAccessibilityIdUiThread ( AccessibilityInteractionController . java : 345 )
at android . view . AccessibilityInteractionController . access$400 ( AccessibilityInteractionController . java : 75 )
at android . view . AccessibilityInteractionController$PrivateHandler . handleMessage ( AccessibilityInteractionController . java : 1393 )
at android . os . Handler . dispatchMessage ( Handler . java : 107 )
* /
return false ;
2021-01-02 18:29:00 +00:00
if ( ex instanceof NullPointerException ) {
for ( StackTraceElement ste : stack )
if ( " android.app.job.IJobCallback$Stub$Proxy " . equals ( ste . getClassName ( ) ) & &
" jobFinished " . equals ( ste . getMethodName ( ) ) )
return false ;
/ *
java . lang . NullPointerException : Attempt to invoke virtual method ' int com . android . server . job . controllers . JobStatus . getUid ( ) ' on a null object reference
at android . os . Parcel . readException ( Parcel . java : 1605 )
at android . os . Parcel . readException ( Parcel . java : 1552 )
at android . app . job . IJobCallback$Stub$Proxy . jobFinished ( IJobCallback . java : 167 )
at android . app . job . JobService$JobHandler . handleMessage ( JobService . java : 147 )
at android . os . Handler . dispatchMessage ( Handler . java : 111 )
at android . os . Looper . loop ( Looper . java : 207 )
at android . app . ActivityThread . main ( ActivityThread . java : 5697 )
at java . lang . reflect . Method . invoke ( Native Method )
at com . android . internal . os . ZygoteInit$MethodAndArgsCaller . run ( ZygoteInit . java : 905 )
at com . android . internal . os . ZygoteInit . main ( ZygoteInit . java : 766 )
* /
}
2020-11-24 08:49:18 +00:00
if ( ex instanceof IllegalStateException & &
stack . length > 0 & &
" android.database.sqlite.SQLiteSession " . equals ( stack [ 0 ] . getClassName ( ) ) & &
" throwIfNoTransaction " . equals ( stack [ 0 ] . getMethodName ( ) ) )
/ *
java . lang . IllegalStateException : Cannot perform this operation because there is no current transaction .
at android . database . sqlite . SQLiteSession . throwIfNoTransaction ( SQLiteSession . java : 917 )
at android . database . sqlite . SQLiteSession . endTransaction ( SQLiteSession . java : 400 )
at android . database . sqlite . SQLiteDatabase . endTransaction ( SQLiteDatabase . java : 585 )
at androidx . sqlite . db . framework . FrameworkSQLiteDatabase . endTransaction ( SourceFile : 1 )
at androidx . room . RoomDatabase . endTransaction ( SourceFile : 1 )
at androidx . work . impl . WorkerWrapper . runWorker ( SourceFile : 66 )
at androidx . work . impl . WorkerWrapper . run ( SourceFile : 3 )
at androidx . work . impl . utils . SerialExecutor$Task . run ( SourceFile : 1 )
* /
return false ;
2020-12-02 18:42:33 +00:00
if ( ex instanceof IllegalArgumentException & &
stack . length > 0 & &
" android.widget.SmartSelectSprite " . equals ( stack [ 0 ] . getClassName ( ) ) & &
" startAnimation " . equals ( stack [ 0 ] . getMethodName ( ) ) )
/ *
java . lang . IllegalArgumentException : Center point is not inside any of the rectangles !
at android . widget . SmartSelectSprite . startAnimation ( SmartSelectSprite . java : 392 )
at android . widget . SelectionActionModeHelper . startSelectionActionModeWithSmartSelectAnimation ( SelectionActionModeHelper . java : 319 )
at android . widget . SelectionActionModeHelper . lambda$l1f1_V5lw6noQxI_3u11qF753Iw ( Unknown Source : 0 )
at android . widget . - $$Lambda$SelectionActionModeHelper$l1f1_V5lw6noQxI_3u11qF753Iw . accept ( Unknown Source : 4 )
at android . widget . SelectionActionModeHelper$TextClassificationAsyncTask . onPostExecute ( SelectionActionModeHelper . java : 910 )
at android . widget . SelectionActionModeHelper$TextClassificationAsyncTask . onPostExecute ( SelectionActionModeHelper . java : 864 )
at android . os . AsyncTask . finish ( AsyncTask . java : 695 )
at android . os . AsyncTask . access$600 ( AsyncTask . java : 180 )
at android . os . AsyncTask$InternalHandler . handleMessage ( AsyncTask . java : 712 )
at android . os . Handler . dispatchMessage ( Handler . java : 106 )
* /
return false ;
2020-09-10 16:37:39 +00:00
if ( ex instanceof InflateException )
/ *
android . view . InflateException : Binary XML file line # 7 : Binary XML file line # 7 : Error inflating class < unknown >
Caused by : android . view . InflateException : Binary XML file line # 7 : Error inflating class < unknown >
Caused by : java . lang . reflect . InvocationTargetException
at java . lang . reflect . Constructor . newInstance0 ( Native Method )
at java . lang . reflect . Constructor . newInstance ( Constructor . java : 343 )
at android . view . LayoutInflater . createView ( LayoutInflater . java : 686 )
at android . view . LayoutInflater . createViewFromTag ( LayoutInflater . java : 829 )
at android . view . LayoutInflater . createViewFromTag ( LayoutInflater . java : 769 )
at android . view . LayoutInflater . rInflate ( LayoutInflater . java : 902 )
at android . view . LayoutInflater . rInflateChildren ( LayoutInflater . java : 863 )
at android . view . LayoutInflater . inflate ( LayoutInflater . java : 554 )
at android . view . LayoutInflater . inflate ( LayoutInflater . java : 461 )
* /
return false ;
2021-02-04 13:44:19 +00:00
for ( StackTraceElement ste : stack ) {
String clazz = ste . getClassName ( ) ;
if ( clazz ! = null & & clazz . startsWith ( " org.chromium.net. " ) )
return false ;
}
2021-02-19 06:17:52 +00:00
if ( ex instanceof SecurityException & &
ex . getMessage ( ) ! = null & &
ex . getMessage ( ) . contains ( " com.opera.browser " ) )
/ *
java . lang . SecurityException : Permission Denial : starting Intent { act = android . intent . action . VIEW dat = https : //tracking.dpd.de/... cmp=com.opera.browser/.leanplum.LeanplumCatchActivity (has extras) } from ProcessRecord{3d9efb1 6332:eu.faircode.email/u0a54} (pid=6332, uid=10054) not exported from uid 10113
at android . os . Parcel . readException ( Parcel . java : 1951 )
at android . os . Parcel . readException ( Parcel . java : 1897 )
at android . app . IActivityManager$Stub$Proxy . startActivity ( IActivityManager . java : 4430 )
at android . app . Instrumentation . execStartActivity ( Instrumentation . java : 1610 )
at android . app . ContextImpl . startActivity ( ContextImpl . java : 862 )
at android . app . ContextImpl . startActivity ( ContextImpl . java : 839 )
at android . view . textclassifier . TextClassification . lambda$ - android_view_textclassifier_TextClassification_5020 ( TextClassification . java : 166 )
at android . view . textclassifier . - $Lambda$mxr44OLodDKdoE5ddAZvMdsFssQ . $m$0 ( Unknown Source : 8 )
at android . view . textclassifier . - $Lambda$mxr44OLodDKdoE5ddAZvMdsFssQ . onClick ( Unknown Source : 0 )
at org . chromium . content . browser . selection . SelectionPopupControllerImpl . m ( chromium - SystemWebViewGoogle . aab - stable - 432415203 : 17 )
at y5 . onActionItemClicked ( chromium - SystemWebViewGoogle . aab - stable - 432415203 : 20 )
at Bn . onActionItemClicked ( chromium - SystemWebViewGoogle . aab - stable - 432415203 : 1 )
at com . android . internal . policy . DecorView$ActionModeCallback2Wrapper . onActionItemClicked ( DecorView . java : 2472 )
at com . android . internal . view . FloatingActionMode$3 . onMenuItemSelected ( FloatingActionMode . java : 101 )
at com . android . internal . view . menu . MenuBuilder . dispatchMenuItemSelected ( MenuBuilder . java : 761 )
at com . android . internal . view . menu . MenuItemImpl . invoke ( MenuItemImpl . java : 167 )
at com . android . internal . view . menu . MenuBuilder . performItemAction ( MenuBuilder . java : 908 )
at com . android . internal . view . menu . MenuBuilder . performItemAction ( MenuBuilder . java : 898 )
at com . android . internal . view . FloatingActionMode . lambda$ - com_android_internal_view_FloatingActionMode_5176 ( FloatingActionMode . java : 129 )
at com . android . internal . view . - $Lambda$IoKM3AcgDw3Ok5aFi0zlym2p3IA . $m$0 ( Unknown Source : 4 )
at com . android . internal . view . - $Lambda$IoKM3AcgDw3Ok5aFi0zlym2p3IA . onMenuItemClick ( Unknown Source : 0 )
at com . android . internal . widget . FloatingToolbar$FloatingToolbarPopup$2 . onClick ( FloatingToolbar . java : 423 )
at android . view . View . performClick ( View . java : 6320 )
at android . view . View$PerformClick . run ( View . java : 25087 )
* /
return false ;
2021-01-31 11:25:10 +00:00
if ( isDead ( ex ) )
return false ;
2019-08-12 11:17:55 +00:00
if ( BuildConfig . BETA_RELEASE )
return true ;
while ( ex ! = null ) {
2021-02-10 17:24:45 +00:00
for ( StackTraceElement ste : stack )
2019-08-12 11:17:55 +00:00
if ( ste . getClassName ( ) . startsWith ( BuildConfig . APPLICATION_ID ) )
return true ;
ex = ex . getCause ( ) ;
}
return false ;
}
2021-01-31 11:25:10 +00:00
private static boolean isDead ( Throwable ex ) {
if ( Build . VERSION . SDK_INT > = Build . VERSION_CODES . M ) {
/ *
java . lang . RuntimeException : Failure from system
at android . app . ContextImpl . bindServiceCommon ( ContextImpl . java : 1327 )
at android . app . ContextImpl . bindService ( ContextImpl . java : 1286 )
at android . content . ContextWrapper . bindService ( ContextWrapper . java : 604 )
at android . content . ContextWrapper . bindService ( ContextWrapper . java : 604 )
at hq . run ( PG : 15 )
at java . lang . Thread . run ( Thread . java : 818 )
Caused by : android . os . DeadObjectException
at android . os . BinderProxy . transactNative ( Native Method )
at android . os . BinderProxy . transact ( Binder . java : 503 )
at android . app . ActivityManagerProxy . bindService ( ActivityManagerNative . java : 3783 )
at android . app . ContextImpl . bindServiceCommon ( ContextImpl . java : 1317 )
* /
Throwable cause = ex ;
while ( cause ! = null ) {
if ( cause instanceof DeadObjectException )
return true ;
cause = cause . getCause ( ) ;
}
}
if ( Build . VERSION . SDK_INT > = Build . VERSION_CODES . N ) {
Throwable cause = ex ;
while ( cause ! = null ) {
if ( cause instanceof DeadSystemException )
return true ;
cause = cause . getCause ( ) ;
}
}
return false ;
}
2019-12-06 07:50:46 +00:00
static String formatThrowable ( Throwable ex ) {
return formatThrowable ( ex , true ) ;
}
2020-09-21 06:13:20 +00:00
static String formatThrowable ( Throwable ex , boolean sanitize ) {
return formatThrowable ( ex , " " , sanitize ) ;
2019-12-06 07:50:46 +00:00
}
static String formatThrowable ( Throwable ex , String separator , boolean sanitize ) {
2020-10-30 07:44:02 +00:00
if ( ex = = null )
return null ;
2019-12-06 07:50:46 +00:00
if ( sanitize ) {
if ( ex instanceof MessageRemovedException )
return null ;
2019-12-06 08:00:31 +00:00
if ( ex instanceof AuthenticationFailedException & &
ex . getCause ( ) instanceof SocketException )
return null ;
2021-11-24 07:23:27 +00:00
if ( ex instanceof ProtocolException & &
ex . getCause ( ) instanceof InterruptedException )
return null ; // Interrupted waitIfIdle
2019-12-06 08:09:14 +00:00
if ( ex instanceof MessagingException & &
2021-08-06 10:23:16 +00:00
( " Not connected " . equals ( ex . getMessage ( ) ) | | // POP3
" connection failure " . equals ( ex . getMessage ( ) ) | |
2019-12-06 08:09:14 +00:00
" failed to create new store connection " . equals ( ex . getMessage ( ) ) ) )
return null ;
2019-12-06 07:50:46 +00:00
if ( ex instanceof MessagingException & &
ex . getCause ( ) instanceof ConnectionException & &
ex . getCause ( ) . getMessage ( ) ! = null & &
( ex . getCause ( ) . getMessage ( ) . contains ( " Read error " ) | |
2019-12-06 08:02:11 +00:00
ex . getCause ( ) . getMessage ( ) . contains ( " Write error " ) | |
2020-01-09 09:49:53 +00:00
ex . getCause ( ) . getMessage ( ) . contains ( " Unexpected end of ZLIB input stream " ) | |
2019-12-06 08:02:11 +00:00
ex . getCause ( ) . getMessage ( ) . contains ( " Socket is closed " ) ) )
2019-12-06 07:50:46 +00:00
return null ;
// javax.mail.MessagingException: AU3 BAD User is authenticated but not connected.;
// nested exception is:
// com.sun.mail.iap.BadCommandException: AU3 BAD User is authenticated but not connected.
// javax.mail.MessagingException: AU3 BAD User is authenticated but not connected.;
// nested exception is:
// com.sun.mail.iap.BadCommandException: AU3 BAD User is authenticated but not connected.
// at com.sun.mail.imap.IMAPFolder.logoutAndThrow(SourceFile:1156)
// at com.sun.mail.imap.IMAPFolder.open(SourceFile:1063)
// at com.sun.mail.imap.IMAPFolder.open(SourceFile:977)
// at eu.faircode.email.ServiceSynchronize.monitorAccount(SourceFile:890)
// at eu.faircode.email.ServiceSynchronize.access$1500(SourceFile:85)
// at eu.faircode.email.ServiceSynchronize$7$1.run(SourceFile:627)
// at java.lang.Thread.run(Thread.java:764)
// Caused by: com.sun.mail.iap.BadCommandException: AU3 BAD User is authenticated but not connected.
// at com.sun.mail.iap.Protocol.handleResult(SourceFile:415)
// at com.sun.mail.imap.protocol.IMAPProtocol.select(SourceFile:1230)
// at com.sun.mail.imap.IMAPFolder.open(SourceFile:1034)
if ( ex instanceof MessagingException & &
ex . getCause ( ) instanceof BadCommandException & &
ex . getCause ( ) . getMessage ( ) ! = null & &
ex . getCause ( ) . getMessage ( ) . contains ( " User is authenticated but not connected " ) )
return null ;
if ( ex instanceof IOException & &
ex . getCause ( ) instanceof MessageRemovedException )
return null ;
if ( ex instanceof ConnectionException )
return null ;
2019-12-09 07:37:08 +00:00
if ( ex instanceof StoreClosedException | |
2021-07-27 16:32:10 +00:00
ex instanceof FolderClosedException | |
ex instanceof FolderClosedIOException | |
ex instanceof OperationCanceledException )
2019-12-06 07:50:46 +00:00
return null ;
if ( ex instanceof IllegalStateException & &
2021-12-01 18:33:29 +00:00
( TOKEN_REFRESH_REQUIRED . equals ( ex . getMessage ( ) ) | |
2021-11-28 10:15:22 +00:00
" Not connected " . equals ( ex . getMessage ( ) ) | |
2019-12-06 07:50:46 +00:00
" This operation is not allowed on a closed folder " . equals ( ex . getMessage ( ) ) ) )
return null ;
}
StringBuilder sb = new StringBuilder ( ) ;
if ( BuildConfig . DEBUG )
sb . append ( ex . toString ( ) ) ;
else
sb . append ( ex . getMessage ( ) = = null ? ex . getClass ( ) . getName ( ) : ex . getMessage ( ) ) ;
Throwable cause = ex . getCause ( ) ;
while ( cause ! = null ) {
if ( BuildConfig . DEBUG )
sb . append ( separator ) . append ( cause . toString ( ) ) ;
else
sb . append ( separator ) . append ( cause . getMessage ( ) = = null ? cause . getClass ( ) . getName ( ) : cause . getMessage ( ) ) ;
cause = cause . getCause ( ) ;
}
return sb . toString ( ) ;
}
2019-08-12 14:18:41 +00:00
static void writeCrashLog ( Context context , Throwable ex ) {
2019-08-12 11:17:55 +00:00
File file = new File ( context . getCacheDir ( ) , " crash.log " ) ;
Log . w ( " Writing exception to " + file ) ;
try ( FileWriter out = new FileWriter ( file , true ) ) {
2021-09-28 20:16:03 +00:00
out . write ( BuildConfig . VERSION_NAME + BuildConfig . REVISION + " " + new Date ( ) + " \ r \ n " ) ;
2019-08-12 11:17:55 +00:00
out . write ( ex + " \ r \ n " + android . util . Log . getStackTraceString ( ex ) + " \ r \ n " ) ;
} catch ( IOException e ) {
Log . e ( e ) ;
}
}
2021-01-03 09:58:51 +00:00
static EntityMessage getDebugInfo ( Context context , int title , Throwable ex , String log ) throws IOException , JSONException {
2019-05-12 17:14:34 +00:00
StringBuilder sb = new StringBuilder ( ) ;
sb . append ( context . getString ( title ) ) . append ( " \ n \ n \ n \ n " ) ;
sb . append ( getAppInfo ( context ) ) ;
if ( ex ! = null )
sb . append ( ex . toString ( ) ) . append ( " \ n " ) . append ( android . util . Log . getStackTraceString ( ex ) ) ;
if ( log ! = null )
sb . append ( log ) ;
2021-08-15 19:28:33 +00:00
String body = " <pre class= \" fairemail_debug_info \" > " + TextUtils . htmlEncode ( sb . toString ( ) ) + " </pre> " ;
2019-05-12 17:14:34 +00:00
EntityMessage draft ;
DB db = DB . getInstance ( context ) ;
try {
db . beginTransaction ( ) ;
2019-09-23 08:04:46 +00:00
List < TupleIdentityEx > identities = db . identity ( ) . getComposableIdentities ( null ) ;
if ( identities = = null | | identities . size ( ) = = 0 )
2020-08-20 21:18:55 +00:00
throw new IllegalArgumentException ( context . getString ( R . string . title_no_composable ) ) ;
2019-09-23 08:04:46 +00:00
EntityIdentity identity = identities . get ( 0 ) ;
EntityFolder drafts = db . folder ( ) . getFolderByType ( identity . account , EntityFolder . DRAFTS ) ;
2020-11-24 20:28:42 +00:00
if ( drafts = = null )
throw new IllegalArgumentException ( context . getString ( R . string . title_no_drafts ) ) ;
2019-05-12 17:14:34 +00:00
draft = new EntityMessage ( ) ;
draft . account = drafts . account ;
draft . folder = drafts . id ;
2019-09-23 08:04:46 +00:00
draft . identity = identity . id ;
2019-05-12 17:14:34 +00:00
draft . msgid = EntityMessage . generateMessageId ( ) ;
draft . thread = draft . msgid ;
draft . to = new Address [ ] { myAddress ( ) } ;
2021-09-28 20:16:03 +00:00
draft . subject = context . getString ( R . string . app_name ) + " " +
BuildConfig . VERSION_NAME + BuildConfig . REVISION + " debug info " ;
2019-05-12 17:14:34 +00:00
draft . received = new Date ( ) . getTime ( ) ;
draft . seen = true ;
draft . ui_seen = true ;
draft . id = db . message ( ) . insertMessage ( draft ) ;
2020-02-20 09:35:01 +00:00
File file = draft . getFile ( context ) ;
Helper . writeText ( file , body ) ;
2021-01-19 10:57:59 +00:00
db . message ( ) . setMessageContent ( draft . id , true , null , false , null , null ) ;
2019-05-12 17:14:34 +00:00
2019-07-21 18:09:55 +00:00
attachSettings ( context , draft . id , 1 ) ;
attachAccounts ( context , draft . id , 2 ) ;
attachNetworkInfo ( context , draft . id , 3 ) ;
attachLog ( context , draft . id , 4 ) ;
attachOperations ( context , draft . id , 5 ) ;
2021-06-18 06:37:11 +00:00
attachTasks ( context , draft . id , 6 ) ;
attachLogcat ( context , draft . id , 7 ) ;
2020-10-09 12:29:30 +00:00
if ( Build . VERSION . SDK_INT > = Build . VERSION_CODES . O )
2021-06-18 06:37:11 +00:00
attachNotificationInfo ( context , draft . id , 8 ) ;
2021-02-10 08:57:48 +00:00
//if (MessageClassifier.isEnabled(context))
2021-06-18 06:37:11 +00:00
// attachClassifierData(context, draft.id, 9);
2019-07-21 18:09:55 +00:00
EntityOperation . queue ( context , draft , EntityOperation . ADD ) ;
2019-05-12 17:14:34 +00:00
db . setTransactionSuccessful ( ) ;
} finally {
db . endTransaction ( ) ;
}
2019-06-19 10:23:17 +00:00
2019-12-09 18:44:27 +00:00
ServiceSynchronize . eval ( context , " debuginfo " ) ;
2019-12-07 19:32:58 +00:00
2019-05-12 17:14:34 +00:00
return draft ;
}
2019-12-06 07:50:46 +00:00
static void unexpectedError ( FragmentManager manager , Throwable ex ) {
2020-07-15 07:54:27 +00:00
unexpectedError ( manager , ex , true ) ;
}
static void unexpectedError ( FragmentManager manager , Throwable ex , boolean report ) {
2019-12-06 07:50:46 +00:00
Log . e ( ex ) ;
2020-11-14 06:50:24 +00:00
if ( ex instanceof OutOfMemoryError )
report = false ;
2019-12-06 07:50:46 +00:00
Bundle args = new Bundle ( ) ;
args . putSerializable ( " ex " , ex ) ;
2020-07-15 07:54:27 +00:00
args . putBoolean ( " report " , report ) ;
2019-12-06 07:50:46 +00:00
FragmentDialogUnexpected fragment = new FragmentDialogUnexpected ( ) ;
fragment . setArguments ( args ) ;
fragment . show ( manager , " error:unexpected " ) ;
}
public static class FragmentDialogUnexpected extends FragmentDialogBase {
@NonNull
@Override
public Dialog onCreateDialog ( @Nullable Bundle savedInstanceState ) {
final Throwable ex = ( Throwable ) getArguments ( ) . getSerializable ( " ex " ) ;
2020-07-15 07:54:27 +00:00
boolean report = getArguments ( ) . getBoolean ( " report " , true ) ;
2019-12-06 07:50:46 +00:00
2021-10-17 05:26:38 +00:00
final Context context = getContext ( ) ;
LayoutInflater inflater = LayoutInflater . from ( context ) ;
View dview = inflater . inflate ( R . layout . dialog_unexpected , null ) ;
TextView tvError = dview . findViewById ( R . id . tvError ) ;
tvError . setText ( Log . formatThrowable ( ex , false ) ) ;
2020-10-30 09:36:16 +00:00
AlertDialog . Builder builder = new AlertDialog . Builder ( getContext ( ) )
2021-10-17 05:26:38 +00:00
. setView ( dview )
2020-07-15 07:54:27 +00:00
. setPositiveButton ( android . R . string . cancel , null ) ;
if ( report )
builder . setNeutralButton ( R . string . title_report , new DialogInterface . OnClickListener ( ) {
@Override
public void onClick ( DialogInterface dialog , int which ) {
2020-10-30 09:36:16 +00:00
// Dialog will be dismissed
final Context context = getContext ( ) ;
2020-07-15 07:54:27 +00:00
new SimpleTask < Long > ( ) {
@Override
protected Long onExecute ( Context context , Bundle args ) throws Throwable {
return Log . getDebugInfo ( context , R . string . title_unexpected_info_remark , ex , null ) . id ;
}
@Override
protected void onExecuted ( Bundle args , Long id ) {
context . startActivity ( new Intent ( context , ActivityCompose . class )
. putExtra ( " action " , " edit " )
. putExtra ( " id " , id ) ) ;
}
@Override
protected void onException ( Bundle args , Throwable ex ) {
if ( ex instanceof IllegalArgumentException )
ToastEx . makeText ( context , ex . getMessage ( ) , Toast . LENGTH_LONG ) . show ( ) ;
else
ToastEx . makeText ( context , ex . toString ( ) , Toast . LENGTH_LONG ) . show ( ) ;
}
2020-10-30 09:36:16 +00:00
} . execute ( getContext ( ) , getActivity ( ) , new Bundle ( ) , " error:unexpected " ) ;
2020-07-15 07:54:27 +00:00
}
} ) ;
return builder . create ( ) ;
2019-12-06 07:50:46 +00:00
}
}
2019-05-12 17:14:34 +00:00
private static StringBuilder getAppInfo ( Context context ) {
StringBuilder sb = new StringBuilder ( ) ;
2021-08-23 16:03:34 +00:00
ContentResolver resolver = context . getContentResolver ( ) ;
2021-07-18 17:41:28 +00:00
SharedPreferences prefs = PreferenceManager . getDefaultSharedPreferences ( context ) ;
2021-07-17 11:49:08 +00:00
PackageManager pm = context . getPackageManager ( ) ;
String installer = pm . getInstallerPackageName ( BuildConfig . APPLICATION_ID ) ;
2021-12-14 08:17:52 +00:00
2021-07-17 11:49:08 +00:00
int targetSdk = - 1 ;
try {
ApplicationInfo ai = pm . getApplicationInfo ( BuildConfig . APPLICATION_ID , 0 ) ;
targetSdk = ai . targetSdkVersion ;
2021-12-14 08:17:52 +00:00
} catch ( PackageManager . NameNotFoundException ex ) {
sb . append ( ex ) . append ( " \ r \ n " ) ;
2021-07-17 11:49:08 +00:00
}
2019-05-12 17:14:34 +00:00
// Get version info
2021-12-14 08:17:52 +00:00
sb . append ( String . format ( " %s %s/%d%s%s%s%s \ r \ n " ,
2019-05-12 17:14:34 +00:00
context . getString ( R . string . app_name ) ,
2021-09-28 20:16:03 +00:00
BuildConfig . VERSION_NAME + BuildConfig . REVISION ,
2021-12-14 08:17:52 +00:00
Helper . hasValidFingerprint ( context ) ? 1 : 3 ,
2019-05-12 17:14:34 +00:00
BuildConfig . PLAY_STORE_RELEASE ? " p " : " " ,
2021-05-02 07:48:08 +00:00
Helper . hasPlayStore ( context ) ? " s " : " " ,
2019-05-12 17:14:34 +00:00
BuildConfig . DEBUG ? " d " : " " ,
2021-12-14 08:17:52 +00:00
ActivityBilling . isPro ( context ) ? " + " : " - " ) ) ;
sb . append ( String . format ( " Package: %s \ r \ n " , BuildConfig . APPLICATION_ID ) ) ;
2021-07-17 11:49:08 +00:00
sb . append ( String . format ( " Android: %s (SDK %d/%d) \ r \ n " ,
Build . VERSION . RELEASE , Build . VERSION . SDK_INT , targetSdk ) ) ;
2021-11-08 16:55:11 +00:00
boolean reporting = prefs . getBoolean ( " crash_reports " , false ) ;
2022-01-09 13:48:37 +00:00
if ( reporting | | BuildConfig . TEST_RELEASE ) {
2021-11-08 16:55:11 +00:00
String uuid = prefs . getString ( " uuid " , null ) ;
sb . append ( String . format ( " UUID: %s \ r \ n " , uuid = = null ? " - " : uuid ) ) ;
}
2021-12-14 08:17:52 +00:00
sb . append ( String . format ( " Installer: %s \ r \ n " , installer ) ) ;
sb . append ( String . format ( " Installed: %s \ r \ n " , new Date ( Helper . getInstallTime ( context ) ) ) ) ;
sb . append ( String . format ( " Now: %s \ r \ n " , new Date ( ) ) ) ;
2019-05-12 17:14:34 +00:00
sb . append ( " \ r \ n " ) ;
// Get device info
sb . append ( String . format ( " Brand: %s \ r \ n " , Build . BRAND ) ) ;
sb . append ( String . format ( " Manufacturer: %s \ r \ n " , Build . MANUFACTURER ) ) ;
sb . append ( String . format ( " Model: %s \ r \ n " , Build . MODEL ) ) ;
sb . append ( String . format ( " Product: %s \ r \ n " , Build . PRODUCT ) ) ;
sb . append ( String . format ( " Device: %s \ r \ n " , Build . DEVICE ) ) ;
sb . append ( String . format ( " Host: %s \ r \ n " , Build . HOST ) ) ;
2021-11-03 07:01:23 +00:00
sb . append ( String . format ( " Time: %s \ r \ n " , new Date ( Build . TIME ) . toString ( ) ) ) ;
2019-05-12 17:14:34 +00:00
sb . append ( String . format ( " Display: %s \ r \ n " , Build . DISPLAY ) ) ;
sb . append ( String . format ( " Id: %s \ r \ n " , Build . ID ) ) ;
2021-12-14 08:17:52 +00:00
sb . append ( String . format ( " uid: %d \ r \ n " , android . os . Process . myUid ( ) ) ) ;
2019-05-12 17:14:34 +00:00
sb . append ( " \ r \ n " ) ;
2019-07-22 07:18:03 +00:00
sb . append ( String . format ( " Processors: %d \ r \ n " , Runtime . getRuntime ( ) . availableProcessors ( ) ) ) ;
ActivityManager am = ( ActivityManager ) context . getSystemService ( Context . ACTIVITY_SERVICE ) ;
2020-07-21 17:06:41 +00:00
ActivityManager . MemoryInfo mi = new ActivityManager . MemoryInfo ( ) ;
am . getMemoryInfo ( mi ) ;
2021-12-14 08:17:52 +00:00
sb . append ( String . format ( " Memory class: %d/%d MB Total: %s \ r \ n " ,
2021-02-17 20:17:03 +00:00
am . getMemoryClass ( ) , am . getLargeMemoryClass ( ) , Helper . humanReadableByteCount ( mi . totalMem ) ) ) ;
2019-07-22 07:18:03 +00:00
2021-05-24 05:49:55 +00:00
long storage_available = Helper . getAvailableStorageSpace ( ) ;
long storage_total = Helper . getTotalStorageSpace ( ) ;
long storage_used = Helper . getSize ( context . getFilesDir ( ) ) ;
2021-01-22 14:01:20 +00:00
sb . append ( String . format ( " Storage space: %s/%s App: %s \ r \ n " ,
2021-05-24 05:49:55 +00:00
Helper . humanReadableByteCount ( storage_total - storage_available ) ,
Helper . humanReadableByteCount ( storage_total ) ,
Helper . humanReadableByteCount ( storage_used ) ) ) ;
2019-10-19 19:53:19 +00:00
2019-07-22 07:18:03 +00:00
Runtime rt = Runtime . getRuntime ( ) ;
2021-08-31 05:40:08 +00:00
long hused = ( rt . totalMemory ( ) - rt . freeMemory ( ) ) / 1024L / 1024L ;
long hmax = rt . maxMemory ( ) / 1024L / 1024L ;
long nheap = Debug . getNativeHeapAllocatedSize ( ) / 1024L / 1024L ;
long nsize = Debug . getNativeHeapSize ( ) / 1024 / 1024L ;
sb . append ( String . format ( " Heap usage: %d/%d MiB native: %d/%d MiB \ r \ n " , hused , hmax , nheap , nsize ) ) ;
2019-07-22 07:18:03 +00:00
2021-09-07 15:08:00 +00:00
if ( Build . VERSION . SDK_INT > = Build . VERSION_CODES . R ) {
int ipc = IBinder . getSuggestedMaxIpcSizeBytes ( ) ;
sb . append ( String . format ( " IPC max: %s \ r \ n " , Helper . humanReadableByteCount ( ipc ) ) ) ;
}
2021-12-14 08:17:52 +00:00
try {
int maxKeySize = javax . crypto . Cipher . getMaxAllowedKeyLength ( " AES " ) ;
sb . append ( context . getString ( R . string . title_advanced_aes_key_size ,
Helper . humanReadableByteCount ( maxKeySize , false ) ) ) . append ( " \ r \ n " ) ;
} catch ( Throwable ex ) {
sb . append ( ex ) . append ( " \ r \ n " ) ;
}
sb . append ( " \ r \ n " ) ;
Locale slocale = Resources . getSystem ( ) . getConfiguration ( ) . locale ;
String language = prefs . getString ( " language " , null ) ;
sb . append ( String . format ( " Locale: def=%s sys=%s lang=%s \ r \ n " ,
Locale . getDefault ( ) , slocale , language ) ) ;
String charset = MimeUtility . getDefaultJavaCharset ( ) ;
sb . append ( String . format ( " Default charset: %s/%s \ r \ n " , charset , MimeUtility . mimeCharset ( charset ) ) ) ;
sb . append ( " Transliterate: " )
. append ( TextHelper . canTransliterate ( ) )
. append ( " \ r \ n " ) ;
sb . append ( " \ r \ n " ) ;
WindowManager wm = ( WindowManager ) context . getSystemService ( Context . WINDOW_SERVICE ) ;
Display display = wm . getDefaultDisplay ( ) ;
Point dim = new Point ( ) ;
display . getSize ( dim ) ;
float density = context . getResources ( ) . getDisplayMetrics ( ) . density ;
sb . append ( String . format ( " Density %f \ r \ n " , density ) ) ;
sb . append ( String . format ( " Resolution: %.2f x %.2f dp \ r \ n " , dim . x / density , dim . y / density ) ) ;
2021-08-10 07:23:05 +00:00
Configuration config = context . getResources ( ) . getConfiguration ( ) ;
2021-12-14 08:17:52 +00:00
2021-08-10 07:23:05 +00:00
String size ;
if ( config . isLayoutSizeAtLeast ( Configuration . SCREENLAYOUT_SIZE_XLARGE ) )
2021-12-14 08:17:52 +00:00
size = " XLarge " ;
2021-08-10 07:23:05 +00:00
else if ( config . isLayoutSizeAtLeast ( Configuration . SCREENLAYOUT_SIZE_LARGE ) )
2021-12-14 08:17:52 +00:00
size = " Large " ;
2021-08-10 07:23:05 +00:00
else if ( config . isLayoutSizeAtLeast ( Configuration . SCREENLAYOUT_SIZE_NORMAL ) )
2021-12-14 08:17:52 +00:00
size = " Medium " ;
2021-08-10 07:23:05 +00:00
else if ( config . isLayoutSizeAtLeast ( Configuration . SCREENLAYOUT_SIZE_SMALL ) )
2021-12-14 08:17:52 +00:00
size = " Small " ;
2021-08-10 07:23:05 +00:00
else
2021-12-14 08:17:52 +00:00
size = " size= " + ( config . screenLayout & Configuration . SCREENLAYOUT_SIZE_MASK ) ;
String orientation ;
if ( config . orientation = = Configuration . ORIENTATION_LANDSCAPE )
orientation = " Landscape " ;
else if ( config . orientation = = Configuration . ORIENTATION_PORTRAIT )
orientation = " Portrait " ;
else
orientation = " orientation= " + config . orientation ;
sb . append ( String . format ( " %s %s \ r \ n " , size , orientation ) ) ;
2019-05-12 17:14:34 +00:00
2021-08-23 16:03:34 +00:00
try {
float animation_scale = Settings . Global . getFloat ( resolver ,
Settings . Global . WINDOW_ANIMATION_SCALE , 0f ) ;
2021-12-14 08:17:52 +00:00
sb . append ( String . format ( " Animation scale: %f %s \ r \ n " , animation_scale ,
animation_scale = = 1f ? " " : " !!! " ) ) ;
2021-08-23 16:03:34 +00:00
} catch ( Throwable ex ) {
2021-12-14 08:17:52 +00:00
sb . append ( ex ) . append ( " \ r \ n " ) ;
2021-08-23 16:03:34 +00:00
}
2021-06-05 06:47:26 +00:00
int uiMode = context . getResources ( ) . getConfiguration ( ) . uiMode ;
sb . append ( String . format ( " UI mode: 0x " ) )
. append ( Integer . toHexString ( uiMode ) )
2021-07-12 22:34:10 +00:00
. append ( " night= " ) . append ( Helper . isNight ( context ) )
2021-06-05 06:47:26 +00:00
. append ( " \ r \ n " ) ;
2021-12-14 08:17:52 +00:00
String uiType = Helper . getUiModeType ( context ) ;
sb . append ( String . format ( " UI type: %s %s \ r \ n " , uiType ,
" normal " . equals ( uiType ) ? " " : " !!! " ) ) ;
2021-10-02 05:37:00 +00:00
2021-12-14 08:17:52 +00:00
sb . append ( " \ r \ n " ) ;
2021-05-15 12:06:44 +00:00
2021-08-07 07:42:52 +00:00
Boolean ignoring = Helper . isIgnoringOptimizations ( context ) ;
2021-12-14 08:17:52 +00:00
sb . append ( String . format ( " Battery optimizations: %s %s \ r \ n " ,
ignoring = = null ? null : Boolean . toString ( ! ignoring ) ,
Boolean . FALSE . equals ( ignoring ) ? " !!! " : " " ) ) ;
2021-08-07 07:42:52 +00:00
2021-08-15 19:11:47 +00:00
sb . append ( String . format ( " Charging: %b; level: %d \ r \ n " ,
Helper . isCharging ( context ) , Helper . getBatteryLevel ( context ) ) ) ;
2019-05-12 17:14:34 +00:00
if ( Build . VERSION . SDK_INT > = Build . VERSION_CODES . P ) {
UsageStatsManager usm = ( UsageStatsManager ) context . getSystemService ( Context . USAGE_STATS_SERVICE ) ;
int bucket = usm . getAppStandbyBucket ( ) ;
2021-08-18 18:43:25 +00:00
boolean inactive = usm . isAppInactive ( BuildConfig . APPLICATION_ID ) ;
sb . append ( String . format ( " Standby bucket: %d-%s;p inactive: %b \ r \ n " ,
bucket , Helper . getStandbyBucketName ( bucket ) , inactive ) ) ;
2019-05-12 17:14:34 +00:00
}
2021-12-14 08:17:52 +00:00
boolean canExact = AlarmManagerCompatEx . canScheduleExactAlarms ( context ) ;
boolean hasExact = AlarmManagerCompatEx . hasExactAlarms ( context ) ;
sb . append ( String . format ( " ExactAlarms can=%b has=%b %s \ r \ n " , canExact , hasExact ,
canExact ? " " : " !!! " ) ) ;
2021-04-05 15:30:47 +00:00
2021-12-14 08:17:52 +00:00
if ( Build . VERSION . SDK_INT > = Build . VERSION_CODES . P ) {
boolean restricted = am . isBackgroundRestricted ( ) ;
sb . append ( String . format ( " Background restricted: %b %s \ r \ n " , restricted ,
restricted ? " !!! " : " " ) ) ;
}
if ( Build . VERSION . SDK_INT > = Build . VERSION_CODES . N ) {
boolean saving = ConnectionHelper . isDataSaving ( context ) ;
sb . append ( String . format ( " Data saving: %b %s \ r \ n " , saving ,
saving ? " !!! " : " " ) ) ;
}
2019-05-12 17:14:34 +00:00
2021-08-23 16:03:34 +00:00
try {
int finish_activities = Settings . Global . getInt ( resolver ,
Settings . Global . ALWAYS_FINISH_ACTIVITIES , 0 ) ;
2021-12-14 08:17:52 +00:00
sb . append ( String . format ( " Always finish: %d %s \ r \ n " , finish_activities ,
finish_activities = = 0 ? " " : " !!! " ) ) ;
2021-08-23 16:03:34 +00:00
} catch ( Throwable ex ) {
2021-12-14 08:17:52 +00:00
sb . append ( ex ) . append ( " \ r \ n " ) ;
2021-08-23 16:03:34 +00:00
}
2021-12-14 08:17:52 +00:00
sb . append ( " \ r \ n " ) ;
sb . append ( String . format ( " Configuration: %s \ r \ n " , config ) ) ;
2021-08-10 07:23:05 +00:00
2019-05-12 17:14:34 +00:00
sb . append ( " \ r \ n " ) ;
2021-09-07 18:05:25 +00:00
for ( Provider p : Security . getProviders ( ) )
sb . append ( p ) . append ( " \ r \ n " ) ;
sb . append ( " \ r \ n " ) ;
2019-05-12 17:14:34 +00:00
2021-02-10 17:24:45 +00:00
try {
PackageInfo pi = context . getPackageManager ( )
. getPackageInfo ( BuildConfig . APPLICATION_ID , PackageManager . GET_PERMISSIONS ) ;
for ( int i = 0 ; i < pi . requestedPermissions . length ; i + + )
if ( pi . requestedPermissions [ i ] ! = null & &
pi . requestedPermissions [ i ] . startsWith ( " android.permission. " ) ) {
boolean granted = ( ( pi . requestedPermissionsFlags [ i ] & PackageInfo . REQUESTED_PERMISSION_GRANTED ) ! = 0 ) ;
sb . append ( pi . requestedPermissions [ i ] . replace ( " android.permission. " , " " ) )
. append ( '=' ) . append ( granted ) . append ( " \ r \ n " ) ;
}
} catch ( Throwable ex ) {
2021-12-14 08:17:52 +00:00
sb . append ( ex ) . append ( " \ r \ n " ) ;
2021-02-10 17:24:45 +00:00
}
sb . append ( " \ r \ n " ) ;
2020-07-11 13:09:32 +00:00
if ( Build . VERSION . SDK_INT > = Build . VERSION_CODES . R ) {
try {
// https://developer.android.com/reference/android/app/ApplicationExitInfo
List < ApplicationExitInfo > infos = am . getHistoricalProcessExitReasons (
context . getPackageName ( ) , 0 , 20 ) ;
for ( ApplicationExitInfo info : infos )
sb . append ( String . format ( " %s: %s %s/%s reason=%d status=%d importance=%d \ r \ n " ,
new Date ( info . getTimestamp ( ) ) , info . getDescription ( ) ,
Helper . humanReadableByteCount ( info . getPss ( ) * 1024L ) ,
Helper . humanReadableByteCount ( info . getRss ( ) * 1024L ) ,
info . getReason ( ) , info . getStatus ( ) , info . getReason ( ) ) ) ;
} catch ( Throwable ex ) {
2021-12-14 08:17:52 +00:00
sb . append ( ex ) . append ( " \ r \ n " ) ;
2020-07-11 13:09:32 +00:00
}
sb . append ( " \ r \ n " ) ;
}
2021-08-30 10:06:18 +00:00
if ( Build . VERSION . SDK_INT > = Build . VERSION_CODES . M )
try {
Map < String , String > stats = Debug . getRuntimeStats ( ) ;
for ( String key : stats . keySet ( ) )
sb . append ( key ) . append ( '=' ) . append ( stats . get ( key ) ) . append ( " \ r \ n " ) ;
sb . append ( " \ r \ n " ) ;
} catch ( Throwable ex ) {
2021-12-14 08:17:52 +00:00
sb . append ( ex ) . append ( " \ r \ n " ) ;
2021-08-30 10:06:18 +00:00
}
2019-05-12 17:14:34 +00:00
return sb ;
}
private static void attachSettings ( Context context , long id , int sequence ) throws IOException {
DB db = DB . getInstance ( context ) ;
EntityAttachment attachment = new EntityAttachment ( ) ;
attachment . message = id ;
attachment . sequence = sequence ;
attachment . name = " settings.txt " ;
attachment . type = " text/plain " ;
2019-06-29 06:52:15 +00:00
attachment . disposition = Part . ATTACHMENT ;
2019-05-12 17:14:34 +00:00
attachment . size = null ;
attachment . progress = 0 ;
attachment . id = db . attachment ( ) . insertAttachment ( attachment ) ;
2019-09-28 16:36:07 +00:00
long size = 0 ;
2019-05-12 17:14:34 +00:00
File file = attachment . getFile ( context ) ;
try ( OutputStream os = new BufferedOutputStream ( new FileOutputStream ( file ) ) ) {
SharedPreferences prefs = PreferenceManager . getDefaultSharedPreferences ( context ) ;
Map < String , ? > settings = prefs . getAll ( ) ;
2020-04-03 06:59:22 +00:00
List < String > keys = new ArrayList < > ( settings . keySet ( ) ) ;
Collections . sort ( keys ) ;
for ( String key : keys )
2019-05-12 17:14:34 +00:00
size + = write ( os , key + " = " + settings . get ( key ) + " \ r \ n " ) ;
}
2019-09-28 16:36:07 +00:00
db . attachment ( ) . setDownloaded ( attachment . id , size ) ;
2019-05-12 17:14:34 +00:00
}
private static void attachAccounts ( Context context , long id , int sequence ) throws IOException {
DB db = DB . getInstance ( context ) ;
EntityAttachment attachment = new EntityAttachment ( ) ;
attachment . message = id ;
attachment . sequence = sequence ;
attachment . name = " accounts.txt " ;
attachment . type = " text/plain " ;
2019-06-29 06:52:15 +00:00
attachment . disposition = Part . ATTACHMENT ;
2019-05-12 17:14:34 +00:00
attachment . size = null ;
attachment . progress = 0 ;
attachment . id = db . attachment ( ) . insertAttachment ( attachment ) ;
2020-08-30 11:35:21 +00:00
DateFormat dtf = Helper . getDateTimeInstance ( context , SimpleDateFormat . SHORT , SimpleDateFormat . SHORT ) ;
2019-09-28 16:36:07 +00:00
long size = 0 ;
2019-05-12 17:14:34 +00:00
File file = attachment . getFile ( context ) ;
try ( OutputStream os = new BufferedOutputStream ( new FileOutputStream ( file ) ) ) {
List < EntityAccount > accounts = db . account ( ) . getAccounts ( ) ;
2021-04-30 13:59:55 +00:00
SharedPreferences prefs = PreferenceManager . getDefaultSharedPreferences ( context ) ;
boolean enabled = prefs . getBoolean ( " enabled " , true ) ;
2021-05-01 17:02:39 +00:00
int pollInterval = ServiceSynchronize . getPollInterval ( context ) ;
2021-08-18 05:22:45 +00:00
boolean metered = prefs . getBoolean ( " metered " , true ) ;
2021-08-07 07:42:52 +00:00
Boolean ignoring = Helper . isIgnoringOptimizations ( context ) ;
2021-09-06 09:36:09 +00:00
boolean auto_optimize = prefs . getBoolean ( " auto_optimize " , false ) ;
2021-06-17 19:25:51 +00:00
boolean schedule = prefs . getBoolean ( " schedule " , false ) ;
2021-04-30 13:59:55 +00:00
size + = write ( os , " accounts= " + accounts . size ( ) +
" enabled= " + enabled +
2021-11-14 10:14:25 +00:00
" interval= " + pollInterval + " \ r \ n " +
" metered= " + metered +
2021-10-05 16:06:56 +00:00
" VPN= " + ConnectionHelper . vpnActive ( context ) +
2021-11-14 10:14:25 +00:00
" NetGuard= " + Helper . isInstalled ( context , " eu.faircode.netguard " ) + " \ r \ n " +
2021-08-07 07:42:52 +00:00
" optimizing= " + ( ignoring = = null ? null : ! ignoring ) +
2021-09-06 09:36:09 +00:00
" auto_optimize= " + auto_optimize +
2021-08-07 07:42:52 +00:00
" \ r \ n \ r \ n " ) ;
2020-08-30 11:35:21 +00:00
2021-06-17 19:25:51 +00:00
if ( schedule ) {
int minuteStart = prefs . getInt ( " schedule_start " , 0 ) ;
int minuteEnd = prefs . getInt ( " schedule_end " , 0 ) ;
size + = write ( os , " schedule " +
( minuteStart / 60 ) + " : " + ( minuteStart % 60 ) + " ... " +
( minuteEnd / 60 ) + " : " + ( minuteEnd % 60 ) + " \ r \ n " ) ;
String [ ] daynames = new DateFormatSymbols ( ) . getWeekdays ( ) ;
for ( int i = 0 ; i < 7 ; i + + ) {
boolean day = prefs . getBoolean ( " schedule_day " + i , true ) ;
size + = write ( os , " schedule " + daynames [ i + 1 ] + " = " + day + " \ r \ n " ) ;
}
size + = write ( os , " \ r \ n " ) ;
}
2020-08-30 11:35:21 +00:00
for ( EntityAccount account : accounts ) {
if ( account . synchronize ) {
2021-08-08 11:55:45 +00:00
int content = 0 ;
int messages = 0 ;
List < TupleFolderEx > folders = db . folder ( ) . getFoldersEx ( account . id ) ;
for ( TupleFolderEx folder : folders ) {
content + = folder . content ;
messages + = folder . messages ;
}
2020-08-30 11:35:21 +00:00
size + = write ( os , account . name +
" " + ( account . protocol = = EntityAccount . TYPE_IMAP ? " IMAP " : " POP " ) + " / " + account . auth_type +
" " + account . host + " : " + account . port + " / " + account . encryption +
" sync= " + account . synchronize +
" exempted= " + account . poll_exempted +
" poll= " + account . poll_interval +
2021-10-16 10:53:28 +00:00
" ondemand= " + account . ondemand +
2021-08-08 11:55:45 +00:00
" messages= " + content + " / " + messages +
2020-08-30 11:35:21 +00:00
" " + account . state +
( account . last_connected = = null ? " " : " " + dtf . format ( account . last_connected ) ) +
" \ r \ n " ) ;
if ( folders . size ( ) > 0 )
Collections . sort ( folders , folders . get ( 0 ) . getComparator ( context ) ) ;
2021-08-08 11:55:45 +00:00
for ( TupleFolderEx folder : folders )
2020-08-30 11:35:21 +00:00
if ( folder . synchronize )
size + = write ( os , " - " + folder . name + " " + folder . type +
2021-10-06 08:34:38 +00:00
( folder . unified ? " unified " : " " ) +
( folder . notify ? " notify " : " " ) +
2020-08-30 11:35:21 +00:00
" poll= " + folder . poll + " / " + folder . poll_factor +
" days= " + folder . sync_days + " / " + folder . keep_days +
2021-08-08 11:55:45 +00:00
" msgs= " + folder . content + " / " + folder . messages +
2020-08-30 11:35:21 +00:00
" " + folder . state +
( folder . last_sync = = null ? " " : " " + dtf . format ( folder . last_sync ) ) +
" \ r \ n " ) ;
size + = write ( os , " \ r \ n " ) ;
}
}
2019-05-12 17:14:34 +00:00
for ( EntityAccount account : accounts )
2021-08-07 07:42:52 +00:00
if ( account . synchronize )
try {
JSONObject jaccount = account . toJSON ( ) ;
jaccount . put ( " state " , account . state = = null ? " null " : account . state ) ;
jaccount . put ( " warning " , account . warning ) ;
jaccount . put ( " error " , account . error ) ;
2021-08-08 11:42:41 +00:00
jaccount . put ( " capabilities " , account . capabilities ) ;
2021-08-07 07:42:52 +00:00
if ( account . last_connected ! = null )
jaccount . put ( " last_connected " , new Date ( account . last_connected ) . toString ( ) ) ;
jaccount . put ( " keep_alive_ok " , account . keep_alive_ok ) ;
jaccount . put ( " keep_alive_failed " , account . keep_alive_failed ) ;
jaccount . put ( " keep_alive_succeeded " , account . keep_alive_succeeded ) ;
jaccount . remove ( " password " ) ;
size + = write ( os , " ========== \ r \ n " ) ;
size + = write ( os , jaccount . toString ( 2 ) + " \ r \ n " ) ;
List < EntityFolder > folders = db . folder ( ) . getFolders ( account . id , false , false ) ;
if ( folders . size ( ) > 0 )
Collections . sort ( folders , folders . get ( 0 ) . getComparator ( context ) ) ;
for ( EntityFolder folder : folders ) {
JSONObject jfolder = folder . toJSON ( ) ;
jfolder . put ( " level " , folder . level ) ;
jfolder . put ( " total " , folder . total ) ;
jfolder . put ( " initialize " , folder . initialize ) ;
jfolder . put ( " subscribed " , folder . subscribed ) ;
jfolder . put ( " state " , folder . state = = null ? " null " : folder . state ) ;
jfolder . put ( " sync_state " , folder . sync_state = = null ? " null " : folder . sync_state ) ;
jfolder . put ( " poll_count " , folder . poll_count ) ;
jfolder . put ( " read_only " , folder . read_only ) ;
jfolder . put ( " selectable " , folder . selectable ) ;
jfolder . put ( " inferiors " , folder . inferiors ) ;
2021-10-26 07:46:27 +00:00
jfolder . put ( " auto_add " , folder . auto_add ) ;
2021-08-07 07:42:52 +00:00
jfolder . put ( " error " , folder . error ) ;
if ( folder . last_sync ! = null )
jfolder . put ( " last_sync " , new Date ( folder . last_sync ) . toString ( ) ) ;
if ( folder . last_sync_count ! = null )
jfolder . put ( " last_sync_count " , folder . last_sync_count ) ;
size + = write ( os , jfolder . toString ( 2 ) + " \ r \ n " ) ;
}
2019-05-12 17:14:34 +00:00
2021-08-07 07:42:52 +00:00
List < EntityIdentity > identities = db . identity ( ) . getIdentities ( account . id ) ;
for ( EntityIdentity identity : identities )
try {
JSONObject jidentity = identity . toJSON ( ) ;
jidentity . remove ( " password " ) ;
jidentity . remove ( " signature " ) ;
size + = write ( os , " ---------- \ r \ n " ) ;
size + = write ( os , jidentity . toString ( 2 ) + " \ r \ n " ) ;
} catch ( JSONException ex ) {
size + = write ( os , ex . toString ( ) + " \ r \ n " ) ;
}
} catch ( JSONException ex ) {
size + = write ( os , ex . toString ( ) + " \ r \ n " ) ;
2020-04-23 12:16:08 +00:00
}
2019-05-12 17:14:34 +00:00
}
2019-09-28 16:36:07 +00:00
db . attachment ( ) . setDownloaded ( attachment . id , size ) ;
2019-05-12 17:14:34 +00:00
}
private static void attachNetworkInfo ( Context context , long id , int sequence ) throws IOException {
DB db = DB . getInstance ( context ) ;
EntityAttachment attachment = new EntityAttachment ( ) ;
attachment . message = id ;
attachment . sequence = sequence ;
attachment . name = " network.txt " ;
attachment . type = " text/plain " ;
2019-06-29 06:52:15 +00:00
attachment . disposition = Part . ATTACHMENT ;
2019-05-12 17:14:34 +00:00
attachment . size = null ;
attachment . progress = 0 ;
attachment . id = db . attachment ( ) . insertAttachment ( attachment ) ;
2019-09-28 16:36:07 +00:00
long size = 0 ;
2019-05-12 17:14:34 +00:00
File file = attachment . getFile ( context ) ;
try ( OutputStream os = new BufferedOutputStream ( new FileOutputStream ( file ) ) ) {
ConnectivityManager cm = ( ConnectivityManager ) context . getSystemService ( Context . CONNECTIVITY_SERVICE ) ;
2019-10-22 06:55:27 +00:00
NetworkInfo ani = cm . getActiveNetworkInfo ( ) ;
if ( ani ! = null )
2020-08-30 10:53:08 +00:00
size + = write ( os , ani . toString ( ) +
" connected= " + ani . isConnected ( ) +
" metered= " + cm . isActiveNetworkMetered ( ) +
" roaming= " + ani . isRoaming ( ) +
" type= " + ani . getType ( ) + " / " + ani . getTypeName ( ) +
" \ r \ n \ r \ n " ) ;
2019-10-22 06:55:27 +00:00
2020-10-27 14:35:28 +00:00
Network active = ConnectionHelper . getActiveNetwork ( context ) ;
2019-05-12 17:14:34 +00:00
for ( Network network : cm . getAllNetworks ( ) ) {
2020-10-27 14:35:28 +00:00
size + = write ( os , ( network . equals ( active ) ? " active= " : " network= " ) + network + " \ r \ n " ) ;
2019-05-12 17:14:34 +00:00
NetworkCapabilities caps = cm . getNetworkCapabilities ( network ) ;
2020-10-27 14:35:28 +00:00
size + = write ( os , " caps= " + caps + " \ r \ n " ) ;
LinkProperties props = cm . getLinkProperties ( network ) ;
size + = write ( os , " props= " + props + " \ r \ n " ) ;
size + = write ( os , " \ r \ n " ) ;
2019-05-12 17:14:34 +00:00
}
2020-02-12 11:56:19 +00:00
2021-06-20 18:40:08 +00:00
try {
Enumeration < NetworkInterface > interfaces = NetworkInterface . getNetworkInterfaces ( ) ;
while ( interfaces ! = null & & interfaces . hasMoreElements ( ) ) {
NetworkInterface ni = interfaces . nextElement ( ) ;
size + = write ( os , " Interface= " + ni + " \ r \ n " ) ;
for ( InterfaceAddress iaddr : ni . getInterfaceAddresses ( ) ) {
InetAddress addr = iaddr . getAddress ( ) ;
size + = write ( os , " addr= " + addr +
( addr . isLoopbackAddress ( ) ? " loopback " : " " ) +
( addr . isSiteLocalAddress ( ) ? " site local (LAN) " : " " ) +
( addr . isLinkLocalAddress ( ) ? " link local (device) " : " " ) +
( addr . isAnyLocalAddress ( ) ? " any local " : " " ) +
( addr . isMulticastAddress ( ) ? " multicast " : " " ) + " \ r \ n " ) ;
}
size + = write ( os , " \ r \ n " ) ;
}
} catch ( Throwable ex ) {
size + = write ( os , ex . getMessage ( ) + " \ r \ n " ) ;
}
2020-02-12 11:56:19 +00:00
size + = write ( os , " VPN active= " + ConnectionHelper . vpnActive ( context ) + " \ r \ n \ r \ n " ) ;
2020-04-24 05:50:20 +00:00
ConnectionHelper . NetworkState state = ConnectionHelper . getNetworkState ( context ) ;
size + = write ( os , " Connected= " + state . isConnected ( ) + " \ r \ n " ) ;
size + = write ( os , " Suitable= " + state . isSuitable ( ) + " \ r \ n " ) ;
size + = write ( os , " Unmetered= " + state . isUnmetered ( ) + " \ r \ n " ) ;
size + = write ( os , " Roaming= " + state . isRoaming ( ) + " \ r \ n " ) ;
2021-05-15 12:09:52 +00:00
size + = write ( os , " Airplane= " + ConnectionHelper . airplaneMode ( context ) + " \ r \ n " ) ;
2019-05-12 17:14:34 +00:00
}
2019-09-28 16:36:07 +00:00
db . attachment ( ) . setDownloaded ( attachment . id , size ) ;
2019-05-12 17:14:34 +00:00
}
private static void attachLog ( Context context , long id , int sequence ) throws IOException {
DB db = DB . getInstance ( context ) ;
EntityAttachment attachment = new EntityAttachment ( ) ;
attachment . message = id ;
attachment . sequence = sequence ;
attachment . name = " log.txt " ;
attachment . type = " text/plain " ;
2019-06-29 06:52:15 +00:00
attachment . disposition = Part . ATTACHMENT ;
2019-05-12 17:14:34 +00:00
attachment . size = null ;
attachment . progress = 0 ;
attachment . id = db . attachment ( ) . insertAttachment ( attachment ) ;
2019-09-28 16:36:07 +00:00
long size = 0 ;
2019-05-12 17:14:34 +00:00
File file = attachment . getFile ( context ) ;
try ( OutputStream os = new BufferedOutputStream ( new FileOutputStream ( file ) ) ) {
long from = new Date ( ) . getTime ( ) - 24 * 3600 * 1000L ;
2019-07-15 19:28:25 +00:00
DateFormat TF = Helper . getTimeInstance ( context ) ;
2019-05-12 17:14:34 +00:00
2021-08-15 18:32:34 +00:00
for ( EntityLog entry : db . log ( ) . getLogs ( from , null ) )
2021-08-17 12:27:36 +00:00
size + = write ( os , String . format ( " %s [%d:%d:%d:%d] %s \ r \ n " ,
TF . format ( entry . time ) ,
entry . type . ordinal ( ) ,
( entry . account = = null ? 0 : entry . account ) ,
( entry . folder = = null ? 0 : entry . folder ) ,
( entry . message = = null ? 0 : entry . message ) ,
entry . data ) ) ;
2019-05-12 17:14:34 +00:00
}
2019-09-28 16:36:07 +00:00
db . attachment ( ) . setDownloaded ( attachment . id , size ) ;
2019-05-12 17:14:34 +00:00
}
private static void attachOperations ( Context context , long id , int sequence ) throws IOException {
DB db = DB . getInstance ( context ) ;
EntityAttachment attachment = new EntityAttachment ( ) ;
attachment . message = id ;
attachment . sequence = sequence ;
attachment . name = " operations.txt " ;
attachment . type = " text/plain " ;
2019-06-29 06:52:15 +00:00
attachment . disposition = Part . ATTACHMENT ;
2019-05-12 17:14:34 +00:00
attachment . size = null ;
attachment . progress = 0 ;
attachment . id = db . attachment ( ) . insertAttachment ( attachment ) ;
2019-09-28 16:36:07 +00:00
long size = 0 ;
2019-05-12 17:14:34 +00:00
File file = attachment . getFile ( context ) ;
try ( OutputStream os = new BufferedOutputStream ( new FileOutputStream ( file ) ) ) {
2019-07-15 19:28:25 +00:00
DateFormat TF = Helper . getTimeInstance ( context ) ;
2019-05-12 17:14:34 +00:00
2020-10-23 13:56:15 +00:00
for ( EntityOperation op : db . operation ( ) . getOperations ( ) ) {
EntityAccount account = ( op . account = = null ? null : db . account ( ) . getAccount ( op . account ) ) ;
EntityFolder folder = ( op . folder = = null ? null : db . folder ( ) . getFolder ( op . folder ) ) ;
size + = write ( os , String . format ( " %s %s/%s %d %s/%d %s %s %s \ r \ n " ,
2019-07-15 19:28:25 +00:00
TF . format ( op . created ) ,
2020-10-23 13:56:15 +00:00
account = = null ? null : account . name ,
folder = = null ? null : folder . name ,
2019-05-12 17:14:34 +00:00
op . message = = null ? - 1 : op . message ,
op . name ,
2020-02-11 16:46:04 +00:00
op . tries ,
2019-05-12 17:14:34 +00:00
op . args ,
2020-02-11 16:47:41 +00:00
op . state ,
2019-05-12 17:14:34 +00:00
op . error ) ) ;
2020-10-23 13:56:15 +00:00
}
2019-05-12 17:14:34 +00:00
}
2019-09-28 16:36:07 +00:00
db . attachment ( ) . setDownloaded ( attachment . id , size ) ;
2019-05-12 17:14:34 +00:00
}
2021-06-18 06:37:11 +00:00
private static void attachTasks ( Context context , long id , int sequence ) throws IOException {
DB db = DB . getInstance ( context ) ;
EntityAttachment attachment = new EntityAttachment ( ) ;
attachment . message = id ;
attachment . sequence = sequence ;
attachment . name = " tasks.txt " ;
attachment . type = " text/plain " ;
attachment . disposition = Part . ATTACHMENT ;
attachment . size = null ;
attachment . progress = 0 ;
attachment . id = db . attachment ( ) . insertAttachment ( attachment ) ;
long size = 0 ;
File file = attachment . getFile ( context ) ;
try ( OutputStream os = new BufferedOutputStream ( new FileOutputStream ( file ) ) ) {
2021-09-22 16:06:50 +00:00
for ( SimpleTask task : SimpleTask . getList ( ) )
2021-06-18 06:37:11 +00:00
size + = write ( os , String . format ( " %s \ r \ n " , task . toString ( ) ) ) ;
2021-09-22 18:11:46 +00:00
size + = write ( os , " \ r \ n " ) ;
2021-09-22 16:06:50 +00:00
for ( TwoStateOwner owner : TwoStateOwner . getList ( ) )
size + = write ( os , String . format ( " %s \ r \ n " , owner . toString ( ) ) ) ;
2021-06-18 06:37:11 +00:00
}
db . attachment ( ) . setDownloaded ( attachment . id , size ) ;
}
2019-05-12 17:14:34 +00:00
private static void attachLogcat ( Context context , long id , int sequence ) throws IOException {
DB db = DB . getInstance ( context ) ;
EntityAttachment attachment = new EntityAttachment ( ) ;
attachment . message = id ;
attachment . sequence = sequence ;
attachment . name = " logcat.txt " ;
attachment . type = " text/plain " ;
2019-06-29 06:52:15 +00:00
attachment . disposition = Part . ATTACHMENT ;
2019-05-12 17:14:34 +00:00
attachment . size = null ;
attachment . progress = 0 ;
attachment . id = db . attachment ( ) . insertAttachment ( attachment ) ;
Process proc = null ;
File file = attachment . getFile ( context ) ;
try ( OutputStream os = new BufferedOutputStream ( new FileOutputStream ( file ) ) ) {
String [ ] cmd = new String [ ] { " logcat " ,
" -d " ,
" -v " , " threadtime " ,
//"-t", "1000",
Log . TAG + " :I " } ;
proc = Runtime . getRuntime ( ) . exec ( cmd ) ;
long size = 0 ;
try ( BufferedReader br = new BufferedReader ( new InputStreamReader ( proc . getInputStream ( ) ) ) ) {
String line ;
while ( ( line = br . readLine ( ) ) ! = null )
size + = write ( os , line + " \ r \ n " ) ;
}
db . attachment ( ) . setDownloaded ( attachment . id , size ) ;
} finally {
if ( proc ! = null )
proc . destroy ( ) ;
}
}
2020-10-09 12:29:30 +00:00
@RequiresApi ( api = Build . VERSION_CODES . O )
private static void attachNotificationInfo ( Context context , long id , int sequence ) throws IOException {
DB db = DB . getInstance ( context ) ;
EntityAttachment attachment = new EntityAttachment ( ) ;
attachment . message = id ;
attachment . sequence = sequence ;
attachment . name = " channel.txt " ;
attachment . type = " text/plain " ;
attachment . disposition = Part . ATTACHMENT ;
attachment . size = null ;
attachment . progress = 0 ;
attachment . id = db . attachment ( ) . insertAttachment ( attachment ) ;
long size = 0 ;
File file = attachment . getFile ( context ) ;
try ( OutputStream os = new BufferedOutputStream ( new FileOutputStream ( file ) ) ) {
NotificationManager nm = ( NotificationManager ) context . getSystemService ( Context . NOTIFICATION_SERVICE ) ;
2021-09-27 14:32:21 +00:00
String name ;
int filter = nm . getCurrentInterruptionFilter ( ) ;
switch ( filter ) {
case NotificationManager . INTERRUPTION_FILTER_UNKNOWN :
name = " Unknown " ;
break ;
case NotificationManager . INTERRUPTION_FILTER_ALL :
name = " All " ;
break ;
case NotificationManager . INTERRUPTION_FILTER_PRIORITY :
name = " Priority " ;
break ;
case NotificationManager . INTERRUPTION_FILTER_NONE :
name = " None " ;
break ;
case NotificationManager . INTERRUPTION_FILTER_ALARMS :
name = " Alarms " ;
break ;
default :
name = Integer . toString ( filter ) ;
}
2021-09-28 14:22:17 +00:00
size + = write ( os , String . format ( " Interruption filter allow=%s \ r \ n \ r \ n " , name ) ) ;
2021-09-27 14:32:21 +00:00
2020-10-09 12:29:30 +00:00
for ( NotificationChannel channel : nm . getNotificationChannels ( ) )
try {
JSONObject jchannel = NotificationHelper . channelToJSON ( channel ) ;
size + = write ( os , jchannel . toString ( 2 ) + " \ r \ n \ r \ n " ) ;
} catch ( JSONException ex ) {
size + = write ( os , ex . toString ( ) + " \ r \ n " ) ;
}
2021-09-27 14:57:17 +00:00
size + = write ( os ,
String . format ( " Importance none=%d; min=%d; low=%d; default=%d; high=%d; max=%d; unspecified=%d \ r \ n " ,
NotificationManager . IMPORTANCE_NONE ,
NotificationManager . IMPORTANCE_MIN ,
NotificationManager . IMPORTANCE_LOW ,
NotificationManager . IMPORTANCE_DEFAULT ,
NotificationManager . IMPORTANCE_HIGH ,
NotificationManager . IMPORTANCE_MAX ,
NotificationManager . IMPORTANCE_UNSPECIFIED ) ) ;
size + = write ( os ,
String . format ( " Visibility private=%d; public=%d; secret=%d \ r \ n " ,
Notification . VISIBILITY_PRIVATE ,
Notification . VISIBILITY_PUBLIC ,
Notification . VISIBILITY_SECRET ) ) ;
2020-10-09 12:29:30 +00:00
}
db . attachment ( ) . setDownloaded ( attachment . id , size ) ;
}
2021-01-03 09:58:51 +00:00
private static void attachClassifierData ( Context context , long id , int sequence ) throws IOException , JSONException {
DB db = DB . getInstance ( context ) ;
EntityAttachment attachment = new EntityAttachment ( ) ;
attachment . message = id ;
attachment . sequence = sequence ;
attachment . name = " classifier.json " ;
attachment . type = " application/json " ;
attachment . disposition = Part . ATTACHMENT ;
attachment . size = null ;
attachment . progress = 0 ;
attachment . id = db . attachment ( ) . insertAttachment ( attachment ) ;
MessageClassifier . save ( context ) ;
File source = MessageClassifier . getFile ( context ) ;
File target = attachment . getFile ( context ) ;
Helper . copy ( source , target ) ;
db . attachment ( ) . setDownloaded ( attachment . id , target . length ( ) ) ;
}
2019-05-12 17:14:34 +00:00
private static int write ( OutputStream os , String text ) throws IOException {
byte [ ] bytes = text . getBytes ( ) ;
os . write ( bytes ) ;
return bytes . length ;
}
2019-08-12 11:33:39 +00:00
private static long getFreeMem ( ) {
2019-05-22 13:41:54 +00:00
Runtime rt = Runtime . getRuntime ( ) ;
long used = ( rt . totalMemory ( ) - rt . freeMemory ( ) ) ;
long max = rt . maxMemory ( ) ;
return ( max - used ) ;
}
static int getFreeMemMb ( ) {
return ( int ) ( getFreeMem ( ) / 1024L / 1024L ) ;
}
2020-09-28 10:30:52 +00:00
static int getAvailableMb ( ) {
Runtime rt = Runtime . getRuntime ( ) ;
return ( int ) ( rt . maxMemory ( ) / 1024L / 1024L ) ;
}
2019-05-12 17:14:34 +00:00
static InternetAddress myAddress ( ) throws UnsupportedEncodingException {
2020-07-10 08:07:53 +00:00
return new InternetAddress ( " marcel+fairemail@faircode.eu " , " FairCode " , StandardCharsets . UTF_8 . name ( ) ) ;
2019-05-12 17:14:34 +00:00
}
2022-01-03 18:23:36 +00:00
static StringBuilder getSpans ( CharSequence text ) {
StringBuilder sb = new StringBuilder ( ) ;
TextUtils . dumpSpans ( text , new Printer ( ) {
@Override
public void println ( String x ) {
if ( sb . length ( ) > 0 )
sb . append ( ' ' ) ;
sb . append ( x . replace ( '\n' , '|' ) ) . append ( ']' ) ;
}
} , " [ " ) ;
return sb ;
}
2021-05-28 18:22:01 +00:00
}