diff --git a/app/build.gradle b/app/build.gradle index cc1f2ee95f..0735420030 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -89,7 +89,7 @@ android { versionName "3.60" applicationId "io.stormbird.wallet" - minSdkVersion 23 + minSdkVersion 24 targetSdkVersion 32 testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' testInstrumentationRunnerArguments clearPackageData: 'true' @@ -243,8 +243,7 @@ dependencies { // WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! // Ethereum client - //implementation "org.web3j:core:4.8.8-android" - implementation fileTree(include: ['*.jar'], dir: 'libs') + implementation "org.web3j:core:4.8.7-android" implementation 'com.fasterxml.jackson.core:jackson-core:2.13.3' implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.3' implementation 'org.slf4j:slf4j-api:2.0.0-alpha7' diff --git a/app/libs/abi-4.8.8-android.jar b/app/libs/abi-4.8.8-android.jar deleted file mode 100644 index 889de4d8d6..0000000000 Binary files a/app/libs/abi-4.8.8-android.jar and /dev/null differ diff --git a/app/libs/core-4.8.8-android.jar b/app/libs/core-4.8.8-android.jar deleted file mode 100644 index 4d7cf4511e..0000000000 Binary files a/app/libs/core-4.8.8-android.jar and /dev/null differ diff --git a/app/libs/crypto-4.8.8-android.jar b/app/libs/crypto-4.8.8-android.jar deleted file mode 100644 index b14d4eec73..0000000000 Binary files a/app/libs/crypto-4.8.8-android.jar and /dev/null differ diff --git a/app/libs/rlp-4.8.8-android.jar b/app/libs/rlp-4.8.8-android.jar deleted file mode 100644 index 5d4a4ead9a..0000000000 Binary files a/app/libs/rlp-4.8.8-android.jar and /dev/null differ diff --git a/app/libs/utils-4.8.8-android.jar b/app/libs/utils-4.8.8-android.jar deleted file mode 100644 index a4500aa0d8..0000000000 Binary files a/app/libs/utils-4.8.8-android.jar and /dev/null differ diff --git a/app/src/androidTest/java/com/alphawallet/app/util/Helper.java b/app/src/androidTest/java/com/alphawallet/app/util/Helper.java index 952e194a39..fb057cceff 100644 --- a/app/src/androidTest/java/com/alphawallet/app/util/Helper.java +++ b/app/src/androidTest/java/com/alphawallet/app/util/Helper.java @@ -25,6 +25,7 @@ import org.hamcrest.Matchers; import java.util.concurrent.TimeoutException; +import java.util.stream.Stream; public class Helper { @@ -70,12 +71,10 @@ public void perform(final UiController uiController, final View view) do { - for (View child : TreeIterables.breadthFirstViewTraversal(view.getRootView())) + Iterable views = TreeIterables.breadthFirstViewTraversal(view.getRootView()); + if (Stream.of(views).anyMatch(matcher::matches)) { - if (matcher.matches(child)) - { - return; - } + return; } uiController.loopMainThreadForAtLeast(50); diff --git a/app/src/main/java/com/alphawallet/app/entity/ContractLocator.java b/app/src/main/java/com/alphawallet/app/entity/ContractLocator.java index d7c67fcc6c..2c39378552 100644 --- a/app/src/main/java/com/alphawallet/app/entity/ContractLocator.java +++ b/app/src/main/java/com/alphawallet/app/entity/ContractLocator.java @@ -1,5 +1,7 @@ package com.alphawallet.app.entity; +import static java.util.stream.Collectors.toList; + import android.os.Parcel; import android.os.Parcelable; @@ -9,6 +11,7 @@ import com.alphawallet.token.entity.ContractInfo; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; /** @@ -44,7 +47,7 @@ protected ContractLocator(Parcel in) public boolean equals(Token token) { - return (token != null && address != null && chainId == token.tokenInfo.chainId && address.equalsIgnoreCase(token.getAddress()) ); + return (token != null && address != null && chainId == token.tokenInfo.chainId && address.equalsIgnoreCase(token.getAddress())); } public boolean equals(TokenCardMeta token) @@ -52,13 +55,12 @@ public boolean equals(TokenCardMeta token) return TokensRealmSource.databaseKey(chainId, address).equalsIgnoreCase(token.tokenId); } - /* replace this with a one-liner use of stream when we up our minSdkVersion to 24 */ - public static ContractLocator[] fromAddresses(String[] addresses, long chainID) { - ContractLocator[] retval = new ContractLocator[addresses.length]; - for (int i=0; i new ContractLocator(address, chainID)) + .collect(toList()) + .toArray(new ContractLocator[]{}); } public static List fromContractInfo(ContractInfo cInfo) @@ -76,14 +78,17 @@ public static List fromContractInfo(ContractInfo cInfo) return retVal; } - public static final Creator CREATOR = new Creator() { + public static final Creator CREATOR = new Creator() + { @Override - public ContractLocator createFromParcel(Parcel in) { + public ContractLocator createFromParcel(Parcel in) + { return new ContractLocator(in); } @Override - public ContractLocator[] newArray(int size) { + public ContractLocator[] newArray(int size) + { return new ContractLocator[size]; } }; diff --git a/app/src/main/java/com/alphawallet/app/entity/TransactionDecoder.java b/app/src/main/java/com/alphawallet/app/entity/TransactionDecoder.java index 2a22edb640..c74ab5040a 100644 --- a/app/src/main/java/com/alphawallet/app/entity/TransactionDecoder.java +++ b/app/src/main/java/com/alphawallet/app/entity/TransactionDecoder.java @@ -19,7 +19,7 @@ /** * Created by James on 2/02/2018. - * + *

* TransactionDecoder currently only decode a transaction input in the * string format, which is strictly a string starting with "0x" and * with an even number of hex digits followed. (Probably should be @@ -468,17 +468,13 @@ public Sign.SignatureData getSignatureData(TransactionInput data) public int[] getIndices(TransactionInput data) { - int[] indices = null; - if (data != null && data.arrayValues != null) + if (data == null || data.arrayValues == null) { - indices = new int[data.arrayValues.size()]; - for (int i = 0; i < data.arrayValues.size(); i++) - { - indices[i] = data.arrayValues.get(i).intValue(); - } + return null; } - - return indices; + return data.arrayValues.stream() + .mapToInt(BigInteger::intValue) + .toArray(); } public static String buildMethodId(String methodSignature) diff --git a/app/src/main/java/com/alphawallet/app/entity/tokens/Ticket.java b/app/src/main/java/com/alphawallet/app/entity/tokens/Ticket.java index e909b34178..5be7c14349 100644 --- a/app/src/main/java/com/alphawallet/app/entity/tokens/Ticket.java +++ b/app/src/main/java/com/alphawallet/app/entity/tokens/Ticket.java @@ -41,14 +41,16 @@ public class Ticket extends Token private final List balanceArray; private boolean isMatchedInXML = false; - public Ticket(TokenInfo tokenInfo, List balances, long blancaTime, String networkName, ContractType type) { + public Ticket(TokenInfo tokenInfo, List balances, long blancaTime, String networkName, ContractType type) + { super(tokenInfo, BigDecimal.ZERO, blancaTime, networkName, type); this.balanceArray = balances; balance = balanceArray != null ? BigDecimal.valueOf(balanceArray.size()) : BigDecimal.ZERO; group = TokenGroup.NFT; } - public Ticket(TokenInfo tokenInfo, String balances, long blancaTime, String networkName, ContractType type) { + public Ticket(TokenInfo tokenInfo, String balances, long blancaTime, String networkName, ContractType type) + { super(tokenInfo, BigDecimal.ZERO, blancaTime, networkName, type); this.balanceArray = stringHexToBigIntegerList(balances); balance = BigDecimal.valueOf(balanceArray.size()); @@ -56,17 +58,20 @@ public Ticket(TokenInfo tokenInfo, String balances, long blancaTime, String netw } @Override - public String getStringBalanceForUI(int scale) { + public String getStringBalanceForUI(int scale) + { return String.valueOf(getTokenCount()); } @Override - public boolean hasPositiveBalance() { + public boolean hasPositiveBalance() + { return (getTokenCount() > 0); } @Override - public String getFullBalance() { + public String getFullBalance() + { if (balanceArray == null) return "no tokens"; else return Utils.bigIntListToString(balanceArray, true); } @@ -94,15 +99,14 @@ public List pruneIDList(String idListStr, int quantity) @Override public int getTokenCount() { - int count = 0; - if (balanceArray != null) + if (balanceArray == null) { - for (BigInteger id : balanceArray) - { - if (id.compareTo(BigInteger.ZERO) != 0) count++; - } + return 0; } - return count; + + return (int) balanceArray.stream() + .filter(id -> id.compareTo(BigInteger.ZERO) != 0) + .count(); } @Override @@ -139,6 +143,7 @@ public int getContractType() /** * Convert a list of TicketID's into an Index list corresponding to those indices + * * @param ticketIds * @return */ @@ -179,6 +184,7 @@ public List ticketIdListToIndexList(List ticketIds) /** * Convert a String list of ticket IDs into a list of ticket indices + * * @param userList * @return */ @@ -192,7 +198,7 @@ public List ticketIdStringToIndexList(String userList) for (String id : ids) { //remove whitespace - String trim = id.trim(); + String trim = id.trim(); BigInteger thisId = Numeric.toBigInt(trim); idList.add(thisId); } @@ -228,7 +234,8 @@ private List tokenIdsToTokenIndices(List tokenIds) } } } - catch (Exception e) { + catch (Exception e) + { indexList = null; } @@ -288,7 +295,8 @@ protected org.web3j.abi.datatypes.DynamicArray getDynArray(List indi } @Override - public boolean isToken() { + public boolean isToken() + { return false; } @@ -299,13 +307,18 @@ public boolean hasArrayBalance() } @Override - public List getArrayBalance() { return balanceArray; } + public List getArrayBalance() + { + return balanceArray; + } @Override public List getNonZeroArrayBalance() { List nonZeroValues = new ArrayList<>(); - for (BigInteger value : balanceArray) if (value.compareTo(BigInteger.ZERO) != 0 && !nonZeroValues.contains(value)) nonZeroValues.add(value); + for (BigInteger value : balanceArray) + if (value.compareTo(BigInteger.ZERO) != 0 && !nonZeroValues.contains(value)) + nonZeroValues.add(value); return nonZeroValues; } @@ -316,10 +329,21 @@ public boolean getIsSent(Transaction transaction) } @Override - public boolean isERC875() { return true; } - public boolean isNonFungible() { return true; } + public boolean isERC875() + { + return true; + } + + public boolean isNonFungible() + { + return true; + } + @Override - public boolean hasGroupedTransfer() { return true; } + public boolean hasGroupedTransfer() + { + return true; + } @Override public boolean groupWithToken(TicketRange currentGroupingRange, TicketRangeElement newElement, long currentGroupTime) @@ -333,6 +357,7 @@ public boolean groupWithToken(TicketRange currentGroupingRange, TicketRangeEleme /** * This function should return a String list of IDs suitable for submission to the token's transfer function * For ERC875 it is a list of indices, so convert this list of TokenIDs to indices + * * @param CSVstringIdList * @return */ @@ -346,6 +371,7 @@ public String getTransferListFormat(String CSVstringIdList) /** * This function takes a list of tokenIds, and returns a BigInteger list suitable for this token's transfer function * For ERC875 it is a list of indices, so convert this list of TokenIDs to indices + * * @param tokenIds * @return */ diff --git a/app/src/main/java/com/alphawallet/app/entity/tokens/Token.java b/app/src/main/java/com/alphawallet/app/entity/tokens/Token.java index f0164cde88..8267355bbf 100644 --- a/app/src/main/java/com/alphawallet/app/entity/tokens/Token.java +++ b/app/src/main/java/com/alphawallet/app/entity/tokens/Token.java @@ -267,15 +267,7 @@ private String sanitiseString(String str) } else { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) - { - return Html.fromHtml(str, FROM_HTML_MODE_COMPACT).toString(); - } - else - { - //noinspection deprecation - return Html.fromHtml(str).toString(); - } + return Html.fromHtml(str, FROM_HTML_MODE_COMPACT).toString(); } } diff --git a/app/src/main/java/com/alphawallet/app/service/AlphaWalletService.java b/app/src/main/java/com/alphawallet/app/service/AlphaWalletService.java index 9d6e84cf41..169f017dd8 100644 --- a/app/src/main/java/com/alphawallet/app/service/AlphaWalletService.java +++ b/app/src/main/java/com/alphawallet/app/service/AlphaWalletService.java @@ -52,7 +52,8 @@ public class AlphaWalletService public AlphaWalletService(OkHttpClient httpClient, TransactionRepositoryType transactionRepository, - Gson gson) { + Gson gson) + { this.httpClient = httpClient; this.transactionRepository = transactionRepository; this.gson = gson; @@ -85,6 +86,7 @@ public Observable handleFeemasterImport(String url, Wallet wallet, long /** * Use API to determine tokenscript validity + * * @param tokenScriptFile * @return */ @@ -166,9 +168,7 @@ private Single generateTicketArray(String indices, Ticket ticket) { return Single.fromCallable(() -> { List ticketIndices = Utils.stringIntsToIntegerList(indices); - int[] indicesArray = new int[ticketIndices.size()]; - for (int i = 0; i < ticketIndices.size(); i++) indicesArray[i] = ticketIndices.get(i); - return indicesArray; + return ticketIndices.stream().mapToInt(Integer::intValue).toArray(); }); } @@ -207,7 +207,8 @@ private Single sendFeemasterTransaction( byte[] tradeSig, String contractAddress, List tokenIds - ) { + ) + { return Single.fromCallable(() -> { Integer result = 500; //fail by default try @@ -318,7 +319,7 @@ public Single checkFeemasterService(String url, long chainId, String ad okhttp3.Response response = httpClient.newCall(request).execute(); int resultCode = response.code(); - if ((resultCode/100) == 2) result = true; + if ((resultCode / 100) == 2) result = true; Timber.tag("RESP").d(response.body().string()); } } diff --git a/app/src/main/java/com/alphawallet/app/service/AssetDefinitionService.java b/app/src/main/java/com/alphawallet/app/service/AssetDefinitionService.java index 88e6099de9..b0a2248824 100644 --- a/app/src/main/java/com/alphawallet/app/service/AssetDefinitionService.java +++ b/app/src/main/java/com/alphawallet/app/service/AssetDefinitionService.java @@ -913,16 +913,7 @@ private void onError(Throwable throwable) private TokenDefinition parseFile(InputStream xmlInputStream) throws Exception { - Locale locale; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) - { - locale = context.getResources().getConfiguration().getLocales().get(0); - } - else - { - locale = context.getResources().getConfiguration().locale; - } - + Locale locale = context.getResources().getConfiguration().getLocales().get(0); return new TokenDefinition( xmlInputStream, locale, this); } diff --git a/app/src/main/java/com/alphawallet/app/service/KeyService.java b/app/src/main/java/com/alphawallet/app/service/KeyService.java index 49852f4774..2b6609e8c0 100644 --- a/app/src/main/java/com/alphawallet/app/service/KeyService.java +++ b/app/src/main/java/com/alphawallet/app/service/KeyService.java @@ -90,7 +90,7 @@ public class KeyService implements AuthenticationCallback, PinAuthenticationCall { private static final String TAG = "HDWallet"; private static final int AUTHENTICATION_DURATION_SECONDS = 30; - public static final String FAILED_SIGNATURE = "00000000000000000000000000000000000000000000000000000000000000000"; + public static final String FAILED_SIGNATURE = "00000000000000000000000000000000000000000000000000000000000000000"; private static final String BLOCK_MODE = KeyProperties.BLOCK_MODE_GCM; private static final String PADDING = KeyProperties.ENCRYPTION_PADDING_NONE; @@ -179,9 +179,9 @@ public void createNewHDKey(Activity callingActivity, CreateWalletCallbackInterfa /** * Create and encrypt/store an authentication-locked keystore password for importing a keystore. * Flow for importing a private key is almost identical - * + *

* Flow is as follows: - * + *

* 1. Obtain authentication event - pop up the unlock dialog. * 2. After authentication event, proceed to authenticatePass and switch through to createPassword() * 3. Create a new strong keystore password, store the password. @@ -217,7 +217,7 @@ public void createPrivateKeyPassword(String address, Activity callingActivity, I /** * Encrypt and store mnemonic for HDWallet - * + *

* 1. Check valid seed phrase, generate HDWallet and store the mnemonic without authentication lock * 2. Obtain authentication event. * 3. After authentication pass through to authenticatePass and switch to importHDKey() @@ -248,7 +248,7 @@ public void importHDKey(String seedPhrase, Activity callingActivity, ImportWalle /** * Fetch mnemonic from storage - * + *

* 1. call unpackMnemonic * 2. if authentication required, get authentication event and call unpackMnemonic * 3. return mnemonic to FetchMnemonic callback @@ -322,12 +322,11 @@ public void setRequireAuthentication() /** * Upgrade key security - * + *

* 1. Get authentication, and then execute 'upgradeKey()' from authenticatePass * 2. Upgrade key reads the mnemonic/password, then calls storeEncryptedBytes with authentication. * 3. returns result and flow back to callee via signCallback.CreatedKey * - * * @param wallet * @param callingActivity * @return @@ -348,10 +347,10 @@ public UpgradeKeyResult upgradeKeySecurity(Wallet wallet, Activity callingActivi /** * SignData - * + *

* Flow for this function is by necessity simpler - this function is called from code that doesn't have access to an Activity, so can't create * any signing dialog. The authentication event must be generated prior to entering the signing flow. - * + *

* If HDWallet - decrypt mnemonic, regenerate private key, generate digest, sign digest using Trezor libs. * If Keystore - fetch keystore JSON file, decrypt keystore password, regenerate Web3j Credentials and sign. * @@ -599,6 +598,7 @@ private void importHDKey() /** * Reached after authentication has been provided + * * @return */ private UpgradeKeyResult upgradeKey() @@ -758,15 +758,15 @@ private boolean tryInitStrongBoxKey(KeyGenerator keyGenerator, String keyAddress keyGenerator.init(new KeyGenParameterSpec.Builder( keyAddress, KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) - .setBlockModes(BLOCK_MODE) - .setKeySize(256) - .setUserAuthenticationRequired(useAuthentication) - .setIsStrongBoxBacked(true) - .setInvalidatedByBiometricEnrollment(false) - .setUserAuthenticationValidityDurationSeconds(AUTHENTICATION_DURATION_SECONDS) - .setRandomizedEncryptionRequired(true) - .setEncryptionPaddings(PADDING) - .build()); + .setBlockModes(BLOCK_MODE) + .setKeySize(256) + .setUserAuthenticationRequired(useAuthentication) + .setIsStrongBoxBacked(true) + .setInvalidatedByBiometricEnrollment(false) + .setUserAuthenticationValidityDurationSeconds(AUTHENTICATION_DURATION_SECONDS) + .setRandomizedEncryptionRequired(true) + .setEncryptionPaddings(PADDING) + .build()); keyGenerator.generateKey(); } @@ -786,33 +786,17 @@ private boolean tryInitTEEKey(KeyGenerator keyGenerator, String keyAddress, bool { try { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) - { - keyGenerator.init(new KeyGenParameterSpec.Builder( - keyAddress, - KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) - .setBlockModes(BLOCK_MODE) - .setKeySize(256) - .setUserAuthenticationRequired(useAuthentication) - .setInvalidatedByBiometricEnrollment(false) - .setUserAuthenticationValidityDurationSeconds(AUTHENTICATION_DURATION_SECONDS) - .setRandomizedEncryptionRequired(true) - .setEncryptionPaddings(PADDING) - .build()); - } - else - { - keyGenerator.init(new KeyGenParameterSpec.Builder( - keyAddress, - KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) - .setBlockModes(BLOCK_MODE) - .setKeySize(256) - .setUserAuthenticationRequired(useAuthentication) - .setUserAuthenticationValidityDurationSeconds(AUTHENTICATION_DURATION_SECONDS) - .setRandomizedEncryptionRequired(true) - .setEncryptionPaddings(PADDING) - .build()); - } + keyGenerator.init(new KeyGenParameterSpec.Builder( + keyAddress, + KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) + .setBlockModes(BLOCK_MODE) + .setKeySize(256) + .setUserAuthenticationRequired(useAuthentication) + .setInvalidatedByBiometricEnrollment(false) + .setUserAuthenticationValidityDurationSeconds(AUTHENTICATION_DURATION_SECONDS) + .setRandomizedEncryptionRequired(true) + .setEncryptionPaddings(PADDING) + .build()); } catch (IllegalStateException | InvalidAlgorithmParameterException e) { @@ -1262,11 +1246,13 @@ private boolean writeBytesToFile(String path, byte[] data) /** * Delete all traces of the key in Android keystore, encrypted bytes and iv file in private data area + * * @param keyAddress */ synchronized void deleteKey(String keyAddress) { - try { + try + { KeyStore keyStore = KeyStore.getInstance(ANDROID_KEY_STORE); keyStore.load(null); String matchingAddr = findMatchingAddrInKeyStore(keyAddress); @@ -1276,7 +1262,9 @@ synchronized void deleteKey(String keyAddress) if (encryptedKeyBytes.exists()) encryptedKeyBytes.delete(); if (encryptedBytesFileIV.exists()) encryptedBytesFileIV.delete(); deleteAccount(matchingAddr); - } catch (Exception e) { + } + catch (Exception e) + { e.printStackTrace(); } } @@ -1284,21 +1272,21 @@ synchronized void deleteKey(String keyAddress) public void deleteAccount(String address) throws Exception { String cleanedAddr = Numeric.cleanHexPrefix(address).toLowerCase(); - deleteAccountFiles(cleanedAddr); + deleteAccountFiles(cleanedAddr); - //Now delete database files (ie tokens, transactions and Tokenscript data for account) - File[] contents = context.getFilesDir().listFiles(); - if (contents != null) + //Now delete database files (ie tokens, transactions and Tokenscript data for account) + File[] contents = context.getFilesDir().listFiles(); + if (contents != null) + { + for (File f : contents) { - for (File f : contents) + String fileName = f.getName().toLowerCase(); + if (fileName.contains(cleanedAddr.toLowerCase())) { - String fileName = f.getName().toLowerCase(); - if (fileName.contains(cleanedAddr.toLowerCase())) - { - deleteRecursive(f); - } + deleteRecursive(f); } } + } } private void deleteAccountFiles(String address) throws Exception @@ -1382,7 +1370,8 @@ private void vibrate() Vibrator vb = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE); if (vb != null && vb.hasVibrator()) { - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) + { VibrationEffect vibe = VibrationEffect.createOneShot(200, DEFAULT_AMPLITUDE); vb.vibrate(vibe); } @@ -1403,7 +1392,7 @@ public boolean hasKeystore(String walletAddress) String matchingAddr = findMatchingAddrInKeyStore(walletAddress); return keyStore.containsAlias(matchingAddr); } - catch (KeyStoreException|NoSuchAlgorithmException|CertificateException|IOException e) + catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException e) { Timber.e(e); } diff --git a/app/src/main/java/com/alphawallet/app/ui/BaseFragment.java b/app/src/main/java/com/alphawallet/app/ui/BaseFragment.java index 0cdee524b1..116500fdf5 100644 --- a/app/src/main/java/com/alphawallet/app/ui/BaseFragment.java +++ b/app/src/main/java/com/alphawallet/app/ui/BaseFragment.java @@ -15,14 +15,14 @@ import org.jetbrains.annotations.NotNull; +import java.util.Arrays; import java.util.List; import dagger.hilt.android.AndroidEntryPoint; @AndroidEntryPoint public class BaseFragment extends Fragment implements Toolbar.OnMenuItemClickListener, - BackupTokenCallback -{ + BackupTokenCallback { private Toolbar toolbar; private TextView toolbarTitle; @@ -30,6 +30,7 @@ private void initToolbar(View view) { toolbar = view.findViewById(R.id.toolbar); toolbarTitle = toolbar.findViewById(R.id.toolbar_title); } + protected void toolbar(View view) { if (view != null) initToolbar(view); } @@ -85,32 +86,70 @@ public boolean onMenuItemClick(MenuItem menuItem) { return false; } - public void comeIntoFocus() - { + public void comeIntoFocus() { // } - public void leaveFocus() - { + public void leaveFocus() { // } - public void softKeyboardVisible() { } - public void softKeyboardGone() { } - public void onItemClick(String url) { } - public void signalUpdate(int updateVersion) { } - public void backupSeedSuccess(boolean hasNoLock) { } - public void storeWalletBackupTime(String backedUpKey) { } - public void resetTokens() { } - public void resetTransactions() { } - public void gotCameraAccess(@NotNull String[] permissions, int[] grantResults) { } - public void gotGeoAccess(@NotNull String[] permissions, int[] grantResults) { } - public void gotFileAccess(@NotNull String[] permissions, int[] grantResults) { } - public void handleQRCode(int resultCode, Intent data, FragmentMessenger messenger) { } - public void pinAuthorisation(boolean gotAuth) { } - public void switchNetworkAndLoadUrl(long chainId, String url) { } - public void scrollToTop() { } - public void addedToken(List tokenContracts) { } - public void setImportFilename(String fName) { } - public void backPressed() { } + protected boolean hasPermissionGranted(@NotNull String[] permissions, int[] grantResults, String permission) { + int index = Arrays.asList(permissions).indexOf(permission); + return index != -1 && grantResults[index] != -1; + } + + public void softKeyboardVisible() { + } + + public void softKeyboardGone() { + } + + public void onItemClick(String url) { + } + + public void signalUpdate(int updateVersion) { + } + + public void backupSeedSuccess(boolean hasNoLock) { + } + + public void storeWalletBackupTime(String backedUpKey) { + } + + public void resetTokens() { + } + + public void resetTransactions() { + } + + public void gotCameraAccess(@NotNull String[] permissions, int[] grantResults) { + } + + public void gotGeoAccess(@NotNull String[] permissions, int[] grantResults) { + } + + public void gotFileAccess(@NotNull String[] permissions, int[] grantResults) { + } + + public void handleQRCode(int resultCode, Intent data, FragmentMessenger messenger) { + } + + public void pinAuthorisation(boolean gotAuth) { + } + + public void switchNetworkAndLoadUrl(long chainId, String url) { + } + + public void scrollToTop() { + } + + public void addedToken(List tokenContracts) { + } + + public void setImportFilename(String fName) { + } + + public void backPressed() { + } } diff --git a/app/src/main/java/com/alphawallet/app/ui/DappBrowserFragment.java b/app/src/main/java/com/alphawallet/app/ui/DappBrowserFragment.java index df3471244d..3018a51a23 100644 --- a/app/src/main/java/com/alphawallet/app/ui/DappBrowserFragment.java +++ b/app/src/main/java/com/alphawallet/app/ui/DappBrowserFragment.java @@ -140,7 +140,9 @@ import java.math.BigDecimal; import java.math.BigInteger; import java.security.SignatureException; +import java.util.Arrays; import java.util.concurrent.TimeUnit; +import java.util.stream.IntStream; import dagger.hilt.android.AndroidEntryPoint; import io.reactivex.Observable; @@ -156,7 +158,8 @@ public class DappBrowserFragment extends BaseFragment implements OnSignTransactionListener, OnSignPersonalMessageListener, OnSignTypedMessageListener, OnSignMessageListener, OnEthCallListener, OnWalletAddEthereumChainObjectListener, OnWalletActionListener, URLLoadInterface, ItemClickListener, OnDappHomeNavClickListener, DappBrowserSwipeInterface, - SignAuthenticationCallback, ActionSheetCallback, TestNetDialog.TestNetDialogCallback { + SignAuthenticationCallback, ActionSheetCallback, TestNetDialog.TestNetDialogCallback +{ public static final String SEARCH = "SEARCH"; public static final String PERSONAL_MESSAGE_PREFIX = "\u0019Ethereum Signed Message:\n"; public static final String CURRENT_FRAGMENT = "currentFragment"; @@ -182,7 +185,8 @@ public class DappBrowserFragment extends BaseFragment implements OnSignTransacti private final Handler handler = new Handler(Looper.getMainLooper()); private ValueCallback uploadMessage; ActivityResultLauncher getContent = registerForActivityResult(new ActivityResultContracts.GetContent(), - new ActivityResultCallback() { + new ActivityResultCallback() + { @Override public void onActivityResult(Uri uri) { @@ -645,7 +649,8 @@ private void setupAddressBar() return false; }); - urlTv.addTextChangedListener(new TextWatcher() { + urlTv.addTextChangedListener(new TextWatcher() + { @Override public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { @@ -707,8 +712,8 @@ private void openURLInputView() expandCollapseView(layoutNavigation, false); disposable = Observable.zip( - Observable.interval(600, TimeUnit.MILLISECONDS).take(1), - Observable.fromArray(clear), (interval, item) -> item) + Observable.interval(600, TimeUnit.MILLISECONDS).take(1), + Observable.fromArray(clear), (interval, item) -> item) .observeOn(AndroidSchedulers.mainThread()) .subscribeOn(AndroidSchedulers.mainThread()) .subscribe(this::postBeginSearchSession); @@ -738,7 +743,8 @@ private synchronized void expandCollapseView(@NotNull View view, boolean expandV { int finalWidth = view.getWidth(); ValueAnimator valueAnimator = slideAnimator(finalWidth, 0, view); - valueAnimator.addListener(new Animator.AnimatorListener() { + valueAnimator.addListener(new Animator.AnimatorListener() + { @Override public void onAnimationStart(Animator animator) { @@ -997,7 +1003,8 @@ private void setupWeb3() web3.setRpcUrl(viewModel.getNetworkNodeRPC(activeNetwork.chainId)); web3.setWalletAddress(new Address(wallet.address)); - web3.setWebChromeClient(new WebChromeClient() { + web3.setWebChromeClient(new WebChromeClient() + { @Override public void onProgressChanged(WebView webview, int newProgress) { @@ -1067,7 +1074,8 @@ public boolean onShowFileChooser(WebView webView, ValueCallback filePathC } }); - web3.setWebViewClient(new WebViewClient() { + web3.setWebViewClient(new WebViewClient() + { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { @@ -1207,13 +1215,13 @@ public void onSignTypedMessage(@NotNull EthereumTypedMessage message) public void onEthCall(Web3Call call) { Single.fromCallable(() -> { - //let's make the call - Web3j web3j = TokenRepository.getWeb3jService(activeNetwork.chainId); - //construct call - org.web3j.protocol.core.methods.request.Transaction transaction - = createFunctionCallTransaction(wallet.address, null, null, call.gasLimit, call.to.toString(), call.value, call.payload); - return web3j.ethCall(transaction, call.blockParam).send(); - }).map(EthCall::getValue) + //let's make the call + Web3j web3j = TokenRepository.getWeb3jService(activeNetwork.chainId); + //construct call + org.web3j.protocol.core.methods.request.Transaction transaction + = createFunctionCallTransaction(wallet.address, null, null, call.gasLimit, call.to.toString(), call.value, call.payload); + return web3j.ethCall(transaction, call.blockParam).send(); + }).map(EthCall::getValue) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(result -> web3.onCallFunctionSuccessful(call.leafPosition, result), @@ -1333,7 +1341,8 @@ private void showChainChangeDialog(long callbackId, NetworkInfo newNetwork) private void handleSignMessage(Signable message) { - dAppFunction = new DAppFunction() { + dAppFunction = new DAppFunction() + { @Override public void DAppError(Throwable error, Signable message) { @@ -1941,32 +1950,22 @@ private void requestCameraPermission(@NotNull PermissionRequest request) @Override public void gotCameraAccess(@NotNull String[] permissions, int[] grantResults) { - boolean cameraAccess = false; - for (int i = 0; i < permissions.length; i++) + boolean cameraAccess = hasPermissionGranted(permissions, grantResults, Manifest.permission.CAMERA); + if (cameraAccess) { - if (permissions[i].equals(Manifest.permission.CAMERA) && grantResults[i] != -1) - { - cameraAccess = true; - if (requestCallback != null) - requestCallback.grant(requestCallback.getResources()); //now we can grant permission - } + if (requestCallback != null) + requestCallback.grant(requestCallback.getResources()); } - if (!cameraAccess) + else + { Toast.makeText(getContext(), "Permission not given", Toast.LENGTH_SHORT).show(); + } } @Override public void gotGeoAccess(@NotNull String[] permissions, int[] grantResults) { - boolean geoAccess = false; - for (int i = 0; i < permissions.length; i++) - { - if (permissions[i].equals(Manifest.permission.ACCESS_FINE_LOCATION) && grantResults[i] != -1) - { - geoAccess = true; - break; - } - } + boolean geoAccess = hasPermissionGranted(permissions, grantResults, Manifest.permission.ACCESS_FINE_LOCATION); if (!geoAccess) Toast.makeText(getContext(), "Permission not given", Toast.LENGTH_SHORT).show(); if (geoCallback != null && geoOrigin != null) @@ -1976,16 +1975,7 @@ public void gotGeoAccess(@NotNull String[] permissions, int[] grantResults) @Override public void gotFileAccess(@NotNull String[] permissions, int[] grantResults) { - boolean fileAccess = false; - for (int i = 0; i < permissions.length; i++) - { - if (permissions[i].equals(Manifest.permission.READ_EXTERNAL_STORAGE) && grantResults[i] != -1) - { - fileAccess = true; - break; - } - } - + boolean fileAccess = hasPermissionGranted(permissions, grantResults, Manifest.permission.READ_EXTERNAL_STORAGE); if (fileAccess) requestUpload(); } @@ -2167,7 +2157,8 @@ public void getAuthorisation(SignAuthenticationCallback callback) @Override public void sendTransaction(Web3Transaction finalTx) { - final SendTransactionInterface callback = new SendTransactionInterface() { + final SendTransactionInterface callback = new SendTransactionInterface() + { @Override public void transactionSuccess(Web3Transaction web3Tx, String hashData) { diff --git a/app/src/main/java/com/alphawallet/app/ui/NewSettingsFragment.java b/app/src/main/java/com/alphawallet/app/ui/NewSettingsFragment.java index 727bec639c..567de04798 100644 --- a/app/src/main/java/com/alphawallet/app/ui/NewSettingsFragment.java +++ b/app/src/main/java/com/alphawallet/app/ui/NewSettingsFragment.java @@ -16,7 +16,6 @@ import static com.alphawallet.token.tools.TokenDefinition.TOKENSCRIPT_CURRENT_SCHEMA; import android.content.Intent; -import android.os.Build; import android.os.Bundle; import android.text.TextUtils; import android.view.LayoutInflater; @@ -176,21 +175,7 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c private void initNotificationView(View view) { notificationView = view.findViewById(R.id.notification); - if (android.os.Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) - { - notificationView.setTitle(getContext().getString(R.string.title_version_support_warning)); - notificationView.setMessage(getContext().getString(R.string.message_version_support_warning)); - notificationView.setPrimaryButtonText(getContext().getString(R.string.hide_notification)); - notificationView.setPrimaryButtonListener(() -> - { - notificationView.setVisibility(View.GONE); - viewModel.setMarshMallowWarning(true); - }); - } - else - { - notificationView.setVisibility(View.GONE); - } + notificationView.setVisibility(View.GONE); } @Override diff --git a/app/src/main/java/com/alphawallet/app/ui/QRScanning/QRScanner.java b/app/src/main/java/com/alphawallet/app/ui/QRScanning/QRScanner.java index 259e2cc20d..72b9b4174e 100644 --- a/app/src/main/java/com/alphawallet/app/ui/QRScanning/QRScanner.java +++ b/app/src/main/java/com/alphawallet/app/ui/QRScanning/QRScanner.java @@ -1,5 +1,10 @@ package com.alphawallet.app.ui.QRScanning; +import static android.Manifest.permission.READ_EXTERNAL_STORAGE; +import static android.os.Build.VERSION.SDK_INT; +import static androidx.core.view.WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE; +import static com.alphawallet.app.repository.SharedPreferenceRepository.FULL_SCREEN_STATE; + import android.Manifest; import android.app.Activity; import android.content.Intent; @@ -14,7 +19,6 @@ import android.text.TextUtils; import android.view.KeyEvent; import android.widget.TextView; -import android.widget.Toast; import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.contract.ActivityResultContracts; @@ -55,11 +59,6 @@ import io.reactivex.schedulers.Schedulers; import timber.log.Timber; -import static android.Manifest.permission.READ_EXTERNAL_STORAGE; -import static android.os.Build.VERSION.SDK_INT; -import static androidx.core.view.WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE; -import static com.alphawallet.app.repository.SharedPreferenceRepository.FULL_SCREEN_STATE; - /** * Created by JB on 12/09/2021. */ @@ -85,12 +84,6 @@ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.N) - { - Toast.makeText(this, R.string.toast_qr_scanning_requires_api_24, Toast.LENGTH_SHORT).show(); - finish(); - } - hideSystemUI(); int rc = ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA); diff --git a/app/src/main/java/com/alphawallet/app/ui/widget/adapter/ActivityAdapter.java b/app/src/main/java/com/alphawallet/app/ui/widget/adapter/ActivityAdapter.java index 919e7da648..5cd50c5751 100644 --- a/app/src/main/java/com/alphawallet/app/ui/widget/adapter/ActivityAdapter.java +++ b/app/src/main/java/com/alphawallet/app/ui/widget/adapter/ActivityAdapter.java @@ -42,12 +42,14 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.stream.IntStream; import timber.log.Timber; public class ActivityAdapter extends RecyclerView.Adapter> implements AdapterCallback { - private final ActivitySortedList> items = new ActivitySortedList<>(SortedItem.class, new ActivitySortedList.Callback>() { + private final ActivitySortedList> items = new ActivitySortedList<>(SortedItem.class, new ActivitySortedList.Callback>() + { @Override public int compare(SortedItem left, SortedItem right) { @@ -55,32 +57,38 @@ public int compare(SortedItem left, SortedItem right) } @Override - public boolean areContentsTheSame(SortedItem oldItem, SortedItem newItem) { + public boolean areContentsTheSame(SortedItem oldItem, SortedItem newItem) + { return oldItem.areContentsTheSame(newItem); } @Override - public boolean areItemsTheSame(SortedItem left, SortedItem right) { + public boolean areItemsTheSame(SortedItem left, SortedItem right) + { return left.areItemsTheSame(right); } @Override - public void onChanged(int position, int count) { + public void onChanged(int position, int count) + { notifyItemRangeChanged(position, count); } @Override - public void onInserted(int position, int count) { + public void onInserted(int position, int count) + { notifyItemRangeInserted(position, count); } @Override - public void onRemoved(int position, int count) { + public void onRemoved(int position, int count) + { notifyItemRangeRemoved(position, count); } @Override - public void onMoved(int fromPosition, int toPosition) { + public void onMoved(int fromPosition, int toPosition) + { notifyItemMoved(fromPosition, toPosition); } }); @@ -97,7 +105,8 @@ public void onMoved(int fromPosition, int toPosition) { private boolean pendingReset = false; public ActivityAdapter(TokensService service, FetchTransactionsInteract fetchTransactionsInteract, - AssetDefinitionService svs, ActivityDataInteract dataInteract) { + AssetDefinitionService svs, ActivityDataInteract dataInteract) + { this.fetchTransactionsInteract = fetchTransactionsInteract; this.dataInteract = dataInteract; this.assetService = svs; @@ -113,8 +122,10 @@ public ActivityAdapter(TokensService service, FetchTransactionsInteract fetchTra } @Override - public BinderViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - switch (viewType) { + public BinderViewHolder onCreateViewHolder(ViewGroup parent, int viewType) + { + switch (viewType) + { case TransactionHolder.VIEW_TYPE: return new TransactionHolder(parent, tokensService, fetchTransactionsInteract, assetService); @@ -153,7 +164,7 @@ else if (position > lastItemPos && dataInteract != null && System.currentTimeMil public void onRViewRecycled(RecyclerView.ViewHolder holder) { - onViewRecycled((BinderViewHolder)(holder)); + onViewRecycled((BinderViewHolder) (holder)); } @Override @@ -185,16 +196,19 @@ private void fetchData(long earliestDate) }; @Override - public int getItemCount() { + public int getItemCount() + { return items.size(); } @Override - public int getItemViewType(int position) { + public int getItemViewType(int position) + { return items.get(position).viewType; } - public void setDefaultWallet(Wallet wallet) { + public void setDefaultWallet(Wallet wallet) + { this.wallet = wallet; notifyDataSetChanged(); } @@ -215,11 +229,11 @@ else if (obj instanceof EventSortedItem) } else if (obj instanceof DateSortedItem) { - return ((DateSortedItem)obj).getUID(); + return ((DateSortedItem) obj).getUID(); } else if (obj instanceof TransferSortedItem) { - return ((TransferSortedItem)obj).getUID(); + return ((TransferSortedItem) obj).getUID(); } else { @@ -231,7 +245,7 @@ else if (obj instanceof TransferSortedItem) public void updateActivityItems(ActivityMeta[] activityItems) { - if (activityItems.length == 0) return ; + if (activityItems.length == 0) return; items.beginBatchedUpdates(); if (itemLimit != 0) @@ -243,17 +257,17 @@ public void updateActivityItems(ActivityMeta[] activityItems) { if (item instanceof TransactionMeta) { - TransactionSortedItem sortedItem = new TransactionSortedItem(TransactionHolder.VIEW_TYPE, (TransactionMeta)item, TimestampSortedItem.DESC); + TransactionSortedItem sortedItem = new TransactionSortedItem(TransactionHolder.VIEW_TYPE, (TransactionMeta) item, TimestampSortedItem.DESC); items.addTransaction(sortedItem); //event has higher UI priority than an event, don't overwrite } else if (item instanceof EventMeta) { - EventSortedItem sortedItem = new EventSortedItem(EventHolder.VIEW_TYPE, (EventMeta)item, TimestampSortedItem.DESC); + EventSortedItem sortedItem = new EventSortedItem(EventHolder.VIEW_TYPE, (EventMeta) item, TimestampSortedItem.DESC); items.add(sortedItem); } else if (item instanceof TokenTransferData) { - TransferSortedItem sortedItem = new TransferSortedItem(TransferHolder.VIEW_TYPE, (TokenTransferData)item, TimestampSortedItem.DESC); + TransferSortedItem sortedItem = new TransferSortedItem(TransferHolder.VIEW_TYPE, (TokenTransferData) item, TimestampSortedItem.DESC); items.add(sortedItem); } items.add(DateSortedItem.round(item.getTimeStampSeconds())); @@ -264,7 +278,8 @@ else if (item instanceof TokenTransferData) items.endBatchedUpdates(); } - public void clear() { + public void clear() + { items.clear(); notifyDataSetChanged(); } @@ -289,9 +304,9 @@ private void applyItemLimit() } } - if (items.get(items.size()-1) instanceof DateSortedItem) + if (items.get(items.size() - 1) instanceof DateSortedItem) { - removalObjects.add(items.get(items.size()-1)); + removalObjects.add(items.get(items.size() - 1)); } for (SortedItem sortedItem : removalObjects) @@ -306,9 +321,9 @@ public void updateItems(List tokenContracts) for (int i = 0; i < items.size(); i++) { if (items.get(i).viewType == TransactionHolder.VIEW_TYPE - && items.get(i).value instanceof TransactionMeta) + && items.get(i).value instanceof TransactionMeta) { - TransactionMeta tm = (TransactionMeta)items.get(i).value; + TransactionMeta tm = (TransactionMeta) items.get(i).value; if (tm.contractAddress != null && hasMatchingContract(tokenContracts, tm.contractAddress.toLowerCase())) { notifyItemChanged(i); @@ -352,26 +367,21 @@ public void resetRequired() public boolean isEmpty() { - for (int i = 0; i < items.size(); i++) - { - Object item = items.get(i).value; - if (item instanceof ActivityMeta) - { - return false; - } - } - - return true; + return IntStream.range(0, items.size()) + .noneMatch(i -> items.get(i).value instanceof ActivityMeta); } - private static class LabelHolder extends BinderViewHolder { + private static class LabelHolder extends BinderViewHolder + { - public LabelHolder(int resId, ViewGroup parent) { + public LabelHolder(int resId, ViewGroup parent) + { super(resId, parent); } @Override - public void bind(@Nullable Date data, @NonNull Bundle addition) { + public void bind(@Nullable Date data, @NonNull Bundle addition) + { } } @@ -387,12 +397,13 @@ public void addTransaction(T item) { if (item instanceof TransactionSortedItem) { - TransactionSortedItem txSortedItem = (TransactionSortedItem)item; + TransactionSortedItem txSortedItem = (TransactionSortedItem) item; int index = items.indexOf(txSortedItem); if (index >= 0 && items.get(index).value instanceof EventMeta) { - EventMeta em = (EventMeta)items.get(index).value; - if (!em.hash.equals(txSortedItem.value.hash)) add(item); //don't replace matching Event + EventMeta em = (EventMeta) items.get(index).value; + if (!em.hash.equals(txSortedItem.value.hash)) + add(item); //don't replace matching Event } else { @@ -411,7 +422,7 @@ public void onDestroy(RecyclerView recyclerView) //ensure all holders have their realm listeners cleaned up for (int childCount = recyclerView.getChildCount(), i = 0; i < childCount; ++i) { - ((BinderViewHolder)recyclerView.getChildViewHolder(recyclerView.getChildAt(i))).onDestroyView(); + ((BinderViewHolder) recyclerView.getChildViewHolder(recyclerView.getChildAt(i))).onDestroyView(); } } } diff --git a/app/src/main/java/com/alphawallet/app/ui/widget/adapter/NodeStatusAdapter.java b/app/src/main/java/com/alphawallet/app/ui/widget/adapter/NodeStatusAdapter.java index 59efcfd160..d02b2f47cc 100644 --- a/app/src/main/java/com/alphawallet/app/ui/widget/adapter/NodeStatusAdapter.java +++ b/app/src/main/java/com/alphawallet/app/ui/widget/adapter/NodeStatusAdapter.java @@ -22,6 +22,7 @@ import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.IntStream; import io.reactivex.Single; import io.reactivex.android.schedulers.AndroidSchedulers; @@ -117,15 +118,9 @@ private NodeStatus fetchNodeStatus(long chainId) private void updateStatus(long chainId, NodeStatus status) { statusMap.put(chainId, status); - int position = 0; - for (int i=0; i networkList.get(i).chainId == chainId) + .findFirst().orElse(0); notifyItemChanged(position); Timber.d("updateStatus: chain: %s-%s: %s", chainId, EthereumNetworkBase.getShortChainName(chainId),status); } diff --git a/app/src/main/java/com/alphawallet/app/util/LocaleUtils.java b/app/src/main/java/com/alphawallet/app/util/LocaleUtils.java index 63fc3551b1..c57014c8c3 100644 --- a/app/src/main/java/com/alphawallet/app/util/LocaleUtils.java +++ b/app/src/main/java/com/alphawallet/app/util/LocaleUtils.java @@ -6,7 +6,6 @@ import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; -import android.os.Build; import android.os.LocaleList; import android.text.TextUtils; import android.text.format.DateUtils; @@ -115,40 +114,16 @@ private static String getActiveLocaleName(Context context) * @return String as a Language Locale */ public static String getDeviceSettingsLocale(Context context) { - String locale; - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) - { - locale = context.getResources().getConfiguration().getLocales().get(0).getLanguage(); - } - else - { - locale = context.getResources().getConfiguration().locale.getLanguage(); - } - return locale; + return context.getResources().getConfiguration().getLocales().get(0).getLanguage(); } private static String getCurrentLanguage() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) - { - return LocaleList.getDefault().get(0).getLanguage(); - } - else - { - return Locale.getDefault().getLanguage(); - } + return LocaleList.getDefault().get(0).getLanguage(); } private static String getCurrentCountry() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) - { - return LocaleList.getDefault().get(0).getCountry(); - } - else - { - return Locale.getDefault().getCountry(); - } + return LocaleList.getDefault().get(0).getCountry(); } } diff --git a/app/src/main/java/com/alphawallet/app/viewmodel/HomeViewModel.java b/app/src/main/java/com/alphawallet/app/viewmodel/HomeViewModel.java index aa9e56c8c1..4bf5d2f2bf 100644 --- a/app/src/main/java/com/alphawallet/app/viewmodel/HomeViewModel.java +++ b/app/src/main/java/com/alphawallet/app/viewmodel/HomeViewModel.java @@ -12,7 +12,6 @@ import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.net.Uri; -import android.os.Build; import android.os.Environment; import android.os.Handler; import android.os.IBinder; @@ -58,10 +57,10 @@ import com.alphawallet.app.ui.HomeActivity; import com.alphawallet.app.ui.ImportWalletActivity; import com.alphawallet.app.ui.SendActivity; -import com.alphawallet.app.util.ens.AWEnsResolver; import com.alphawallet.app.util.QRParser; import com.alphawallet.app.util.RateApp; import com.alphawallet.app.util.Utils; +import com.alphawallet.app.util.ens.AWEnsResolver; import com.alphawallet.app.walletconnect.WCClient; import com.alphawallet.app.walletconnect.entity.WCUtils; import com.alphawallet.app.widget.EmailPromptView; @@ -587,15 +586,7 @@ public void tryToShowWhatsNewDialog(Context context) { } private TokenDefinition parseFile(Context ctx, InputStream xmlInputStream) throws Exception { - Locale locale; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - locale = ctx.getResources().getConfiguration().getLocales().get(0); - } - else - { - locale = ctx.getResources().getConfiguration().locale; - } - + Locale locale = ctx.getResources().getConfiguration().getLocales().get(0); return new TokenDefinition( xmlInputStream, locale, null); } diff --git a/app/src/main/java/com/alphawallet/app/web3/Web3View.java b/app/src/main/java/com/alphawallet/app/web3/Web3View.java index 91f774f712..8fa6a1d915 100644 --- a/app/src/main/java/com/alphawallet/app/web3/Web3View.java +++ b/app/src/main/java/com/alphawallet/app/web3/Web3View.java @@ -1,13 +1,8 @@ package com.alphawallet.app.web3; -import static androidx.webkit.WebSettingsCompat.FORCE_DARK_OFF; -import static androidx.webkit.WebSettingsCompat.FORCE_DARK_ON; - import android.annotation.SuppressLint; import android.content.Context; -import android.content.res.Configuration; import android.graphics.Bitmap; -import android.os.Build; import android.util.AttributeSet; import android.webkit.WebChromeClient; import android.webkit.WebResourceError; @@ -18,9 +13,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.annotation.RequiresApi; -import androidx.webkit.WebSettingsCompat; -import androidx.webkit.WebViewFeature; import com.alphawallet.app.BuildConfig; import com.alphawallet.app.entity.URLLoadInterface; @@ -377,15 +369,6 @@ else if (!loadingError && loadInterface != null) loadingError = false; } - @Override - public boolean shouldOverrideUrlLoading(WebView view, String url) - { - redirect = true; - - return externalClient.shouldOverrideUrlLoading(view, url) - || internalClient.shouldOverrideUrlLoading(view, url); - } - @Override public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) { @@ -394,7 +377,6 @@ public void onReceivedError(WebView view, WebResourceRequest request, WebResourc externalClient.onReceivedError(view, request, error); } - @RequiresApi(api = Build.VERSION_CODES.N) @Override public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { diff --git a/app/src/test/java/com/alphawallet/app/entity/ContractLocatorTest.java b/app/src/test/java/com/alphawallet/app/entity/ContractLocatorTest.java new file mode 100644 index 0000000000..e2d11dc23d --- /dev/null +++ b/app/src/test/java/com/alphawallet/app/entity/ContractLocatorTest.java @@ -0,0 +1,23 @@ +package com.alphawallet.app.entity; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.IsEqual.equalTo; + +import org.junit.Test; + +public class ContractLocatorTest +{ + @Test + public void should_from_addresses() + { + String[] addresses = {"add1", "add2"}; + + ContractLocator[] contractLocators = ContractLocator.fromAddresses(addresses, 1L); + + assertThat(contractLocators.length, equalTo(2)); + assertThat(contractLocators[0].address, equalTo("add1")); + assertThat(contractLocators[0].chainId, equalTo(1L)); + assertThat(contractLocators[1].address, equalTo("add2")); + assertThat(contractLocators[1].chainId, equalTo(1L)); + } +} \ No newline at end of file diff --git a/app/src/test/java/com/alphawallet/app/entity/tokens/TicketTest.java b/app/src/test/java/com/alphawallet/app/entity/tokens/TicketTest.java new file mode 100644 index 0000000000..6722b03ef7 --- /dev/null +++ b/app/src/test/java/com/alphawallet/app/entity/tokens/TicketTest.java @@ -0,0 +1,23 @@ +package com.alphawallet.app.entity.tokens; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.IsEqual.equalTo; + +import org.junit.Test; + +import java.math.BigInteger; +import java.util.Arrays; +import java.util.List; + +public class TicketTest +{ + @Test + public void should_get_token_count() + { + Ticket ticket = new Ticket(null, Arrays.asList(BigInteger.valueOf(2), BigInteger.ZERO, BigInteger.ONE), 0L, null, null); + assertThat(ticket.getTokenCount(), equalTo(2)); + + ticket = new Ticket(null, (List) null, 0L, null, null); + assertThat(ticket.getTokenCount(), equalTo(0)); + } +} diff --git a/app/src/test/java/com/alphawallet/app/ui/widget/adapter/ActivityAdapterTest.java b/app/src/test/java/com/alphawallet/app/ui/widget/adapter/ActivityAdapterTest.java new file mode 100644 index 0000000000..1139a04e9f --- /dev/null +++ b/app/src/test/java/com/alphawallet/app/ui/widget/adapter/ActivityAdapterTest.java @@ -0,0 +1,34 @@ +package com.alphawallet.app.ui.widget.adapter; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.IsEqual.equalTo; + +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import com.alphawallet.app.entity.ActivityMeta; +import com.alphawallet.app.entity.EventMeta; +import com.alphawallet.shadows.ShadowAnalyticsService; +import com.alphawallet.shadows.ShadowApp; +import com.alphawallet.shadows.ShadowKeyProviderFactory; +import com.alphawallet.shadows.ShadowKeyService; +import com.alphawallet.shadows.ShadowRealmManager; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.annotation.Config; +import org.robolectric.shadows.ShadowPackageManager; + +@RunWith(AndroidJUnit4.class) +@Config(shadows = {ShadowApp.class, ShadowKeyProviderFactory.class, ShadowRealmManager.class, ShadowKeyService.class, ShadowAnalyticsService.class, ShadowPackageManager.class}) +public class ActivityAdapterTest +{ + @Test + public void test_isEmpty() + { + ActivityAdapter activityAdapter = new ActivityAdapter(null, null, null); + activityAdapter.updateActivityItems(new ActivityMeta[]{}); + assertThat(activityAdapter.isEmpty(), equalTo(true)); + activityAdapter.updateActivityItems(new ActivityMeta[]{ new EventMeta("", "", "", System.currentTimeMillis(), 1L)}); + assertThat(activityAdapter.isEmpty(), equalTo(false)); + } +} diff --git a/lib/build.gradle b/lib/build.gradle index 602fe07e6b..3d69926421 100644 --- a/lib/build.gradle +++ b/lib/build.gradle @@ -11,10 +11,6 @@ apply plugin: 'com.github.johnrengelman.shadow' apply plugin: 'java-library' dependencies { - implementation files('..\\app\\libs\\abi-4.8.8-android.jar') - implementation files('..\\app\\libs\\core-4.8.8-android.jar') - implementation files('..\\app\\libs\\crypto-4.8.8-android.jar') - implementation files('..\\app\\libs\\utils-4.8.8-android.jar') testImplementation 'junit:junit:4.12' implementation 'org.bouncycastle:bcprov-jdk15on:1.62' // https://mvnrepository.com/artifact/com.github.cliftonlabs/json-simple diff --git a/lib/src/main/java/com/alphawallet/token/entity/EthereumReadBuffer.java b/lib/src/main/java/com/alphawallet/token/entity/EthereumReadBuffer.java index 2582c1aec7..6321d538d9 100644 --- a/lib/src/main/java/com/alphawallet/token/entity/EthereumReadBuffer.java +++ b/lib/src/main/java/com/alphawallet/token/entity/EthereumReadBuffer.java @@ -6,6 +6,7 @@ import java.math.BigInteger; import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; import com.alphawallet.token.tools.Numeric; @@ -35,6 +36,7 @@ public BigInteger readBI() throws IOException /** * Custom BigInteger which is formed from a byte array of sz size. + * * @param sz size of bytes to read for the BigInteger * @return * @throws IOException @@ -50,7 +52,8 @@ public BigInteger readBI(int sz) throws IOException return retVal; } - public String readAddress() throws IOException { + public String readAddress() throws IOException + { byte[] buffer20 = new byte[20]; read(buffer20); return Numeric.toHexString(buffer20); @@ -68,9 +71,12 @@ public int available() throws IOException public void readSignature(byte[] signature) throws IOException { - if (signature.length == 65) { + if (signature.length == 65) + { read(signature); // would it throw already, if the data is too short? - Weiwu - } else { + } + else + { throw new IOException("Data isn't a signature"); // Is this even necessary? - Weiwu } } @@ -91,7 +97,8 @@ public void readUnsignedShort(int[] ints) throws IOException /* * equivalent of Short.toUnsignedInt */ - private int toUnsignedInt(short s) { + private int toUnsignedInt(short s) + { return s & 0x0000FFFF; } @@ -106,7 +113,8 @@ private int toUnsignedInt(byte b) /* * equivalent of Integer.readUnsignedLong */ - public long toUnsignedLong(int i) { + public long toUnsignedLong(int i) + { return i & 0x00000000ffffffffL; // long is always 64 bits } @@ -163,10 +171,9 @@ public int[] readCompressedIndices(int indiciesLength) throws IOException index++; } - int[] indexArray = new int[indexList.size()]; - for (int i = 0; i < indexList.size(); i++) indexArray[i] = indexList.get(i); - - return indexArray; + return indexList.stream() + .mapToInt(Integer::intValue) + .toArray(); } public byte[] readBytes(int i) throws IOException