├── .gitignore ├── .gitmodules ├── LICENSE ├── README.md ├── app ├── build.gradle ├── proguard-android-optimize-patched.txt ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── io │ │ └── oversec │ │ └── one │ │ └── ApplicationTest.java │ ├── appsec-common │ └── res │ │ ├── raw │ │ ├── about.md │ │ └── changelog.md │ │ ├── values-de │ │ └── strings.xml │ │ ├── values-es │ │ └── strings.xml │ │ ├── values-fr │ │ └── strings.xml │ │ ├── values-it │ │ └── strings.xml │ │ ├── values-pt │ │ └── strings.xml │ │ ├── values-ru │ │ └── strings.xml │ │ ├── values-tr │ │ └── strings.xml │ │ ├── values-zh-rCN │ │ └── strings.xml │ │ └── values │ │ └── strings.xml │ └── main │ ├── AndroidManifest.xml │ ├── aidl │ └── com │ │ └── android │ │ └── vending │ │ └── billing │ │ └── IInAppBillingService.aidl │ ├── java │ └── io │ │ └── oversec │ │ └── one │ │ ├── AccessibilityServiceStatusChangedListener.java │ │ ├── App.java │ │ ├── Core.java │ │ ├── CrashActivity.java │ │ ├── CrashHandler.java │ │ ├── EncryptionCache.java │ │ ├── ObservableCore.java │ │ ├── OversecIntentService.java │ │ ├── SecretCodeReceiver.java │ │ ├── Share.java │ │ ├── UiThreadVars.java │ │ ├── Util.java │ │ ├── acs │ │ ├── DisplayNodeVisitor.java │ │ ├── InvalidRefreshException.java │ │ ├── NodeAndFlag.java │ │ ├── OversecAccessibilityService.java │ │ ├── OversecAccessibilityService_1.java │ │ ├── Tree.java │ │ ├── TreeNodeVisitor.java │ │ └── util │ │ │ ├── AccessibilityNodeInfoRef.java │ │ │ ├── AccessibilityNodeInfoUtils.java │ │ │ ├── AndroidIntegration.java │ │ │ ├── Bag.java │ │ │ ├── BasePackageMonitor.java │ │ │ ├── ClassLoadingManager.java │ │ │ ├── SimplePool.java │ │ │ └── SynchronizedPool.java │ │ ├── db │ │ ├── Db.java │ │ ├── IDecryptOverlayLayoutParamsChangedListener.java │ │ └── PadderDb.java │ │ ├── iab │ │ ├── Base64.java │ │ ├── Base64DecoderException.java │ │ ├── FullVersionListener.java │ │ ├── IabException.java │ │ ├── IabHelper.java │ │ ├── IabResult.java │ │ ├── IabUtil.java │ │ ├── Inventory.java │ │ ├── Purchase.java │ │ ├── PurchaseActivity.java │ │ ├── Security.java │ │ └── SkuDetails.java │ │ ├── ovl │ │ ├── AbstractOverlayButtonFreeView.java │ │ ├── AbstractOverlayButtonInputView.java │ │ ├── AbstractOverlayButtonView.java │ │ ├── AbstractOverlayDialogView.java │ │ ├── AbstractOverlayTouchableView.java │ │ ├── IDragListener.java │ │ ├── NodeGroupLayout.java │ │ ├── NodeTextView.java │ │ ├── NodeView.java │ │ ├── OverlayButtonCameraView.java │ │ ├── OverlayButtonComposeView.java │ │ ├── OverlayButtonConfigView.java │ │ ├── OverlayButtonDecryptView.java │ │ ├── OverlayButtonEncryptView.java │ │ ├── OverlayButtonHideView.java │ │ ├── OverlayButtonInfomodeView.java │ │ ├── OverlayButtonUpgradeView.java │ │ ├── OverlayDecryptView.java │ │ ├── OverlayDialogCorruptedEncodingView.java │ │ ├── OverlayDialogInsufficientPaddingView.java │ │ ├── OverlayDialogToast.java │ │ ├── OverlayDialogTooltip.java │ │ ├── OverlayDialogUpgrade.java │ │ ├── OverlayDialogUserInteractionRequired.java │ │ ├── OverlayEditTextBorderView.java │ │ ├── OverlayInfoButtonView.java │ │ ├── OverlayOutsideTouchView.java │ │ ├── OverlayView.java │ │ └── SampleNodeTextView.java │ │ ├── ui │ │ ├── AboutActivity.java │ │ ├── AboutFragment.java │ │ ├── ActionAccessibilitySettingsNotResolvableActivity.java │ │ ├── AppConfigActivity.java │ │ ├── AppConfigView.java │ │ ├── AppsFragment.java │ │ ├── ChangelogFragment.java │ │ ├── CheckboxPref.java │ │ ├── ColorSeekBar.java │ │ ├── ComposeActivity.java │ │ ├── DbCheckBoxPreference.java │ │ ├── DialercodeEditTextPreference.java │ │ ├── DonationFragment.java │ │ ├── EncryptionParamsActivity.java │ │ ├── HelpFragment.java │ │ ├── IgnoreTextDialogActivity.java │ │ ├── ImageDecryptActivity.java │ │ ├── ImageEncryptActivity.java │ │ ├── ImeMemoryLeakWorkaroundDummyActivity.java │ │ ├── IntSpinnerPref.java │ │ ├── MainActivity.java │ │ ├── MainSettingsFragment.java │ │ ├── ManageOverlayPermissionWarningActivity.java │ │ ├── MaxHeightScrollView.java │ │ ├── OnboardingActivity.java │ │ ├── Overlays.java │ │ ├── PadderDetailActivity.java │ │ ├── PadderFragment.java │ │ ├── PendingIntentFiringBlankActivity.java │ │ ├── PostAcsEnableActivity.java │ │ ├── PurchasesFragment.java │ │ ├── TakePhotoActivity.java │ │ ├── ValidatedDialogPreference.java │ │ ├── ValidatedEditTextPreference.java │ │ ├── WarningActivity.java │ │ └── encparams │ │ │ ├── ActivityResultWrapper.java │ │ │ ├── GpgEncryptionParamsFragment.java │ │ │ ├── SimpleSymmetricEncryptionParamsFragment.java │ │ │ └── SymmetricEncryptionParamsFragment.java │ │ └── util │ │ └── WrappedWindowManager.java │ └── res │ ├── drawable-hdpi │ ├── ic_backspace_black_18dp.png │ ├── ic_backspace_black_24dp.png │ ├── ic_camera_alt_black_24dp.png │ ├── ic_cancel_black_24dp.png │ ├── ic_cancel_white_24dp.png │ ├── ic_create_black_24dp.png │ ├── ic_help_outline_black_24dp.png │ ├── ic_help_outline_white_24dp.png │ ├── ic_info_black_24dp.png │ ├── ic_info_outline_black_24dp.png │ ├── ic_info_outline_white_24dp.png │ ├── ic_lock_open_black_24dp.png │ ├── ic_mail_outline_black_24dp.png │ ├── ic_not_interested_black_24dp.png │ ├── ic_not_interested_white_24dp.png │ ├── ic_question_black_24dp.png │ ├── ic_settings_black_24dp.png │ ├── ic_share_black_24dp.png │ ├── ic_share_white_24dp.png │ └── ic_shop_black_24dp.png │ ├── drawable-mdpi │ ├── ic_backspace_black_18dp.png │ ├── ic_backspace_black_24dp.png │ ├── ic_camera_alt_black_24dp.png │ ├── ic_cancel_black_24dp.png │ ├── ic_cancel_white_24dp.png │ ├── ic_create_black_24dp.png │ ├── ic_help_outline_black_24dp.png │ ├── ic_help_outline_white_24dp.png │ ├── ic_info_black_24dp.png │ ├── ic_info_outline_black_24dp.png │ ├── ic_info_outline_white_24dp.png │ ├── ic_lock_open_black_24dp.png │ ├── ic_mail_outline_black_24dp.png │ ├── ic_not_interested_black_24dp.png │ ├── ic_not_interested_white_24dp.png │ ├── ic_question_black_24dp.png │ ├── ic_settings_black_24dp.png │ ├── ic_share_black_24dp.png │ ├── ic_share_white_24dp.png │ └── ic_shop_black_24dp.png │ ├── drawable-xhdpi │ ├── ic_backspace_black_18dp.png │ ├── ic_backspace_black_24dp.png │ ├── ic_camera_alt_black_24dp.png │ ├── ic_cancel_black_24dp.png │ ├── ic_cancel_white_24dp.png │ ├── ic_create_black_24dp.png │ ├── ic_help_outline_black_24dp.png │ ├── ic_help_outline_white_24dp.png │ ├── ic_info_black_24dp.png │ ├── ic_info_outline_black_24dp.png │ ├── ic_info_outline_white_24dp.png │ ├── ic_lock_open_black_24dp.png │ ├── ic_mail_outline_black_24dp.png │ ├── ic_not_interested_black_24dp.png │ ├── ic_not_interested_white_24dp.png │ ├── ic_question_black_24dp.png │ ├── ic_settings_black_24dp.png │ ├── ic_share_black_24dp.png │ ├── ic_share_white_24dp.png │ └── ic_shop_black_24dp.png │ ├── drawable-xxhdpi │ ├── ic_backspace_black_18dp.png │ ├── ic_backspace_black_24dp.png │ ├── ic_camera_alt_black_24dp.png │ ├── ic_cancel_black_24dp.png │ ├── ic_cancel_white_24dp.png │ ├── ic_create_black_24dp.png │ ├── ic_help_outline_black_24dp.png │ ├── ic_help_outline_white_24dp.png │ ├── ic_info_black_24dp.png │ ├── ic_info_outline_black_24dp.png │ ├── ic_info_outline_white_24dp.png │ ├── ic_lock_open_black_24dp.png │ ├── ic_mail_outline_black_24dp.png │ ├── ic_not_interested_black_24dp.png │ ├── ic_not_interested_white_24dp.png │ ├── ic_question_black_24dp.png │ ├── ic_settings_black_24dp.png │ ├── ic_share_black_24dp.png │ ├── ic_share_white_24dp.png │ └── ic_shop_black_24dp.png │ ├── drawable-xxxhdpi │ ├── ic_backspace_black_18dp.png │ ├── ic_backspace_black_24dp.png │ ├── ic_camera_alt_black_24dp.png │ ├── ic_cancel_black_24dp.png │ ├── ic_cancel_white_24dp.png │ ├── ic_create_black_24dp.png │ ├── ic_help_outline_black_24dp.png │ ├── ic_help_outline_white_24dp.png │ ├── ic_info_black_24dp.png │ ├── ic_info_outline_black_24dp.png │ ├── ic_info_outline_white_24dp.png │ ├── ic_lock_open_black_24dp.png │ ├── ic_mail_outline_black_24dp.png │ ├── ic_not_interested_black_24dp.png │ ├── ic_not_interested_white_24dp.png │ ├── ic_question_black_24dp.png │ ├── ic_settings_black_24dp.png │ ├── ic_share_black_24dp.png │ ├── ic_share_white_24dp.png │ └── ic_shop_black_24dp.png │ ├── drawable │ ├── tooltip_bg_primary_headline.xml │ └── tooltip_bg_transparent.xml │ ├── layout │ ├── activity_about.xml │ ├── activity_actionaccessibilitysettingsnotresolvable.xml │ ├── activity_appconfig.xml │ ├── activity_compose.xml │ ├── activity_crash.xml │ ├── activity_decrypt_image.xml │ ├── activity_encryption_params.xml │ ├── activity_main.xml │ ├── activity_onboarding.xml │ ├── activity_overlaypermissionwarning.xml │ ├── activity_padder_detail.xml │ ├── activity_post_acs_enable.xml │ ├── activity_purchase.xml │ ├── activity_warning.xml │ ├── checkbox_pref.xml │ ├── content_crash.xml │ ├── content_encryption_params.xml │ ├── content_main.xml │ ├── content_padder_detail.xml │ ├── fragment_about.xml │ ├── fragment_changelog.xml │ ├── fragment_donation.xml │ ├── fragment_main_apps.xml │ ├── fragment_main_help.xml │ ├── fragment_padders.xml │ ├── fragment_purchases.xml │ ├── gpg_encryption_params.xml │ ├── gpg_encryption_params_nookc.xml │ ├── gpg_encryption_params_okcok.xml │ ├── ignore_text_dialog.xml │ ├── intspinner_item.xml │ ├── intspinner_pref.xml │ ├── listitem_app.xml │ ├── listitem_app_only.xml │ ├── listitem_iab_purchase.xml │ ├── listitem_iab_sku.xml │ ├── overlay_button.xml │ ├── overlay_dialog.xml │ ├── overlay_info_button.xml │ ├── simplesym_encryption_params.xml │ ├── sym_encryption_params.xml │ ├── tweaks__colors.xml │ └── tweaks__expert.xml │ ├── menu │ ├── menu_appconfig.xml │ ├── menu_encryption_params.xml │ ├── menu_image_decrypted.xml │ └── menu_main.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── mipmap-xxxhdpi │ └── ic_launcher.png │ ├── raw │ ├── about.md │ └── changelog.md │ ├── values-land │ └── dimens.xml │ ├── values-v21 │ └── styles.xml │ ├── values-w820dp │ └── dimens.xml │ ├── values │ ├── attrs.xml │ ├── colors.xml │ ├── dimens.xml │ ├── ids.xml │ └── styles.xml │ └── xml │ ├── acs_config.xml │ ├── empty_preferences.xml │ └── main_preferences.xml ├── build.gradle ├── fastlane └── metadata │ └── android │ ├── de │ ├── description.txt │ └── summary.txt │ ├── en-US │ ├── description.txt │ ├── images │ │ ├── featureGraphic.png │ │ ├── icon.png │ │ ├── phoneScreenshots │ │ │ ├── 0.png │ │ │ ├── 1.png │ │ │ ├── 2.png │ │ │ ├── 3.png │ │ │ ├── 4.png │ │ │ └── 5.png │ │ └── promoGraphic.png │ └── summary.txt │ ├── es │ ├── description.txt │ └── summary.txt │ ├── fr │ ├── description.txt │ └── summary.txt │ ├── pt │ ├── description.txt │ └── summary.txt │ ├── ru │ ├── description.txt │ └── summary.txt │ ├── tr │ ├── description.txt │ └── summary.txt │ └── zh-CN │ ├── description.txt │ └── summary.txt ├── gradle-witness.jar ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── hunspell.custom └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | proguardMappings 2 | app/fdroidVersionCode.gradle 3 | app/src/oversec 4 | app/src/whatsapp 5 | app/src/intern 6 | app/src/clean 7 | 8 | # Built application files 9 | *.apk 10 | *.ap_ 11 | 12 | # Files for the ART/Dalvik VM 13 | *.dex 14 | 15 | # Java class files 16 | *.class 17 | 18 | # Generated files 19 | bin/ 20 | gen/ 21 | out/ 22 | 23 | # Gradle files 24 | .gradle/ 25 | build/ 26 | 27 | # Local configuration file (sdk path, etc) 28 | local.properties 29 | 30 | # Proguard folder generated by Eclipse 31 | proguard/ 32 | 33 | # Log Files 34 | *.log 35 | 36 | # Android Studio Navigation editor temp files 37 | .navigation/ 38 | 39 | # Android Studio captures folder 40 | captures/ 41 | 42 | # IntelliJ 43 | *.iml 44 | .idea 45 | .idea/workspace.xml 46 | .idea/tasks.xml 47 | .idea/gradle.xml 48 | .idea/assetWizardSettings.xml 49 | .idea/dictionaries 50 | .idea/libraries 51 | .idea/caches 52 | 53 | # Keystore files 54 | # Uncomment the following line if you do not want to check your keystore files in. 55 | #*.jks 56 | 57 | # External native build folder generated in Android Studio 2.2 and later 58 | .externalNativeBuild 59 | 60 | # Google Services (e.g. APIs or Firebase) 61 | google-services.json 62 | 63 | # Freeline 64 | freeline.py 65 | freeline/ 66 | freeline_project_description.json 67 | 68 | # fastlane 69 | fastlane/report.xml 70 | fastlane/Preview.html 71 | fastlane/screenshots 72 | fastlane/test_output 73 | fastlane/readme.md 74 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "libraries/oversec_crypto"] 2 | path = libraries/oversec_crypto 3 | url = https://github.com/oversecio/oversec_crypto.git 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # The **Oversec** app 2 | 3 | Oversec is a unique app for Android that adds secure text and image-encryption to any other Android app. Oversec is an overlay on top of other apps that transparently sends encrypted text, and shows decrypted text, in place. 4 | 5 | ### More infos on our [website](http://oversec.io) 6 | 7 | [Get it on F-Droid](https://f-droid.org/packages/io.oversec.one/) 10 | [Get it on Google Play](https://play.google.com/store/apps/details?id=io.oversec.one) 13 | 14 | 16 | Teaser Video 17 |
18 | Oversec Teaser 20 |
21 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Documentation for ProGuard: 2 | # http://developer.android.com/guide/developing/tools/proguard.html 3 | # http://proguard.sourceforge.net/ 4 | 5 | #-dontshrink # shrinking enabled, see below 6 | #-dontobfuscate # obfuscation enabled for one class (see below) 7 | #-dontoptimize //need optimization to kill the log statements 8 | -dontpreverify 9 | -keepattributes ** 10 | -dontwarn ** 11 | -dontnote ** 12 | 13 | # Rules are defined as negation filters! 14 | # (! = negation filter, ** = all subpackages) 15 | # Keep everything (** {*;}) except... 16 | 17 | # * Obfuscate android.support.v7.view.menu.** to fix Samsung Android 4.2 bug 18 | # https://code.google.com/p/android/issues/detail?id=78377 19 | # * Remove unneeded Spongy Castle packages to be under 64K limit 20 | # http://developer.android.com/tools/building/multidex.html 21 | 22 | -keep class 23 | io.oversec.one.crypto.**, 24 | io.oversec.one.common.**, 25 | net.rehacktive.waspdb.**, 26 | com.esotericsoftware.kryo.**, 27 | com.nulabinc.zxcvbn.**, 28 | com.dlazaro66.qrcodereaderview.**, 29 | org.sufficientlysecure.**, 30 | org.openintents.**, 31 | org.objenesis.**, 32 | org.ow2.asm.**, 33 | !android.support.v7.view.menu.**, 34 | !com.google.protobuf.**, 35 | !com.google.zxing.**, 36 | !org.apache.commons.io.**, 37 | !org.spongycastle.math.ec.**, 38 | !org.spongycastle.crypto.tls.**, 39 | !org.spongycastle.crypto.openssl.**, 40 | !org.spongycastle.pqc.**, 41 | !org.spongycastle.x509.**, 42 | org.spongycastle.** {*;} 43 | 44 | #-renamesourcefileattribute SourceFile 45 | -dontobfuscate 46 | 47 | -assumenosideeffects class roboguice.util.Ln { 48 | public static *** v(...); 49 | public static *** i(...); 50 | public static *** w(...); 51 | public static *** d(...); 52 | 53 | } 54 | 55 | -------------------------------------------------------------------------------- /app/src/androidTest/java/io/oversec/one/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/appsec-common/res/raw/about.md: -------------------------------------------------------------------------------- 1 | [WhatsSecret-Website](https://www.whatsapp.oversec.io) 2 | 3 | **[Privacy Policy](https://www.oversec.io/policy.html)** 4 | 5 | [Oversec Open-Source Crypto-Module](https://github.com/oversecio/oversec-crypto) 6 | 7 | ## Libraries 8 | * [Android Support Libraries](http://developer.android.com/tools/support-library/index.html) (Apache License v2) 9 | * [HtmlTextView](https://github.com/sufficientlysecure/html-textview) (Apache License v2) 10 | * [Markdown4J](https://github.com/jdcasey/markdown4j) (Apache License v2) 11 | * [Protobuf](https://github.com/google/protobuf) ( [License](https://raw.githubusercontent.com/google/protobuf/v3.0.0-beta-3/LICENSE) ) 12 | * [Material Dialogs](https://github.com/afollestad/material-dialogs) (MIT License) 13 | * [ImageViewTouch](https://github.com/sephiroth74/ImageViewZoom) (MIT License) 14 | * [ReadMoreTextView](https://github.com/borjabravo10/ReadMoreTextView) (Apache License v2) 15 | * [Android-RateThisApp](https://github.com/kobakei/Android-RateThisApp) (Apache License v2) 16 | 17 | 18 | -------------------------------------------------------------------------------- /app/src/appsec-common/res/raw/changelog.md: -------------------------------------------------------------------------------- 1 | ### 1.4.3 2 | Bugfix 3 | ### 1.4.5 4 | Changed / Added wording to comply with Google policies 5 | ### 1.4.7 6 | Fixed some ANRs -------------------------------------------------------------------------------- /app/src/appsec-common/res/values-de/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/appsec-common/res/values-es/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/appsec-common/res/values-fr/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/appsec-common/res/values-it/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/appsec-common/res/values-pt/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/appsec-common/res/values-ru/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/appsec-common/res/values-tr/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/appsec-common/res/values-zh-rCN/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/appsec-common/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/AccessibilityServiceStatusChangedListener.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one; 2 | 3 | public interface AccessibilityServiceStatusChangedListener { 4 | void onStatusChanged(boolean running); 5 | } 6 | -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/App.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one; 2 | 3 | import android.app.ActivityManager; 4 | import android.content.IntentFilter; 5 | import android.os.Process; 6 | import android.support.multidex.MultiDexApplication; 7 | 8 | import com.kobakei.ratethisapp.RateThisApp; 9 | 10 | import io.oversec.one.crypto.AppsReceiver; 11 | import io.oversec.one.crypto.LoggingConfig; 12 | import io.oversec.one.crypto.gpg.OpenKeychainConnector; 13 | import io.oversec.one.iab.IabUtil; 14 | 15 | public class App extends MultiDexApplication { 16 | @Override 17 | public void onCreate() { 18 | 19 | int pid = Process.myPid(); 20 | ActivityManager manager = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE); 21 | String currentProcName = null; 22 | for (ActivityManager.RunningAppProcessInfo processInfo : manager.getRunningAppProcesses()) { 23 | if (processInfo.pid == pid) { 24 | currentProcName = processInfo.processName; 25 | break; 26 | } 27 | } 28 | 29 | if (currentProcName.endsWith("zxcvbn")) { 30 | super.onCreate(); 31 | return; 32 | } 33 | 34 | CrashHandler.init(this); 35 | 36 | LoggingConfig.INSTANCE.init(BuildConfig.DEBUG); 37 | 38 | super.onCreate(); 39 | 40 | if (IabUtil.isGooglePlayInstalled(this)) { 41 | RateThisApp.Config config = new RateThisApp.Config(7, 30); 42 | RateThisApp.init(config); 43 | } 44 | 45 | //need to register from code, registering from manifest is ignored 46 | IntentFilter packageChangeFilter = new IntentFilter(); 47 | packageChangeFilter.addAction("android.intent.action.PACKAGE_ADDED"); 48 | packageChangeFilter.addAction("android.intent.action.PACKAGE_REMOVED"); 49 | packageChangeFilter.addAction("android.intent.action.PACKAGE_CHANGED"); 50 | packageChangeFilter.addDataScheme("package"); 51 | registerReceiver(new AppsReceiver(), packageChangeFilter); 52 | 53 | IabUtil.getInstance(this); 54 | Core.getInstance(this); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/ObservableCore.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one; 2 | 3 | import java.util.Observable; 4 | 5 | public class ObservableCore extends Observable { 6 | public void setChanged() { 7 | super.setChanged(); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/SecretCodeReceiver.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one; 2 | 3 | import android.content.BroadcastReceiver; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | import android.widget.Toast; 7 | 8 | import io.oversec.one.common.MainPreferences; 9 | import io.oversec.one.ui.MainActivity; 10 | 11 | public class SecretCodeReceiver extends BroadcastReceiver { 12 | public SecretCodeReceiver() { 13 | } 14 | 15 | @Override 16 | public void onReceive(Context context, Intent intent) { 17 | if (intent.getAction().equals("android.provider.Telephony.SECRET_CODE")) { 18 | String uri = intent.getDataString(); 19 | if (uri==null) return; //should never happen but aparently does happen :-( 20 | String[] sep = uri.split("://"); 21 | String code = sep[1]; 22 | if (MainPreferences.INSTANCE.getLauncherSecretDialerCode(context).equals(code)) { 23 | 24 | if (!MainPreferences.INSTANCE.isDialerSecretCodeBroadcastConfirmedWorking(context)) { 25 | MainPreferences.INSTANCE.setDialerSecretCodeBroadcastConfirmedWorking(context); 26 | 27 | MainActivity.confirmDialerSecretCodeBroadcastWorking(context); 28 | 29 | 30 | } else { 31 | Core.getInstance(context).disablePanicMode(); 32 | Toast.makeText(context, context.getString(R.string.toast_panicmode_disabled), Toast.LENGTH_LONG).show(); 33 | //MainActivity.show(context); 34 | } 35 | } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/Share.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | 6 | import io.oversec.one.R; 7 | 8 | public class Share { 9 | 10 | public static void share(Context ctx) { 11 | try { 12 | Intent sendIntent = new Intent(); 13 | sendIntent.setAction(Intent.ACTION_SEND); 14 | sendIntent.putExtra(Intent.EXTRA_TEXT, ctx.getString(R.string.share_body)); 15 | sendIntent.setType("text/plain"); 16 | ctx.startActivity(Intent.createChooser(sendIntent, ctx.getString(R.string.share_chooser_title))); 17 | } catch (Exception e) { 18 | e.printStackTrace(); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/Util.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one; 2 | 3 | import android.content.ComponentName; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | import android.content.pm.ApplicationInfo; 7 | import android.content.pm.PackageManager; 8 | import android.content.pm.ResolveInfo; 9 | import android.content.res.Resources; 10 | 11 | import io.oversec.one.ui.MainActivity; 12 | 13 | import java.util.List; 14 | 15 | public class Util { 16 | 17 | public static CharSequence getPackageLabel(Context ctx, String packageName) { 18 | PackageManager lPackageManager = ctx.getPackageManager(); 19 | ApplicationInfo lApplicationInfo = null; 20 | try { 21 | lApplicationInfo = lPackageManager.getApplicationInfo(packageName, 22 | 0); 23 | } catch (final PackageManager.NameNotFoundException e) { 24 | return packageName; 25 | } 26 | return lPackageManager.getApplicationLabel(lApplicationInfo); 27 | } 28 | 29 | public static void enableLauncherIcon(Context context, boolean enable) { 30 | ComponentName componentName = new ComponentName(context.getPackageName(), "io.oversec.one.MainActivityLauncher"); 31 | setComponentState(context, componentName, enable ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED : PackageManager.COMPONENT_ENABLED_STATE_DISABLED); 32 | 33 | if (!enable) { 34 | MainActivity.closeOnPanic(); 35 | } 36 | } 37 | 38 | private static void setComponentState(Context context, ComponentName componentName, int componentState) { 39 | PackageManager pm = context.getPackageManager(); 40 | pm.setComponentEnabledSetting(componentName, componentState, PackageManager.DONT_KILL_APP); 41 | } 42 | 43 | public static boolean hasDialerIntentHandler(Context context) { 44 | //or "is this a phone 45 | 46 | Intent intent = new Intent(Intent.ACTION_DIAL); 47 | PackageManager manager = context.getPackageManager(); 48 | List infos = manager.queryIntentActivities(intent, 0); 49 | return infos.size() > 0; 50 | } 51 | 52 | public static boolean isOversec(Context ctx) { 53 | try { 54 | return ctx.getResources().getString(R.string.feature_package).trim().length() == 0; 55 | } catch (Resources.NotFoundException ex) { 56 | return true; 57 | } 58 | } 59 | 60 | public static boolean isFeatureEnctypeSYM(Context ctx) { 61 | return ctx.getResources().getBoolean(R.bool.feature_enctype_sym); 62 | 63 | } 64 | 65 | public static boolean isFeatureEnctypePGP(Context ctx) { 66 | return ctx.getResources().getBoolean(R.bool.feature_enctype_pgp); 67 | 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/acs/DisplayNodeVisitor.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.acs; 2 | 3 | import io.oversec.one.ovl.NodeTextView; 4 | 5 | public interface DisplayNodeVisitor { 6 | void visit(NodeTextView ntv); 7 | } 8 | -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/acs/InvalidRefreshException.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.acs; 2 | 3 | public class InvalidRefreshException extends Exception { 4 | } 5 | -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/acs/NodeAndFlag.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.acs; 2 | 3 | import android.view.accessibility.AccessibilityNodeInfo; 4 | 5 | class NodeAndFlag { 6 | int nodeHash; 7 | AccessibilityNodeInfo node; 8 | boolean cancelled; 9 | public OversecAccessibilityService.PerformNodeAction nodeAction; 10 | 11 | public NodeAndFlag(AccessibilityNodeInfo node, OversecAccessibilityService.PerformNodeAction nodeAction) { 12 | this.node = node; 13 | this.nodeHash = node.hashCode(); 14 | this.nodeAction = nodeAction; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/acs/OversecAccessibilityService_1.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.acs; 2 | 3 | public class OversecAccessibilityService_1 extends OversecAccessibilityService { 4 | } 5 | -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/acs/TreeNodeVisitor.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.acs; 2 | 3 | public interface TreeNodeVisitor { 4 | void visit(Tree.TreeNode node); 5 | } 6 | -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/acs/util/AndroidIntegration.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.acs.util; 2 | 3 | import android.content.Context; 4 | import android.provider.Settings; 5 | import android.provider.Settings.SettingNotFoundException; 6 | 7 | import io.oversec.one.Core; 8 | import io.oversec.one.acs.OversecAccessibilityService_1; 9 | 10 | public class AndroidIntegration { 11 | 12 | public static boolean isAccessibilitySettingsOnAndServiceRunning(Context ctx) { 13 | return isAccessibilitySettingsOn(ctx) && Core.getInstance(ctx).isAccessibilityServiceRunning(); 14 | } 15 | 16 | private static boolean isAccessibilitySettingsOn(Context ctx) { 17 | int accessibilityEnabled = 0; 18 | final String service = ctx.getPackageName() + "/" 19 | + OversecAccessibilityService_1.class.getName(); 20 | boolean accessibilityFound = false; 21 | try { 22 | accessibilityEnabled = Settings.Secure.getInt(ctx 23 | .getApplicationContext().getContentResolver(), 24 | Settings.Secure.ACCESSIBILITY_ENABLED); 25 | } catch (SettingNotFoundException e) { 26 | e.printStackTrace(); 27 | } 28 | 29 | if (accessibilityEnabled == 1) { 30 | String settingValue = Settings.Secure.getString(ctx 31 | .getApplicationContext().getContentResolver(), 32 | Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES); 33 | if (settingValue != null) { 34 | String[] values = settingValue.split("\\:"); 35 | for (String string : values) { 36 | 37 | if (string.equalsIgnoreCase(service)) { 38 | return true; 39 | } 40 | } 41 | } 42 | } 43 | return accessibilityFound; 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/acs/util/Bag.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.acs.util; 2 | 3 | public class Bag { 4 | 5 | private T[] data; 6 | private int manyItems; 7 | 8 | public Bag(int initialCapacity) { 9 | if (initialCapacity < 0) 10 | throw new IllegalArgumentException 11 | ("The initialCapacity is negative: " + initialCapacity); 12 | //noinspection unchecked 13 | data = (T[]) new Object[initialCapacity]; 14 | manyItems = 0; 15 | } 16 | 17 | public void add(T element) { 18 | if (manyItems == data.length) { // Ensure twice as much space as we need. 19 | ensureCapacity((manyItems + 1) * 2); 20 | } 21 | 22 | data[manyItems] = element; 23 | manyItems++; 24 | } 25 | 26 | public void ensureCapacity(int minimumCapacity) { 27 | T[] biggerArray; 28 | 29 | if (data.length < minimumCapacity) { 30 | //noinspection unchecked 31 | biggerArray = (T[]) new Object[minimumCapacity]; 32 | System.arraycopy(data, 0, biggerArray, 0, manyItems); 33 | data = biggerArray; 34 | } 35 | } 36 | 37 | public int size() { 38 | return manyItems; 39 | } 40 | 41 | 42 | public T get(int idx) { 43 | return data[idx]; 44 | } 45 | 46 | public boolean remove(T target) { 47 | int index; // The location of target in the data array. 48 | 49 | // Find the first occurrence of the target in the bag. 50 | index = 0; 51 | while ((index < manyItems) && (target != data[index])) 52 | index++; 53 | 54 | if (index == manyItems) 55 | // The target was not found, so nothing is removed. 56 | return false; 57 | else { // The target was found at data[index]. 58 | // So reduce manyItems by 1 and copy the last element onto data[index]. 59 | manyItems--; 60 | data[index] = data[manyItems]; 61 | data[manyItems] = null; 62 | return true; 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/acs/util/SimplePool.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.acs.util; 2 | 3 | public class SimplePool { 4 | private final Object[] mPool; 5 | 6 | private int mPoolSize; 7 | 8 | public int getCurrentSize() { 9 | return mPoolSize; 10 | } 11 | 12 | public int getMaxSize() { 13 | return mPool.length; 14 | } 15 | 16 | /** 17 | * Creates a new instance. 18 | * 19 | * @param maxPoolSize The max pool size. 20 | * @throws IllegalArgumentException If the max pool size is less than zero. 21 | */ 22 | public SimplePool(int maxPoolSize) { 23 | if (maxPoolSize <= 0) { 24 | throw new IllegalArgumentException("The max pool size must be > 0"); 25 | } 26 | mPool = new Object[maxPoolSize]; 27 | } 28 | 29 | 30 | public T acquire() { 31 | if (mPoolSize > 0) { 32 | final int lastPooledIndex = mPoolSize - 1; 33 | @SuppressWarnings("unchecked") T instance = (T) mPool[lastPooledIndex]; 34 | mPool[lastPooledIndex] = null; 35 | mPoolSize--; 36 | return instance; 37 | } 38 | return null; 39 | } 40 | 41 | 42 | public boolean release(T instance) { 43 | if (isInPool(instance)) { 44 | throw new IllegalStateException("Already in the pool!"); 45 | } 46 | if (mPoolSize < mPool.length) { 47 | mPool[mPoolSize] = instance; 48 | mPoolSize++; 49 | return true; 50 | } 51 | return false; 52 | } 53 | 54 | private boolean isInPool(T instance) { 55 | for (int i = 0; i < mPoolSize; i++) { 56 | if (mPool[i] == instance) { 57 | return true; 58 | } 59 | } 60 | return false; 61 | } 62 | } -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/acs/util/SynchronizedPool.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.acs.util; 2 | 3 | public class SynchronizedPool extends SimplePool { 4 | private final Object mLock = new Object(); 5 | 6 | /** 7 | * Creates a new instance. 8 | * 9 | * @param maxPoolSize The max pool size. 10 | * @throws IllegalArgumentException If the max pool size is less than zero. 11 | */ 12 | public SynchronizedPool(int maxPoolSize) { 13 | super(maxPoolSize); 14 | } 15 | 16 | @Override 17 | public T acquire() { 18 | synchronized (mLock) { 19 | return super.acquire(); 20 | } 21 | } 22 | 23 | @Override 24 | public boolean release(T element) { 25 | synchronized (mLock) { 26 | return super.release(element); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/db/IDecryptOverlayLayoutParamsChangedListener.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.db; 2 | 3 | public interface IDecryptOverlayLayoutParamsChangedListener { 4 | 5 | void onDecryptOverlayLayoutParamsChanged(String packagename); 6 | } 7 | -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/db/PadderDb.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.db; 2 | 3 | import android.content.Context; 4 | 5 | import io.oversec.one.crypto.R; 6 | import io.oversec.one.crypto.encoding.pad.PadderContent; 7 | 8 | import net.rehacktive.waspdb.WaspDb; 9 | import net.rehacktive.waspdb.WaspFactory; 10 | import net.rehacktive.waspdb.WaspHash; 11 | 12 | import java.util.Collections; 13 | import java.util.List; 14 | 15 | public class PadderDb { 16 | private static final String DATABASE_NAME = "padder4"; 17 | private static PadderDb mInstance; 18 | 19 | private final WaspDb mDb; 20 | private final WaspHash mPadderContent; 21 | private final Context mCtx; 22 | 23 | public static synchronized PadderDb getInstance(Context ctx) { 24 | if (mInstance == null) { 25 | mInstance = new PadderDb(ctx.getApplicationContext()); 26 | } 27 | return mInstance; 28 | } 29 | 30 | private PadderDb(Context ctx) { 31 | mCtx = ctx; 32 | mDb = WaspFactory.openOrCreateDatabase(ctx.getFilesDir().getPath(), DATABASE_NAME, null); 33 | boolean prefill = false; 34 | if (!mDb.existsHash("padder_content4")) { 35 | prefill = true; 36 | } 37 | mPadderContent = mDb.openOrCreateHash("padder_content4"); 38 | if (prefill) { 39 | prefill(); 40 | } 41 | } 42 | 43 | private void prefill() { 44 | add(new PadderContent("aa", mCtx.getString(R.string.padder_lorem), mCtx.getString(R.string.paddercontent_lorem))); 45 | add(new PadderContent("ab", mCtx.getString(R.string.padder_chicken), mCtx.getString(R.string.paddercontent_chicken))); 46 | add(new PadderContent("ab", mCtx.getString(R.string.padder_hansel_and_gretel), mCtx.getString(R.string.paddercontent_hansel_and_gretel))); 47 | } 48 | 49 | public List getAllValues() { 50 | List v = mPadderContent.getAllValues(); 51 | if (v != null) { 52 | Collections.sort(v, PadderContent.Companion.getSortComparator()); 53 | } else { 54 | return Collections.EMPTY_LIST; 55 | } 56 | 57 | return v; 58 | } 59 | 60 | public void delete(Long key) { 61 | mPadderContent.remove(key); 62 | } 63 | 64 | public void add(PadderContent content) { 65 | mPadderContent.put(content.getKey(), content); 66 | } 67 | 68 | 69 | public PadderContent get(Long id) { 70 | return mPadderContent.get(id); 71 | } 72 | 73 | public void update(PadderContent pc) { 74 | mPadderContent.put(pc.getKey(), pc); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/iab/Base64DecoderException.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.iab; 2 | 3 | public class Base64DecoderException extends Exception { 4 | public Base64DecoderException() { 5 | super(); 6 | } 7 | 8 | public Base64DecoderException(String s) { 9 | super(s); 10 | } 11 | 12 | private static final long serialVersionUID = 1L; 13 | } -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/iab/FullVersionListener.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.iab; 2 | 3 | public interface FullVersionListener { 4 | 5 | void onFullVersion_MAIN_THREAD(boolean isFullVersion); 6 | } 7 | -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/iab/IabException.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.iab; 2 | 3 | /** 4 | * Exception thrown when something went wrong with in-app billing. 5 | * An IabException has an associated IabResult (an error). 6 | * To get the IAB result that caused this exception to be thrown, 7 | * call {@link #getResult()}. 8 | */ 9 | public class IabException extends Exception { 10 | IabResult mResult; 11 | 12 | public IabException(IabResult r) { 13 | this(r, null); 14 | } 15 | public IabException(int response, String message) { 16 | this(new IabResult(response, message)); 17 | } 18 | public IabException(IabResult r, Exception cause) { 19 | super(r.getMessage(), cause); 20 | mResult = r; 21 | } 22 | public IabException(int response, String message, Exception cause) { 23 | this(new IabResult(response, message), cause); 24 | } 25 | 26 | /** Returns the IAB result (error) that this exception signals. */ 27 | public IabResult getResult() { return mResult; } 28 | } -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/iab/IabResult.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.iab; 2 | 3 | /** 4 | * Represents the result of an in-app billing operation. 5 | * A result is composed of a response code (an integer) and possibly a 6 | * message (String). You can get those by calling 7 | * {@link #getResponse} and {@link #getMessage()}, respectively. You 8 | * can also inquire whether a result is a success or a failure by 9 | * calling {@link #isSuccess()} and {@link #isFailure()}. 10 | */ 11 | public class IabResult { 12 | int mResponse; 13 | String mMessage; 14 | 15 | public IabResult(int response, String message) { 16 | mResponse = response; 17 | if (message == null || message.trim().length() == 0) { 18 | mMessage = IabHelper.getResponseDesc(response); 19 | } else { 20 | mMessage = message + " (response: " + IabHelper.getResponseDesc(response) + ")"; 21 | } 22 | } 23 | 24 | public int getResponse() { 25 | return mResponse; 26 | } 27 | 28 | public String getMessage() { 29 | return mMessage; 30 | } 31 | 32 | public boolean isSuccess() { 33 | return mResponse == IabHelper.BILLING_RESPONSE_RESULT_OK; 34 | } 35 | 36 | public boolean isFailure() { 37 | return !isSuccess(); 38 | } 39 | 40 | public String toString() { 41 | return "IabResult: " + getMessage(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/iab/Inventory.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.iab; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | /** 9 | * Represents a block of information about in-app items. 10 | * An Inventory is returned by such methods as {@link IabHelper#queryInventory}. 11 | */ 12 | public class Inventory { 13 | Map mSkuMap = new HashMap<>(); 14 | Map mPurchaseMap = new HashMap<>(); 15 | 16 | Inventory() { 17 | } 18 | 19 | /** 20 | * Returns the listing details for an in-app product. 21 | */ 22 | public SkuDetails getSkuDetails(String sku) { 23 | return mSkuMap.get(sku); 24 | } 25 | 26 | /** 27 | * Returns purchase information for a given product, or null if there is no purchase. 28 | */ 29 | public Purchase getPurchase(String sku) { 30 | return mPurchaseMap.get(sku); 31 | } 32 | 33 | /** 34 | * Returns whether or not there exists a purchase of the given product. 35 | */ 36 | public boolean hasPurchase(String sku) { 37 | return mPurchaseMap.containsKey(sku); 38 | } 39 | 40 | /** 41 | * Return whether or not details about the given product are available. 42 | */ 43 | public boolean hasDetails(String sku) { 44 | return mSkuMap.containsKey(sku); 45 | } 46 | 47 | /** 48 | * Erase a purchase (locally) from the inventory, given its product ID. This just 49 | * modifies the Inventory object locally and has no effect on the server! This is 50 | * useful when you have an existing Inventory object which you know to be up to date, 51 | * and you have just consumed an item successfully, which means that erasing its 52 | * purchase data from the Inventory you already have is quicker than querying for 53 | * a new Inventory. 54 | */ 55 | public void erasePurchase(String sku) { 56 | if (mPurchaseMap.containsKey(sku)) mPurchaseMap.remove(sku); 57 | } 58 | 59 | /** 60 | * Returns a list of all owned product IDs. 61 | */ 62 | List getAllOwnedSkus() { 63 | return new ArrayList<>(mPurchaseMap.keySet()); 64 | } 65 | 66 | /** 67 | * Returns a list of all owned product IDs of a given type 68 | */ 69 | List getAllOwnedSkus(String itemType) { 70 | List result = new ArrayList<>(); 71 | for (Purchase p : mPurchaseMap.values()) { 72 | if (p.getItemType().equals(itemType)) result.add(p.getSku()); 73 | } 74 | return result; 75 | } 76 | 77 | /** 78 | * Returns a list of all purchases. 79 | */ 80 | public List getAllPurchases() { 81 | return new ArrayList<>(mPurchaseMap.values()); 82 | } 83 | 84 | void addSkuDetails(SkuDetails d) { 85 | mSkuMap.put(d.getSku(), d); 86 | } 87 | 88 | void addPurchase(Purchase p) { 89 | mPurchaseMap.put(p.getSku(), p); 90 | } 91 | } -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/iab/Purchase.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.iab; 2 | 3 | import org.json.JSONException; 4 | import org.json.JSONObject; 5 | 6 | /** 7 | * Represents an in-app billing purchase. 8 | */ 9 | public class Purchase { 10 | String mItemType; // ITEM_TYPE_INAPP or ITEM_TYPE_SUBS 11 | String mOrderId; 12 | String mPackageName; 13 | String mSku; 14 | long mPurchaseTime; 15 | int mPurchaseState; 16 | String mDeveloperPayload; 17 | String mToken; 18 | String mOriginalJson; 19 | String mSignature; 20 | 21 | public Purchase(String itemType, String jsonPurchaseInfo, String signature) throws JSONException { 22 | mItemType = itemType; 23 | mOriginalJson = jsonPurchaseInfo; 24 | JSONObject o = new JSONObject(mOriginalJson); 25 | mOrderId = o.optString("orderId"); 26 | mPackageName = o.optString("packageName"); 27 | mSku = o.optString("productId"); 28 | mPurchaseTime = o.optLong("purchaseTime"); 29 | mPurchaseState = o.optInt("purchaseState"); 30 | mDeveloperPayload = o.optString("developerPayload"); 31 | mToken = o.optString("token", o.optString("purchaseToken")); 32 | mSignature = signature; 33 | } 34 | 35 | public String getItemType() { 36 | return mItemType; 37 | } 38 | 39 | public String getOrderId() { 40 | return mOrderId; 41 | } 42 | 43 | public String getPackageName() { 44 | return mPackageName; 45 | } 46 | 47 | public String getSku() { 48 | return mSku; 49 | } 50 | 51 | public long getPurchaseTime() { 52 | return mPurchaseTime; 53 | } 54 | 55 | public int getPurchaseState() { 56 | return mPurchaseState; 57 | } 58 | 59 | public String getDeveloperPayload() { 60 | return mDeveloperPayload; 61 | } 62 | 63 | public String getToken() { 64 | return mToken; 65 | } 66 | 67 | public String getOriginalJson() { 68 | return mOriginalJson; 69 | } 70 | 71 | public String getSignature() { 72 | return mSignature; 73 | } 74 | 75 | @Override 76 | public String toString() { 77 | return "PurchaseInfo(type:" + mItemType + "):" + mOriginalJson; 78 | } 79 | } -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/iab/SkuDetails.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.iab; 2 | 3 | import org.json.JSONException; 4 | import org.json.JSONObject; 5 | 6 | /** 7 | * Represents an in-app product's listing details. 8 | */ 9 | public class SkuDetails { 10 | String mItemType; 11 | String mSku; 12 | String mType; 13 | String mPrice; 14 | String mTitle; 15 | String mDescription; 16 | String mJson; 17 | 18 | public SkuDetails(String jsonSkuDetails) throws JSONException { 19 | this(IabHelper.ITEM_TYPE_INAPP, jsonSkuDetails); 20 | } 21 | 22 | public SkuDetails(String itemType, String jsonSkuDetails) throws JSONException { 23 | mItemType = itemType; 24 | mJson = jsonSkuDetails; 25 | JSONObject o = new JSONObject(mJson); 26 | mSku = o.optString("productId"); 27 | mType = o.optString("type"); 28 | mPrice = o.optString("price"); 29 | mTitle = o.optString("title"); 30 | mDescription = o.optString("description"); 31 | } 32 | 33 | public String getSku() { 34 | return mSku; 35 | } 36 | 37 | public String getType() { 38 | return mType; 39 | } 40 | 41 | public String getPrice() { 42 | return mPrice; 43 | } 44 | 45 | public String getTitle() { 46 | return mTitle; 47 | } 48 | 49 | public String getDescription() { 50 | return mDescription; 51 | } 52 | 53 | @Override 54 | public String toString() { 55 | return "SkuDetails:" + mJson; 56 | } 57 | } -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/ovl/AbstractOverlayButtonFreeView.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.ovl; 2 | 3 | import android.content.res.Configuration; 4 | 5 | import io.oversec.one.Core; 6 | 7 | public abstract class AbstractOverlayButtonFreeView extends AbstractOverlayButtonView { 8 | protected int mLandscapeX, mLandscapeY; 9 | protected int mPortraitX, mPortraitY; 10 | 11 | public AbstractOverlayButtonFreeView(Core core, String packageName) { 12 | super(core, packageName); 13 | } 14 | 15 | 16 | @Override 17 | protected void storeTransientPosition(int x, int y) { 18 | if (Configuration.ORIENTATION_PORTRAIT == mOrientation) { 19 | mPortraitX = mLayoutParams.x; 20 | mPortraitY = mLayoutParams.y; 21 | } else { 22 | mLandscapeX = mLayoutParams.x; 23 | mLandscapeY = mLayoutParams.y; 24 | } 25 | } 26 | 27 | @Override 28 | public void onScrapeComplete(NodeTextView focusedView, boolean hasVisibleNodes) { 29 | 30 | if (isImeFullScreen()) { 31 | hideSelf(true); 32 | } else { 33 | hideSelf(false); 34 | updatePosition(); 35 | } 36 | 37 | } 38 | 39 | @Override 40 | protected void updatePosition() { 41 | setPosition(mOrientation == Configuration.ORIENTATION_PORTRAIT ? mPortraitX : mLandscapeX, 42 | mOrientation == Configuration.ORIENTATION_PORTRAIT ? mPortraitY : mLandscapeY); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/ovl/AbstractOverlayTouchableView.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.ovl; 2 | 3 | import android.content.Context; 4 | import android.graphics.PixelFormat; 5 | import android.view.Gravity; 6 | import android.view.WindowManager; 7 | import io.oversec.one.Core; 8 | 9 | public abstract class AbstractOverlayTouchableView extends OverlayView { 10 | 11 | public AbstractOverlayTouchableView(Core core, String packageName) { 12 | super(core, packageName); 13 | } 14 | 15 | @Override 16 | protected WindowManager.LayoutParams createLayoutParams(Context ctx) { 17 | 18 | WindowManager.LayoutParams res = new WindowManager.LayoutParams( 19 | getMyWidth(), 20 | getMyHeight(), 21 | 0, 22 | 0, 23 | getOverlayType(), 24 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL 25 | | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN 26 | , PixelFormat.TRANSLUCENT); 27 | 28 | 29 | res.flags = res.flags | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; 30 | 31 | res.gravity = Gravity.TOP | Gravity.LEFT; 32 | 33 | return res; 34 | } 35 | 36 | protected abstract int getMyWidth(); 37 | 38 | protected abstract int getMyHeight(); 39 | 40 | 41 | } 42 | -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/ovl/IDragListener.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.ovl; 2 | 3 | public interface IDragListener { 4 | void onDrag(int x, int y); 5 | } 6 | -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/ovl/NodeView.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.ovl; 2 | 3 | import android.graphics.Rect; 4 | 5 | import io.oversec.one.acs.Tree; 6 | 7 | public interface NodeView { 8 | void setUnused(); 9 | 10 | boolean isUnused(); 11 | 12 | void recycle(); 13 | 14 | int getNodeKey(); 15 | 16 | void update(Tree.TreeNode node, Rect parentBoundsInScreen); 17 | 18 | boolean matchesNodeType(Tree.TreeNode node); 19 | 20 | Tree.TreeNode getNode(); 21 | 22 | 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/ovl/OverlayButtonCameraView.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.ovl; 2 | 3 | import android.view.View; 4 | 5 | import io.oversec.one.Core; 6 | import io.oversec.one.R; 7 | import io.oversec.one.db.Db; 8 | 9 | public class OverlayButtonCameraView extends AbstractOverlayButtonFreeView { 10 | 11 | public OverlayButtonCameraView(Core core, String packageName) { 12 | super(core, packageName); 13 | 14 | int myWH = isSmall() ? WH_SMALL_PX : WH_PX; 15 | 16 | mLandscapeX = mCore.getDb().getButtonCameraLandscapeX(mPackageName, 0); 17 | mLandscapeY = mCore.getDb().getButtonCameraLandscapeY(mPackageName, Integer.MAX_VALUE); 18 | 19 | mPortraitX = mCore.getDb().getButtonCameraPortraitX(mPackageName, 0); 20 | mPortraitY = mCore.getDb().getButtonCameraPortraitY(mPackageName, Integer.MAX_VALUE); 21 | 22 | mView.setImageResource(R.drawable.ic_camera_alt_black_24dp); 23 | } 24 | 25 | @Override 26 | void onSingleTap() { 27 | 28 | mCore.onButtonCameraSingleTap(); 29 | } 30 | 31 | @Override 32 | void onLongTap() { 33 | } 34 | 35 | @Override 36 | protected void store(Db db) { 37 | mCore.getDb().setButtonCameraLandscapeX(mPackageName, mLandscapeX); 38 | mCore.getDb().setButtonCameraLandscapeY(mPackageName, mLandscapeY); 39 | mCore.getDb().setButtonCameraPortraitX(mPackageName, mPortraitX); 40 | mCore.getDb().setButtonCameraPortraitY(mPackageName, mPortraitY); 41 | } 42 | 43 | public View getButtonView() { 44 | return mView; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/ovl/OverlayButtonComposeView.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.ovl; 2 | 3 | import android.view.View; 4 | 5 | import io.oversec.one.Core; 6 | import io.oversec.one.R; 7 | import io.oversec.one.crypto.Help; 8 | import io.oversec.one.db.Db; 9 | 10 | public class OverlayButtonComposeView extends AbstractOverlayButtonFreeView { 11 | 12 | public OverlayButtonComposeView(Core core, String packageName) { 13 | super(core, packageName); 14 | 15 | int myWH = isSmall() ? WH_SMALL_PX : WH_PX; 16 | 17 | mLandscapeX = mCore.getDb().getButtonComposeLandscapeX(mPackageName, 0); 18 | mLandscapeY = mCore.getDb().getButtonComposeLandscapeY(mPackageName, Integer.MAX_VALUE); 19 | 20 | mPortraitX = mCore.getDb().getButtonComposePortraitX(mPackageName, 0); 21 | mPortraitY = mCore.getDb().getButtonComposePortraitY(mPackageName, Integer.MAX_VALUE); 22 | 23 | mView.setImageResource(R.drawable.ic_create_black_24dp); 24 | } 25 | 26 | @Override 27 | void onSingleTap() { 28 | 29 | mCore.onButtonComposeSingleTap(); 30 | } 31 | 32 | @Override 33 | void onLongTap() { 34 | } 35 | 36 | @Override 37 | public void onScrapeComplete(NodeTextView focusedView, boolean hasVisibleNodes) { 38 | super.onScrapeComplete(focusedView, hasVisibleNodes); 39 | if (!isHidden()) { 40 | mCore.showTooltip_UI(this, 41 | mCore.getCtx().getString(R.string.tooltip_buttoncompose), 42 | getContext().getString(R.string.tooltipid_buttoncompose), 43 | Help.ANCHOR.button_compose, false); 44 | } 45 | } 46 | 47 | @Override 48 | protected void store(Db db) { 49 | mCore.getDb().setButtonComposeLandscapeX(mPackageName, mLandscapeX); 50 | mCore.getDb().setButtonComposeLandscapeY(mPackageName, mLandscapeY); 51 | mCore.getDb().setButtonComposePortraitX(mPackageName, mPortraitX); 52 | mCore.getDb().setButtonComposePortraitY(mPackageName, mPortraitY); 53 | 54 | } 55 | 56 | public View getButtonView() { 57 | return mView; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/ovl/OverlayButtonConfigView.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.ovl; 2 | 3 | import android.view.View; 4 | 5 | import io.oversec.one.Core; 6 | import io.oversec.one.R; 7 | import io.oversec.one.db.Db; 8 | 9 | public class OverlayButtonConfigView extends AbstractOverlayButtonFreeView { 10 | 11 | public OverlayButtonConfigView(Core core, String packageName) { 12 | super(core, packageName); 13 | 14 | int myWH = isSmall() ? WH_SMALL_PX : WH_PX; 15 | 16 | mLandscapeX = mCore.getDb().getButtonConfigLandscapeX(mPackageName, 0); 17 | mLandscapeY = mCore.getDb().getButtonConfigLandscapeY(mPackageName, STATUSBAR_PLUS_ACTIONBAR_HEIGHT_PX); 18 | 19 | mPortraitX = mCore.getDb().getButtonConfigPortraitX(mPackageName, 0); 20 | mPortraitY = mCore.getDb().getButtonConfigPortraitY(mPackageName, STATUSBAR_PLUS_ACTIONBAR_HEIGHT_PX); 21 | 22 | mView.setImageResource(R.drawable.ic_settings_black_24dp); 23 | } 24 | 25 | @Override 26 | void onSingleTap() { 27 | 28 | mCore.onButtonConfigSingleTap(); 29 | } 30 | 31 | @Override 32 | void onLongTap() { 33 | mCore.onButtonConfigLongTap(); 34 | } 35 | 36 | @Override 37 | protected void store(Db db) { 38 | mCore.getDb().setButtonConfigLandscapeX(mPackageName, mLandscapeX); 39 | mCore.getDb().setButtonConfigLandscapeY(mPackageName, mLandscapeY); 40 | mCore.getDb().setButtonConfigPortraitX(mPackageName, mPortraitX); 41 | mCore.getDb().setButtonConfigPortraitY(mPackageName, mPortraitY); 42 | 43 | } 44 | 45 | public View getButtonView() { 46 | return mView; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/ovl/OverlayButtonHideView.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.ovl; 2 | 3 | import android.graphics.drawable.Drawable; 4 | 5 | import io.oversec.one.Core; 6 | import io.oversec.one.R; 7 | import io.oversec.one.db.Db; 8 | 9 | public class OverlayButtonHideView extends AbstractOverlayButtonFreeView { 10 | 11 | private final Drawable mVisibleBackground; 12 | 13 | public OverlayButtonHideView(Core core, String packageName) { 14 | super(core, packageName); 15 | 16 | int maxDim = Math.max(mDisplayWidth, mDisplayHeight); 17 | int minDim = Math.min(mDisplayWidth, mDisplayHeight); 18 | 19 | int myWH = isSmall() ? WH_SMALL_PX : WH_PX; 20 | 21 | mLandscapeX = mCore.getDb().getButtonHideLandscapeX(mPackageName, maxDim - myWH); 22 | mLandscapeY = mCore.getDb().getButtonHideLandscapeY(mPackageName, STATUSBAR_PLUS_ACTIONBAR_HEIGHT_PX); 23 | 24 | mPortraitX = mCore.getDb().getButtonHidePortraitX(mPackageName, minDim - myWH); 25 | mPortraitY = mCore.getDb().getButtonHidePortraitY(mPackageName, STATUSBAR_PLUS_ACTIONBAR_HEIGHT_PX); 26 | 27 | setImage(); 28 | 29 | mVisibleBackground = mView.getBackground(); 30 | } 31 | 32 | private void setImage() { 33 | mView.setImageResource(R.drawable.ic_not_interested_black_24dp); 34 | } 35 | 36 | @Override 37 | void onSingleTap() { 38 | mCore.onButtonHideSingleTap(); 39 | } 40 | 41 | @Override 42 | void onLongTap() { 43 | mCore.onButtonHideLongTap(); 44 | } 45 | 46 | @Override 47 | void onDoubleTap() { 48 | mCore.onButtonHideDoubleTap(); 49 | } 50 | 51 | 52 | @Override 53 | protected void store(Db db) { 54 | mCore.getDb().setButtonHideLandscapeX(mPackageName, mLandscapeX); 55 | mCore.getDb().setButtonHideLandscapeY(mPackageName, mLandscapeY); 56 | mCore.getDb().setButtonHidePortraitX(mPackageName, mPortraitX); 57 | mCore.getDb().setButtonHidePortraitY(mPackageName, mPortraitY); 58 | } 59 | 60 | public void hideButton(boolean hidden) { 61 | if (hidden) { 62 | mView.setBackground(null); 63 | mView.setImageDrawable(null); 64 | } else { 65 | mView.setBackground(mVisibleBackground); 66 | setImage(); 67 | } 68 | } 69 | 70 | @Override 71 | public boolean isHidden() { 72 | return mHiddenMaster || mHiddenSelf; 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/ovl/OverlayButtonInfomodeView.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.ovl; 2 | 3 | import android.support.v4.content.ContextCompat; 4 | 5 | import io.oversec.one.Core; 6 | import io.oversec.one.db.Db; 7 | 8 | import io.oversec.one.R; 9 | 10 | public class OverlayButtonInfomodeView extends AbstractOverlayButtonFreeView { 11 | 12 | public OverlayButtonInfomodeView(Core core, String packageName) { 13 | super(core, packageName); 14 | 15 | int myWH = isSmall() ? WH_SMALL_PX : WH_PX; 16 | 17 | mLandscapeX = mCore.getDb().getButtonInfomodeLandscapeX(mPackageName, 0); 18 | mLandscapeY = mCore.getDb().getButtonInfomodeLandscapeY(mPackageName, myWH * 2); 19 | 20 | mPortraitX = mCore.getDb().getButtonInfomodePortraitX(mPackageName, 0); 21 | mPortraitY = mCore.getDb().getButtonInfomodePortraitY(mPackageName, myWH * 2); 22 | 23 | mView.setImageResource(R.drawable.ic_info_outline_black_24dp); 24 | } 25 | 26 | @Override 27 | void onSingleTap() { 28 | 29 | mCore.onButtonInfomodeSingleTap(); 30 | } 31 | 32 | @Override 33 | void onLongTap() { 34 | mCore.onButtonInfomodeLongTap(); 35 | } 36 | 37 | @Override 38 | protected void store(Db db) { 39 | mCore.getDb().setButtonInfomodeLandscapeX(mPackageName, mLandscapeX); 40 | mCore.getDb().setButtonInfomodeLandscapeY(mPackageName, mLandscapeY); 41 | mCore.getDb().setButtonInfomodePortraitX(mPackageName, mPortraitX); 42 | mCore.getDb().setButtonInfomodePortraitY(mPackageName, mPortraitY); 43 | } 44 | 45 | @Override 46 | public void onScrapeComplete(NodeTextView focusedView, boolean hasVisibleNodes) { 47 | super.onScrapeComplete(focusedView, hasVisibleNodes); 48 | 49 | //TODO: maybe make this configurable 50 | hideSelf(!hasVisibleNodes); 51 | 52 | if (mCore.isInfoMode()) { 53 | mView.setImageDrawable(ContextCompat.getDrawable(getContext(), R.drawable.ic_clear_black_24dp)); 54 | } else { 55 | mView.setImageDrawable(ContextCompat.getDrawable(getContext(), R.drawable.ic_info_outline_black_24dp)); 56 | } 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/ovl/OverlayButtonUpgradeView.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.ovl; 2 | 3 | import android.support.v4.content.res.ResourcesCompat; 4 | 5 | import io.oversec.one.Core; 6 | import io.oversec.one.R; 7 | import io.oversec.one.db.Db; 8 | import io.oversec.one.iab.IabUtil; 9 | import roboguice.util.Ln; 10 | 11 | public class OverlayButtonUpgradeView extends AbstractOverlayButtonFreeView { 12 | 13 | public OverlayButtonUpgradeView(Core core, String packageName) { 14 | super(core, packageName); 15 | 16 | int myWH = isSmall() ? WH_SMALL_PX : WH_PX; 17 | 18 | mPortraitX = mDisplayWidth / 2 - myWH / 2; 19 | mPortraitY = mDisplayHeight / 2 - myWH / 2; 20 | 21 | //noinspection SuspiciousNameCombination 22 | mLandscapeX = mPortraitY; 23 | //noinspection SuspiciousNameCombination 24 | mLandscapeY = mPortraitX; 25 | 26 | 27 | mView.setImageDrawable(null); 28 | mView.setBackground(null); 29 | 30 | mView.postDelayed(new Runnable() { 31 | @Override 32 | public void run() { 33 | try { 34 | mView.setImageResource(R.drawable.ic_shop_black_24dp); 35 | mView.setBackground( 36 | ResourcesCompat.getDrawable(getResources(), R.drawable.fab_bg, getContext().getTheme())); 37 | } catch (Exception ex) { 38 | 39 | } 40 | } 41 | }, IabUtil.getInstance(getContext()).getUpgradeButtonDelay(mView.getContext())); 42 | } 43 | 44 | @Override 45 | protected void setButtonColor() { 46 | //reset the buttons bg to the default! 47 | mView.setBackground( 48 | ResourcesCompat.getDrawable(getResources(), R.drawable.fab_bg, getContext().getTheme())); 49 | } 50 | 51 | @Override 52 | void onSingleTap() { 53 | mCore.onButtonUpgradeSingleTap(); 54 | } 55 | 56 | @Override 57 | void onLongTap() { 58 | } 59 | 60 | @Override 61 | protected void store(Db db) { 62 | //NO store, alyway show in the middle of the screen 63 | } 64 | 65 | @Override 66 | public void onScrapeComplete(NodeTextView focusedView, boolean hasVisibleNodes) { 67 | super.onScrapeComplete(focusedView, hasVisibleNodes); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/ovl/OverlayDialogCorruptedEncodingView.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.ovl; 2 | 3 | import android.view.View; 4 | 5 | import io.oversec.one.Core; 6 | import io.oversec.one.R; 7 | import io.oversec.one.crypto.Help; 8 | 9 | public class OverlayDialogCorruptedEncodingView extends AbstractOverlayDialogView { 10 | 11 | public OverlayDialogCorruptedEncodingView(Core core, String packageName, View anchor) { 12 | super(core, packageName, anchor); 13 | init(); 14 | } 15 | 16 | @Override 17 | int getIconResId() { 18 | return R.drawable.ic_warning_black_24dp; 19 | } 20 | 21 | @Override 22 | String getText() { 23 | return getResources().getString(R.string.toast_corrupted_encoding); 24 | } 25 | 26 | @Override 27 | String getOkText() { 28 | return getResources().getString(R.string.action_clear_input); 29 | } 30 | 31 | @Override 32 | String getCancelText() { 33 | return null; 34 | } 35 | 36 | @Override 37 | String getNeutralText() { 38 | return getResources().getString(R.string.action_moreinfo); 39 | } 40 | 41 | @Override 42 | void onOkPressed() { 43 | mCore.dismissOverlayDialogCorruptedEncoding_UI(); 44 | mCore.clearCurrentFocusedEditText_UI(); 45 | } 46 | 47 | @Override 48 | void onCancelPressed() { 49 | } 50 | 51 | @Override 52 | void onNeutralPressed() { 53 | Help.INSTANCE.open(getContext(), Help.ANCHOR.input_corruptedencoding); 54 | } 55 | 56 | @Override 57 | protected boolean forceOnTop() { 58 | return true; 59 | } 60 | 61 | protected int getExtraToolTipHeight() { 62 | return mCore.dipToPixels(20); 63 | } 64 | 65 | @Override 66 | public void onScrapeComplete(NodeTextView focusedView) { 67 | mAnchor = focusedView; 68 | super.onScrapeComplete(focusedView); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/ovl/OverlayDialogInsufficientPaddingView.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.ovl; 2 | 3 | import android.view.View; 4 | 5 | import io.oversec.one.Core; 6 | import io.oversec.one.R; 7 | import io.oversec.one.crypto.Help; 8 | import io.oversec.one.crypto.ui.util.GotItPreferences; 9 | 10 | public class OverlayDialogInsufficientPaddingView extends AbstractOverlayDialogView { 11 | 12 | final static String PREF_KEY = "toast_insufficient_padding_3"; 13 | 14 | public OverlayDialogInsufficientPaddingView(Core core, String packageName, View anchor) { 15 | super(core, packageName, anchor); 16 | init(); 17 | } 18 | 19 | @Override 20 | int getIconResId() { 21 | return R.drawable.ic_warning_black_24dp; 22 | } 23 | 24 | @Override 25 | String getText() { 26 | return getResources().getString(R.string.toast_insufficient_padding); 27 | } 28 | 29 | @Override 30 | String getOkText() { 31 | return getResources().getString(R.string.action_gotit); 32 | } 33 | 34 | @Override 35 | String getCancelText() { 36 | return getResources().getString(R.string.action_dismiss); 37 | } 38 | 39 | @Override 40 | String getNeutralText() { 41 | return getResources().getString(R.string.action_moreinfo); 42 | } 43 | 44 | @Override 45 | void onOkPressed() { 46 | mCore.dismissOverlayDialogInsufficientPadding_UI(); 47 | GotItPreferences.Companion.getPreferences(getContext()).setTooltipConfirmed(getContext().getString(R.string.tooltipid_edittext_insufficientpadding)); 48 | } 49 | 50 | @Override 51 | void onCancelPressed() { 52 | mCore.dismissOverlayDialogInsufficientPadding_UI(); 53 | } 54 | 55 | @Override 56 | void onNeutralPressed() { 57 | Help.INSTANCE.open(getContext(), Help.ANCHOR.input_insufficientpadding); 58 | } 59 | 60 | @Override 61 | public void onScrapeComplete(NodeTextView focusedView) { 62 | mAnchor = focusedView; 63 | super.onScrapeComplete(focusedView); 64 | } 65 | 66 | @Override 67 | protected boolean forceOnTop() { 68 | return true; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/ovl/OverlayDialogToast.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.ovl; 2 | 3 | import io.oversec.one.Core; 4 | import io.oversec.one.R; 5 | 6 | /** 7 | * Created by yao on 09/04/16. 8 | */ 9 | public class OverlayDialogToast extends AbstractOverlayDialogView { 10 | 11 | public static final long DURATION_SHORT = 1000; 12 | public static final long DURATION_LONG = 3000; 13 | 14 | private final String mText; 15 | 16 | public OverlayDialogToast(Core core, String packageName, String text) { 17 | super(core, packageName); 18 | mText = text; 19 | init(); 20 | } 21 | 22 | @Override 23 | int getIconResId() { 24 | return R.drawable.ic_info_outline_black_24dp; 25 | } 26 | 27 | @Override 28 | String getText() { 29 | return mText; 30 | } 31 | 32 | @Override 33 | String getOkText() { 34 | return null; 35 | } 36 | 37 | @Override 38 | String getCancelText() { 39 | return null; 40 | } 41 | 42 | @Override 43 | String getNeutralText() { 44 | return null; 45 | } 46 | 47 | @Override 48 | void onOkPressed() { 49 | mCore.dismissOverlayToast(); 50 | } 51 | 52 | @Override 53 | void onCancelPressed() { 54 | } 55 | 56 | @Override 57 | void onNeutralPressed() { 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/ovl/OverlayDialogUpgrade.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.ovl; 2 | 3 | import io.oversec.one.Core; 4 | import io.oversec.one.R; 5 | import io.oversec.one.iab.IabUtil; 6 | 7 | public class OverlayDialogUpgrade extends AbstractOverlayDialogView { 8 | 9 | public OverlayDialogUpgrade(Core core) { 10 | super(core, null, null); 11 | init(); 12 | } 13 | 14 | @Override 15 | int getIconResId() { 16 | return R.drawable.ic_shop_black_24dp; 17 | } 18 | 19 | @Override 20 | String getText() { 21 | return getResources().getString(R.string.upgrade_overlay_msg); 22 | } 23 | 24 | @Override 25 | String getOkText() { 26 | return getResources().getString(R.string.action_upgrade); 27 | } 28 | 29 | @Override 30 | String getCancelText() { 31 | return getResources().getString(R.string.action_cancel); 32 | } 33 | 34 | @Override 35 | String getNeutralText() { 36 | return null; 37 | } 38 | 39 | @Override 40 | void onOkPressed() { 41 | mCore.removeUpgradeDialog(); 42 | IabUtil.getInstance(getContext()).showPurchaseActivity(getContext()); 43 | } 44 | 45 | @Override 46 | void onCancelPressed() { 47 | mCore.removeUpgradeDialog_UI(); 48 | } 49 | 50 | @Override 51 | void onNeutralPressed() { 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/ovl/OverlayDialogUserInteractionRequired.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.ovl; 2 | 3 | import io.oversec.one.Core; 4 | import io.oversec.one.R; 5 | 6 | public class OverlayDialogUserInteractionRequired extends AbstractOverlayDialogView { 7 | 8 | private final String mEncodedText; 9 | 10 | public OverlayDialogUserInteractionRequired(Core core, String packageName, String encodedText) { 11 | super(core, packageName, null); 12 | mEncodedText = encodedText; 13 | init(); 14 | } 15 | 16 | @Override 17 | int getIconResId() { 18 | return R.drawable.ic_warning_black_24dp; 19 | } 20 | 21 | @Override 22 | String getText() { 23 | return getResources().getString(R.string.decrypt_error_user_interaction_required__long); 24 | } 25 | 26 | @Override 27 | String getOkText() { 28 | return getResources().getString(R.string.action_ok); 29 | } 30 | 31 | @Override 32 | String getCancelText() { 33 | return getResources().getString(R.string.action_cancel); 34 | } 35 | 36 | @Override 37 | String getNeutralText() { 38 | return null; 39 | } 40 | 41 | @Override 42 | void onOkPressed() { 43 | mCore.onUserInteractionDialogConfirmed_UI(true, mEncodedText); 44 | } 45 | 46 | @Override 47 | void onCancelPressed() { 48 | mCore.onUserInteractionDialogConfirmed_UI(false, mEncodedText); 49 | } 50 | 51 | @Override 52 | void onNeutralPressed() { 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/ovl/OverlayOutsideTouchView.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.ovl; 2 | 3 | import android.content.Context; 4 | import android.graphics.PixelFormat; 5 | import android.view.Gravity; 6 | import android.view.MotionEvent; 7 | import android.view.WindowManager; 8 | 9 | import io.oversec.one.Core; 10 | 11 | public class OverlayOutsideTouchView extends OverlayView { 12 | 13 | public OverlayOutsideTouchView(Core core, String packagename) { 14 | super(core, packagename); 15 | } 16 | 17 | @Override 18 | protected WindowManager.LayoutParams createLayoutParams(Context ctx) { 19 | WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(); 20 | 21 | layoutParams.packageName = ctx.getPackageName(); 22 | layoutParams.alpha = 1; 23 | layoutParams.type = getOverlayType(); 24 | layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 25 | | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL 26 | | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM 27 | | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH; 28 | 29 | layoutParams.gravity = Gravity.CENTER; 30 | layoutParams.format = PixelFormat.TRANSLUCENT; 31 | 32 | layoutParams.x = 0; 33 | layoutParams.y = 0; 34 | layoutParams.width = 0; 35 | layoutParams.height = 0; 36 | 37 | return layoutParams; 38 | } 39 | 40 | @Override 41 | public boolean onTouchEvent(MotionEvent event) { 42 | if (event.getAction() == MotionEvent.ACTION_OUTSIDE) { 43 | mCore.startPreemptiveRefresh_UI(); 44 | } 45 | return false; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/ovl/OverlayView.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.ovl; 2 | 3 | import android.content.Context; 4 | import android.os.Build; 5 | import android.view.View; 6 | import android.view.WindowManager; 7 | import android.widget.AbsoluteLayout; 8 | 9 | import io.oversec.one.Core; 10 | import io.oversec.one.util.WrappedWindowManager; 11 | 12 | public abstract class OverlayView extends AbsoluteLayout { 13 | 14 | protected final Core mCore; 15 | protected final WrappedWindowManager mWm; 16 | protected final String mPackageName; 17 | protected WindowManager.LayoutParams mLayoutParams; 18 | protected boolean mHiddenMaster; 19 | protected boolean mHiddenSelf; 20 | 21 | public OverlayView(Core core, String packageName) { 22 | super(core.getCtx()); 23 | 24 | core.checkUiThread(); 25 | 26 | //prevent from events being sent to our own scraper 27 | setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS); 28 | 29 | mCore = core; 30 | mPackageName = packageName; 31 | updateLayoutParams(); 32 | mWm = WrappedWindowManager.get(core.getCtx()); 33 | updateVisibility(); 34 | 35 | } 36 | 37 | protected abstract WindowManager.LayoutParams createLayoutParams(Context ctx); 38 | 39 | public void updateLayoutParams() { 40 | mLayoutParams = createLayoutParams(mCore.getCtx()); 41 | } 42 | 43 | public WindowManager.LayoutParams getMyLayoutParams() { 44 | return mLayoutParams; 45 | } 46 | 47 | public void hideMaster(boolean hide) { 48 | mHiddenMaster = hide; 49 | updateVisibility(); 50 | } 51 | 52 | public void hideSelf(boolean hide) { 53 | mHiddenSelf = hide; 54 | updateVisibility(); 55 | } 56 | 57 | protected void updateVisibility() { 58 | int vis = isHidden() ? View.GONE : View.VISIBLE; 59 | if (vis != getVisibility()) { 60 | setVisibility(vis); 61 | } 62 | } 63 | 64 | public boolean isHidden() { 65 | return mHiddenMaster || mHiddenSelf || mCore.isTemporaryHidden_UI(mPackageName); 66 | } 67 | 68 | @Override 69 | public String toString() { 70 | return getClass().getSimpleName() + " [" + hashCode(); 71 | } 72 | 73 | protected static int getOverlayType() { 74 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { 75 | return WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; 76 | } else { 77 | return WindowManager.LayoutParams.TYPE_SYSTEM_ERROR; 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/ovl/SampleNodeTextView.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.ovl; 2 | 3 | import android.content.Context; 4 | import android.graphics.drawable.GradientDrawable; 5 | import android.util.AttributeSet; 6 | import android.util.TypedValue; 7 | import android.widget.TextView; 8 | 9 | import io.oversec.one.Core; 10 | import io.oversec.one.db.IDecryptOverlayLayoutParamsChangedListener; 11 | import io.oversec.one.db.Db; 12 | 13 | public class SampleNodeTextView extends TextView implements IDecryptOverlayLayoutParamsChangedListener { 14 | private GradientDrawable mBgShape; 15 | private Db mDb; 16 | private Core mCore; 17 | 18 | public SampleNodeTextView(Context context) { 19 | super(context); 20 | setUp(); 21 | } 22 | 23 | public SampleNodeTextView(Context context, AttributeSet attrs) { 24 | super(context, attrs); 25 | setUp(); 26 | } 27 | 28 | public SampleNodeTextView(Context context, AttributeSet attrs, int defStyleAttr) { 29 | super(context, attrs, defStyleAttr); 30 | setUp(); 31 | } 32 | 33 | private void setUp() { 34 | if (!isInEditMode()) { 35 | mCore = Core.getInstance(getContext()); 36 | mDb = mCore.getDb(); 37 | } 38 | 39 | mBgShape = new GradientDrawable(); 40 | setBackground(mBgShape); 41 | } 42 | 43 | @Override 44 | public void onDecryptOverlayLayoutParamsChanged(String packagename) { 45 | mBgShape.setCornerRadius(mCore.dipToPixels(mDb.getDecryptOverlayCornerRadius(packagename))); 46 | mBgShape.setColor(mDb.getDecryptOverlayBgColor(packagename)); 47 | 48 | setTextColor(mDb.getDecryptOverlayTextColor(packagename)); 49 | setTextSize(TypedValue.COMPLEX_UNIT_SP, 6 + mDb.getDecryptOverlayTextSize(packagename)); 50 | 51 | int statusIconResId = 0; 52 | if (mDb.isShowStatusIcon(packagename)) { 53 | statusIconResId = io.oversec.one.crypto.R.drawable.ic_done_all_green_a700_18dp; 54 | } 55 | setCompoundDrawablesWithIntrinsicBounds(0, 0, statusIconResId, 0); 56 | 57 | int paddingLeft = mCore.dipToPixels(mDb.getDecryptOverlayPaddingLeft(packagename)); 58 | int paddingTop = mCore.dipToPixels(mDb.getDecryptOverlayPaddingTop(packagename)); 59 | 60 | setPadding(paddingLeft, paddingTop, 0, 0); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/ui/AboutFragment.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.ui; 2 | 3 | import android.app.Fragment; 4 | import android.os.Bundle; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.widget.TextView; 9 | 10 | import io.oversec.one.BuildConfig; 11 | import io.oversec.one.R; 12 | 13 | import org.markdown4j.Markdown4jProcessor; 14 | import org.sufficientlysecure.htmltextview.HtmlAssetsImageGetter; 15 | import org.sufficientlysecure.htmltextview.HtmlTextView; 16 | 17 | import java.io.IOException; 18 | 19 | public class AboutFragment extends Fragment { 20 | 21 | public AboutFragment() { 22 | } 23 | 24 | @Override 25 | public View onCreateView(LayoutInflater inflater, ViewGroup container, 26 | Bundle savedInstanceState) { 27 | View v = inflater.inflate(R.layout.fragment_about, container, false); 28 | 29 | //TODO use a format string 30 | ((TextView) v.findViewById(R.id.help_about_version)).setText(BuildConfig.VERSION_NAME + " (" + BuildConfig.VERSION_CODE + ") " 31 | + (BuildConfig.DEBUG ? " DEBUG" : "") + " [" + BuildConfig.FLAVOR + "]"); 32 | 33 | HtmlTextView aboutTextView = (HtmlTextView) v.findViewById(R.id.about_text); 34 | 35 | try { 36 | String html = new Markdown4jProcessor().process( 37 | getActivity().getResources().openRawResource(R.raw.about)); 38 | 39 | 40 | aboutTextView.setHtml(html, new HtmlAssetsImageGetter(container.getContext())); 41 | } catch (IOException e) { 42 | e.printStackTrace(); 43 | } 44 | 45 | return v; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/ui/ActionAccessibilitySettingsNotResolvableActivity.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.ui; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | import android.content.pm.PackageManager; 7 | import android.os.Bundle; 8 | import android.provider.Settings; 9 | import android.view.View; 10 | import android.widget.Button; 11 | import io.oversec.one.Core; 12 | import io.oversec.one.R; 13 | import io.oversec.one.acs.util.AndroidIntegration; 14 | import io.oversec.one.crypto.Help; 15 | import io.oversec.one.crypto.ui.util.GotItPreferences; 16 | import roboguice.util.Ln; 17 | 18 | import java.util.Observable; 19 | import java.util.Observer; 20 | 21 | public class ActionAccessibilitySettingsNotResolvableActivity extends Activity { 22 | 23 | public static void show(Context ctx) { 24 | Intent i = new Intent(); 25 | i.setClass(ctx, ActionAccessibilitySettingsNotResolvableActivity.class); 26 | ctx.startActivity(i); 27 | } 28 | 29 | public static void showFromService(Context ctx) { 30 | Intent i = new Intent(); 31 | i.setClass(ctx, ActionAccessibilitySettingsNotResolvableActivity.class); 32 | i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 33 | ctx.startActivity(i); 34 | } 35 | 36 | @Override 37 | protected void onCreate(Bundle savedInstanceState) { 38 | super.onCreate(savedInstanceState); 39 | setContentView(R.layout.activity_actionaccessibilitysettingsnotresolvable); 40 | Button btOk = (Button) findViewById(R.id.btn_ok); 41 | btOk.setOnClickListener(new View.OnClickListener() { 42 | @Override 43 | public void onClick(View v) { 44 | 45 | finish(); 46 | 47 | Intent intent = new Intent( 48 | Settings.ACTION_SETTINGS); 49 | 50 | PackageManager packageManager = getPackageManager(); 51 | if (intent.resolveActivity(packageManager) != null) { 52 | startActivityForResult( 53 | intent, 54 | 0); 55 | 56 | } else { 57 | Ln.w("No Intent available to handle ACTION_SETTINGS"); 58 | } 59 | 60 | } 61 | }); 62 | 63 | Button btMoreInfo = (Button) findViewById(R.id.btn_moreinfo); 64 | btMoreInfo.setOnClickListener(new View.OnClickListener() { 65 | @Override 66 | public void onClick(View v) { 67 | Help.INSTANCE.open(ActionAccessibilitySettingsNotResolvableActivity.this, Help.ANCHOR.main_help_accessibilitysettingsnotresolvable); 68 | 69 | } 70 | }); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/ui/ChangelogFragment.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.ui; 2 | 3 | 4 | import android.app.Fragment; 5 | import android.os.Bundle; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | 10 | import io.oversec.one.R; 11 | 12 | import org.markdown4j.Markdown4jProcessor; 13 | import org.sufficientlysecure.htmltextview.HtmlAssetsImageGetter; 14 | import org.sufficientlysecure.htmltextview.HtmlTextView; 15 | 16 | import java.io.IOException; 17 | 18 | 19 | public class ChangelogFragment extends Fragment { 20 | 21 | @Override 22 | public View onCreateView(LayoutInflater inflater, ViewGroup container, 23 | Bundle savedInstanceState) { 24 | View v = inflater.inflate(R.layout.fragment_changelog, container, false); 25 | 26 | 27 | HtmlTextView aboutTextView = (HtmlTextView) v.findViewById(R.id.changelog_text); 28 | 29 | try { 30 | String html = new Markdown4jProcessor().process( 31 | getActivity().getResources().openRawResource(R.raw.changelog)); 32 | aboutTextView.setHtml(html, new HtmlAssetsImageGetter(container.getContext())); 33 | } catch (IOException e) { 34 | e.printStackTrace(); 35 | } 36 | 37 | return v; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/ui/CheckboxPref.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.ui; 2 | 3 | import android.content.Context; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.widget.CheckBox; 7 | import android.widget.LinearLayout; 8 | import android.widget.TextView; 9 | 10 | import io.oversec.one.R; 11 | 12 | public abstract class CheckboxPref extends LinearLayout { 13 | public CheckboxPref(Context context, int titleResId, int subResId) { 14 | this(context, context.getString(titleResId), context.getString(subResId)); 15 | } 16 | 17 | public CheckboxPref(Context context, String head, String body) { 18 | super(context); 19 | LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 20 | inflater.inflate(R.layout.checkbox_pref, this); 21 | 22 | TextView title = (TextView) findViewById(R.id.pref_title); 23 | TextView sub = (TextView) findViewById(R.id.pref_sub); 24 | title.setText(head); 25 | sub.setText(body); 26 | 27 | final CheckBox cb = (CheckBox) findViewById(R.id.pref_checkbox); 28 | cb.setChecked(getValue()); 29 | 30 | cb.setOnClickListener(new View.OnClickListener() { 31 | 32 | @Override 33 | public void onClick(View v) { 34 | setValue( 35 | cb.isChecked()); 36 | 37 | } 38 | }); 39 | } 40 | 41 | abstract boolean getValue(); 42 | 43 | abstract void setValue(boolean b); 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/ui/DbCheckBoxPreference.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.ui; 2 | 3 | import android.content.Context; 4 | import android.preference.CheckBoxPreference; 5 | import android.preference.Preference; 6 | 7 | public abstract class DbCheckBoxPreference extends CheckBoxPreference { 8 | public DbCheckBoxPreference(Context ctx, String title, String summary) { 9 | super(ctx); 10 | setTitle(title); 11 | setSummary(summary); 12 | setChecked(getValue()); 13 | setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { 14 | @Override 15 | public boolean onPreferenceChange(Preference preference, Object newValue) { 16 | setValue((boolean)newValue); 17 | return true; 18 | } 19 | }); 20 | } 21 | 22 | protected abstract boolean getValue(); 23 | protected abstract void setValue(boolean b); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/ui/DialercodeEditTextPreference.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.ui; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | 6 | import io.oversec.one.R; 7 | 8 | 9 | import static io.oversec.one.ui.MainSettingsFragment.MIN_SECRETCODE_LENGTH; 10 | 11 | public class DialercodeEditTextPreference extends ValidatedEditTextPreference { 12 | 13 | public DialercodeEditTextPreference(Context context) { 14 | super(context); 15 | } 16 | 17 | public DialercodeEditTextPreference(Context context, AttributeSet attrs) { 18 | super(context, attrs); 19 | } 20 | 21 | public DialercodeEditTextPreference(Context context, AttributeSet attrs, int defStyleAttr) { 22 | super(context, attrs, defStyleAttr); 23 | } 24 | 25 | @Override 26 | protected boolean validateInput(ValidatedDialogPreference pref) { 27 | 28 | boolean res = getEditText().getText().toString().trim().length() >= MIN_SECRETCODE_LENGTH; 29 | if (!res) { 30 | getEditText().setError(getContext().getString(R.string.secretdialer_code_too_short, "" + MIN_SECRETCODE_LENGTH)); 31 | } 32 | return res; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/ui/DonationFragment.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.ui; 2 | 3 | import android.app.Fragment; 4 | import android.content.ClipData; 5 | import android.content.ClipboardManager; 6 | import android.graphics.Color; 7 | import android.os.Bundle; 8 | import android.text.Html; 9 | import android.text.Spannable; 10 | import android.text.SpannableString; 11 | import android.text.style.ForegroundColorSpan; 12 | import android.text.style.RelativeSizeSpan; 13 | import android.view.LayoutInflater; 14 | import android.view.View; 15 | import android.view.ViewGroup; 16 | import android.widget.Button; 17 | import android.widget.Toast; 18 | 19 | import io.oversec.one.BuildConfig; 20 | import io.oversec.one.R; 21 | 22 | import static android.content.Context.CLIPBOARD_SERVICE; 23 | 24 | public class DonationFragment extends Fragment { 25 | 26 | public DonationFragment() { 27 | } 28 | 29 | @Override 30 | public View onCreateView(LayoutInflater inflater, ViewGroup container, 31 | Bundle savedInstanceState) { 32 | View v = inflater.inflate(R.layout.fragment_donation, container, false); 33 | 34 | setButton(v, R.id.btn_btc, R.string.donate_btn_btc, BuildConfig.DONATION_BTC); 35 | setButton(v, R.id.btn_eth, R.string.donate_btn_eth, BuildConfig.DONATION_ETH); 36 | setButton(v, R.id.btn_iota, R.string.donate_btn_iota, BuildConfig.DONATION_IOTA); 37 | setButton(v, R.id.btn_dash, R.string.donate_btn_dash, BuildConfig.DONATION_DASH); 38 | 39 | return v; 40 | } 41 | 42 | private void setButton(final View v, int buttonId, int textId, final String address) { 43 | Button b = v.findViewById(buttonId); 44 | String coin = getString(textId); 45 | 46 | SpannableString spannable = new SpannableString(coin + "\n" + address); 47 | spannable.setSpan( 48 | new RelativeSizeSpan(1.5f), 49 | 0, coin.length(), 50 | Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 51 | spannable.setSpan( 52 | new RelativeSizeSpan(0.85f), 53 | coin.length() + 1, spannable.length(), 54 | Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 55 | b.setText(spannable); 56 | 57 | b.setOnClickListener(new View.OnClickListener() { 58 | @Override 59 | public void onClick(View view) { 60 | ClipboardManager clipboard = (ClipboardManager) v.getContext().getSystemService(CLIPBOARD_SERVICE); 61 | ClipData clip = ClipData.newPlainText(getString(R.string.donate_clip_label), address); 62 | clipboard.setPrimaryClip(clip); 63 | Toast.makeText(v.getContext(), R.string.donate_toast_copied, Toast.LENGTH_LONG).show(); 64 | } 65 | }); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/ui/ImeMemoryLeakWorkaroundDummyActivity.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.ui; 2 | 3 | import android.app.Activity; 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | import android.os.Handler; 7 | import android.support.annotation.Nullable; 8 | import android.support.v7.app.AppCompatActivity; 9 | 10 | import roboguice.util.Ln; 11 | 12 | public class ImeMemoryLeakWorkaroundDummyActivity extends AppCompatActivity { 13 | 14 | public static void maybeShow(Activity activity) { 15 | //see https://code.google.com/p/android/issues/detail?id=171190 16 | //see https://code.google.com/p/android/issues/detail?id=205171 17 | //TODO: suppress for Android >= N where that bug should finally be fixed! 18 | activity.startActivity(new Intent(activity, ImeMemoryLeakWorkaroundDummyActivity.class)); 19 | } 20 | 21 | @Override 22 | protected void onCreate(@Nullable Bundle savedInstanceState) { 23 | Ln.d("onCreate"); 24 | super.onCreate(savedInstanceState); 25 | new Handler().postDelayed(new Runnable() { 26 | @Override 27 | public void run() { 28 | finish(); 29 | } 30 | }, 100); 31 | } 32 | 33 | @Override 34 | protected void onDestroy() { 35 | Ln.d("onDestroy"); 36 | super.onDestroy(); 37 | } 38 | 39 | @Override 40 | protected void onStop() { 41 | Ln.d("onStop"); 42 | super.onStop(); 43 | } 44 | 45 | @Override 46 | protected void onStart() { 47 | Ln.d("onStart"); 48 | super.onStop(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/ui/IntSpinnerPref.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.ui; 2 | 3 | import android.content.Context; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.widget.AdapterView; 7 | import android.widget.ArrayAdapter; 8 | import android.widget.LinearLayout; 9 | import android.widget.Spinner; 10 | import android.widget.TextView; 11 | 12 | import io.oversec.one.R; 13 | 14 | public abstract class IntSpinnerPref extends LinearLayout { 15 | public IntSpinnerPref(Context context, int titleResId, int subResId, Integer[] items) { 16 | super(context); 17 | LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 18 | inflater.inflate(R.layout.intspinner_pref, this); 19 | 20 | TextView title = (TextView) findViewById(R.id.pref_title); 21 | TextView sub = (TextView) findViewById(R.id.pref_sub); 22 | title.setText(titleResId); 23 | sub.setText(subResId); 24 | 25 | final Spinner sp = (Spinner) findViewById(R.id.pref_spinner); 26 | 27 | final ArrayAdapter adapter = new ArrayAdapter<>(context, R.layout.intspinner_item, items); 28 | sp.setAdapter(adapter); 29 | 30 | sp.setSelection(adapter.getPosition(getValue())); 31 | 32 | sp.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { 33 | @Override 34 | public void onItemSelected(AdapterView parent, View view, int position, long id) { 35 | setValue(adapter.getItem(position)); 36 | } 37 | 38 | @Override 39 | public void onNothingSelected(AdapterView parent) { 40 | setValue(0); 41 | } 42 | }); 43 | } 44 | 45 | abstract int getValue(); 46 | 47 | abstract void setValue(int v); 48 | } 49 | -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/ui/ManageOverlayPermissionWarningActivity.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.ui; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | import android.net.Uri; 7 | import android.os.Build; 8 | import android.os.Bundle; 9 | import android.provider.Settings; 10 | import android.util.TimeUtils; 11 | import android.view.View; 12 | import android.widget.Button; 13 | import io.oversec.one.Core; 14 | import io.oversec.one.R; 15 | import io.oversec.one.acs.util.AndroidIntegration; 16 | import io.oversec.one.crypto.Help; 17 | import io.oversec.one.crypto.ui.util.GotItPreferences; 18 | import roboguice.util.Ln; 19 | 20 | import java.util.Observable; 21 | import java.util.Observer; 22 | import java.util.concurrent.TimeUnit; 23 | 24 | public class ManageOverlayPermissionWarningActivity extends Activity { 25 | private static long LATER = 0; 26 | 27 | public static void show(Context ctx) { 28 | if (System.currentTimeMillis()= Build.VERSION_CODES.M) { 67 | if (Settings.canDrawOverlays(this)) { 68 | finish(); 69 | } 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/ui/MaxHeightScrollView.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.ui; 2 | 3 | import android.content.Context; 4 | import android.content.res.TypedArray; 5 | import android.util.AttributeSet; 6 | import android.widget.ScrollView; 7 | 8 | import io.oversec.one.R; 9 | 10 | public class MaxHeightScrollView extends ScrollView { 11 | private int maxHeight; 12 | 13 | public MaxHeightScrollView(Context context) { 14 | super(context); 15 | } 16 | 17 | public MaxHeightScrollView(Context context, AttributeSet attrs) { 18 | super(context, attrs); 19 | init(attrs); 20 | } 21 | 22 | public MaxHeightScrollView(Context context, AttributeSet attrs, int defStyleAttr) { 23 | super(context, attrs, defStyleAttr); 24 | init(attrs); 25 | } 26 | 27 | private void init(AttributeSet attrs) { 28 | TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.MaxHeightScrollView); 29 | final int N = a.getIndexCount(); 30 | for (int i = 0; i < N; ++i) { 31 | int attr = a.getIndex(i); 32 | switch (attr) { 33 | case R.styleable.MaxHeightScrollView_maxxxHeight: 34 | setMaxHeight(a.getDimensionPixelSize(i, 0)); 35 | break; 36 | } 37 | } 38 | a.recycle(); 39 | } 40 | 41 | @Override 42 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 43 | heightMeasureSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST); 44 | super.onMeasure(widthMeasureSpec, heightMeasureSpec); 45 | } 46 | 47 | public void setMaxHeight(int maxHeight) { 48 | this.maxHeight = maxHeight; 49 | } 50 | 51 | public int getMaxHeight() { 52 | return maxHeight; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/ui/encparams/ActivityResultWrapper.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.ui.encparams; 2 | 3 | import android.content.Intent; 4 | 5 | public class ActivityResultWrapper { 6 | private final int mRequestCode; 7 | private final int mResultCode; 8 | private final Intent mData; 9 | 10 | public ActivityResultWrapper(int requestCode, int resultCode, Intent data) { 11 | mRequestCode = requestCode; 12 | mResultCode = resultCode; 13 | mData = data; 14 | } 15 | 16 | public int getRequestCode() { 17 | return mRequestCode; 18 | } 19 | 20 | public int getResultCode() { 21 | return mResultCode; 22 | } 23 | 24 | public Intent getData() { 25 | return mData; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/io/oversec/one/util/WrappedWindowManager.java: -------------------------------------------------------------------------------- 1 | package io.oversec.one.util; 2 | 3 | import android.content.Context; 4 | import android.os.Build; 5 | import android.provider.Settings; 6 | import android.view.Display; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | import android.view.WindowManager; 10 | 11 | import io.oversec.one.ovl.OverlayView; 12 | import io.oversec.one.ui.ManageOverlayPermissionWarningActivity; 13 | 14 | public class WrappedWindowManager { 15 | private static WrappedWindowManager INSTANCE; 16 | private final WindowManager mWm; 17 | private final Context mCtx; 18 | 19 | private WrappedWindowManager(Context ctx) { 20 | mCtx = ctx; 21 | mWm = (WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE); 22 | } 23 | 24 | public static synchronized WrappedWindowManager get(Context ctx) { 25 | if (INSTANCE == null) { 26 | INSTANCE = new WrappedWindowManager(ctx.getApplicationContext()); 27 | } 28 | return INSTANCE; 29 | } 30 | 31 | public Display getDefaultDisplay() { 32 | return mWm.getDefaultDisplay(); 33 | } 34 | 35 | public void updateViewLayout(View v, ViewGroup.LayoutParams params) { 36 | try { 37 | mWm.updateViewLayout(v, params); 38 | } catch (Exception ex) { 39 | checkOrShowManageOverlayPermissionIntent(mCtx); 40 | } 41 | } 42 | 43 | public static void checkOrShowManageOverlayPermissionIntent(Context ctx) { 44 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 45 | if (!Settings.canDrawOverlays(ctx)) { 46 | ManageOverlayPermissionWarningActivity.show(ctx); 47 | } 48 | } 49 | } 50 | 51 | public void removeView(View v) { 52 | try { 53 | mWm.removeView(v); 54 | } catch (Exception ex) { 55 | checkOrShowManageOverlayPermissionIntent(mCtx); 56 | } 57 | } 58 | 59 | public void addView(OverlayView v, ViewGroup.LayoutParams params) { 60 | try { 61 | mWm.addView(v, params); 62 | } catch (Exception ex) { 63 | checkOrShowManageOverlayPermissionIntent(mCtx); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_backspace_black_18dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-hdpi/ic_backspace_black_18dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_backspace_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-hdpi/ic_backspace_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_camera_alt_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-hdpi/ic_camera_alt_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_cancel_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-hdpi/ic_cancel_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_cancel_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-hdpi/ic_cancel_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_create_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-hdpi/ic_create_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_help_outline_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-hdpi/ic_help_outline_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_help_outline_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-hdpi/ic_help_outline_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_info_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-hdpi/ic_info_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_info_outline_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-hdpi/ic_info_outline_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_info_outline_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-hdpi/ic_info_outline_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_lock_open_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-hdpi/ic_lock_open_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_mail_outline_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-hdpi/ic_mail_outline_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_not_interested_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-hdpi/ic_not_interested_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_not_interested_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-hdpi/ic_not_interested_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_question_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-hdpi/ic_question_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_settings_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-hdpi/ic_settings_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_share_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-hdpi/ic_share_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_share_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-hdpi/ic_share_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_shop_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-hdpi/ic_shop_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_backspace_black_18dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-mdpi/ic_backspace_black_18dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_backspace_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-mdpi/ic_backspace_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_camera_alt_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-mdpi/ic_camera_alt_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_cancel_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-mdpi/ic_cancel_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_cancel_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-mdpi/ic_cancel_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_create_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-mdpi/ic_create_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_help_outline_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-mdpi/ic_help_outline_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_help_outline_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-mdpi/ic_help_outline_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_info_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-mdpi/ic_info_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_info_outline_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-mdpi/ic_info_outline_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_info_outline_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-mdpi/ic_info_outline_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_lock_open_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-mdpi/ic_lock_open_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_mail_outline_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-mdpi/ic_mail_outline_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_not_interested_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-mdpi/ic_not_interested_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_not_interested_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-mdpi/ic_not_interested_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_question_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-mdpi/ic_question_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_settings_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-mdpi/ic_settings_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_share_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-mdpi/ic_share_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_share_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-mdpi/ic_share_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_shop_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-mdpi/ic_shop_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_backspace_black_18dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xhdpi/ic_backspace_black_18dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_backspace_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xhdpi/ic_backspace_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_camera_alt_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xhdpi/ic_camera_alt_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_cancel_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xhdpi/ic_cancel_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_cancel_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xhdpi/ic_cancel_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_create_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xhdpi/ic_create_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_help_outline_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xhdpi/ic_help_outline_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_help_outline_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xhdpi/ic_help_outline_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_info_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xhdpi/ic_info_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_info_outline_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xhdpi/ic_info_outline_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_info_outline_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xhdpi/ic_info_outline_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_lock_open_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xhdpi/ic_lock_open_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_mail_outline_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xhdpi/ic_mail_outline_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_not_interested_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xhdpi/ic_not_interested_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_not_interested_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xhdpi/ic_not_interested_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_question_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xhdpi/ic_question_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_settings_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xhdpi/ic_settings_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_share_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xhdpi/ic_share_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_share_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xhdpi/ic_share_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_shop_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xhdpi/ic_shop_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_backspace_black_18dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xxhdpi/ic_backspace_black_18dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_backspace_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xxhdpi/ic_backspace_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_camera_alt_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xxhdpi/ic_camera_alt_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_cancel_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xxhdpi/ic_cancel_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_cancel_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xxhdpi/ic_cancel_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_create_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xxhdpi/ic_create_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_help_outline_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xxhdpi/ic_help_outline_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_help_outline_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xxhdpi/ic_help_outline_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_info_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xxhdpi/ic_info_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_info_outline_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xxhdpi/ic_info_outline_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_info_outline_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xxhdpi/ic_info_outline_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_lock_open_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xxhdpi/ic_lock_open_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_mail_outline_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xxhdpi/ic_mail_outline_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_not_interested_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xxhdpi/ic_not_interested_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_not_interested_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xxhdpi/ic_not_interested_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_question_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xxhdpi/ic_question_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_settings_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xxhdpi/ic_settings_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_share_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xxhdpi/ic_share_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_share_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xxhdpi/ic_share_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_shop_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xxhdpi/ic_shop_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_backspace_black_18dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xxxhdpi/ic_backspace_black_18dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_backspace_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xxxhdpi/ic_backspace_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_camera_alt_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xxxhdpi/ic_camera_alt_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_cancel_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xxxhdpi/ic_cancel_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_cancel_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xxxhdpi/ic_cancel_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_create_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xxxhdpi/ic_create_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_help_outline_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xxxhdpi/ic_help_outline_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_help_outline_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xxxhdpi/ic_help_outline_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_info_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xxxhdpi/ic_info_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_info_outline_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xxxhdpi/ic_info_outline_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_info_outline_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xxxhdpi/ic_info_outline_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_lock_open_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xxxhdpi/ic_lock_open_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_mail_outline_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xxxhdpi/ic_mail_outline_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_not_interested_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xxxhdpi/ic_not_interested_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_not_interested_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xxxhdpi/ic_not_interested_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_question_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xxxhdpi/ic_question_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_settings_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xxxhdpi/ic_settings_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_share_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xxxhdpi/ic_share_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_share_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xxxhdpi/ic_share_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_shop_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oversecio/oversec/790dd63b47e98137ede83884a9558550e6669e4b/app/src/main/res/drawable-xxxhdpi/ic_shop_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/tooltip_bg_primary_headline.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 14 | 15 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/tooltip_bg_transparent.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 10 | 11 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_about.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 16 | 17 | 24 | 25 | 26 | 27 | 28 | 38 | 39 | 40 | 47 | 48 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_crash.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 14 | 15 | 21 | 22 | 23 | 24 | 25 | 26 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_encryption_params.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 20 | 21 | 28 | 29 | 35 | 36 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 16 | 17 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_padder_detail.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 14 | 15 | 21 | 22 | 23 | 24 | 25 | 26 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_purchase.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 14 | 22 | 23 | 30 | 31 | 32 | 37 | 38 | 39 | 45 | 46 | 54 | 55 | 56 | 61 | 62 | 63 | 71 | 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_warning.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/layout/checkbox_pref.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 18 | 19 | 28 | 29 | 39 | 40 | 41 | 42 | 49 | 50 | -------------------------------------------------------------------------------- /app/src/main/res/layout/content_crash.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 22 | 23 | 29 | 30 | 37 | 38 | 39 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /app/src/main/res/layout/content_encryption_params.xml: -------------------------------------------------------------------------------- 1 | 2 | 14 | 15 | 16 | 23 | 24 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /app/src/main/res/layout/content_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 14 | 15 | 16 | 23 | 24 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /app/src/main/res/layout/content_padder_detail.xml: -------------------------------------------------------------------------------- 1 | 2 | 14 | 15 | 20 | 21 | 25 | 26 | 27 | 28 | 29 | 33 | 34 | 39 | 40 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_about.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 19 | 20 | 24 | 25 | 29 | 30 | 36 | 37 | 38 | 42 | 43 | 49 | 50 | 56 | 57 | 58 | 59 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_changelog.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_donation.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 18 | 19 | 26 | 27 | 31 | 32 |