Compare commits

..
Author SHA1 Message Date
Yevheniia Berdnyk 063d9fd29a e2e: fix for driver creation error 2023-12-22 17:46:38 +02:00
2270 changed files with 61880 additions and 85041 deletions
+13 -25
View File
@@ -1,5 +1,4 @@
{:config-paths ["status-im"]
:output {:exclude-files ["src/user.cljs" "src/dev/user.cljs"]}
:lint-as {legacy.status-im.utils.views/defview clojure.core/defn
legacy.status-im.utils.views/letsubs clojure.core/let
reagent.core/with-let clojure.core/let
@@ -10,31 +9,25 @@
legacy.status-im.utils.styles/def clojure.core/def
legacy.status-im.utils.styles/defn clojure.core/defn
test-helpers.unit/deftest-sub clojure.core/defn
test-helpers.unit/deftest-event clojure.core/defn
taoensso.tufte/defnp clojure.core/defn}
:linters {:case-duplicate-test {:level :error}
:case-quoted-test {:level :error}
:case-symbol-test {:level :error}
:clj-kondo-config {:level :error}
:cond-else {:level :error}
:condition-always-true {:level :error}
:conflicting-alias {:level :error}
:consistent-alias {:level :error
:aliases {clojure.set set
clojure.string string
clojure.walk walk
malli.core malli
malli.dev.pretty malli.pretty
malli.dev.virhe malli.virhe
malli.error malli.error
malli.generator malli.generator
malli.transform malli.transform
malli.util malli.util
promesa.core promesa
schema.core schema
status-im.feature-flags ff
taoensso.timbre log}}
:aliases {clojure.set set
clojure.string string
clojure.walk walk
malli.core malli
malli.dev.pretty malli.pretty
malli.dev.virhe malli.virhe
malli.error malli.error
malli.generator malli.generator
malli.transform malli.transform
malli.util malli.util
schema.core schema
taoensso.timbre log}}
:deprecated-namespace {:level :warning}
:docstring-blank {:level :error}
:equals-true {:level :error}
@@ -47,13 +40,11 @@
:missing-body-in-when {:level :error}
:missing-clause-in-try {:level :error}
:missing-else-branch {:level :error}
:multiple-async-in-deftest {:level :error}
:not-empty? {:level :error}
:plus-one {:level :error}
:redundant-do {:level :error}
:redundant-let {:level :error}
:refer-all {:level :error}
:shadowed-fn-param {:level :error}
:shadowed-var {:level :error
;; We temporarily use :include to define an
;; allowlist of core Clojure vars. In the
@@ -61,11 +52,9 @@
;; vars, we should be able to delete this
;; option and lint all vars.
:exclude [type name]}
:self-requiring-namespace {:level :error}
:single-operand-comparison {:level :error}
:syntax {:level :error}
:unbound-destructuring-default {:level :error}
:underscore-in-namespace {:level :error}
:uninitialized-var {:level :error}
:unknown-require-option {:level :error}
:unreachable-code {:level :error}
@@ -74,8 +63,7 @@
;; https://github.com/borkdude/clj-kondo/issues/867
:unresolved-symbol {:exclude [PersistentPriorityMap.EMPTY
number
legacy.status-im.test-helpers/restore-app-db
(cljs.test/is [match-strict?])]}
legacy.status-im.test-helpers/restore-app-db]}
:unresolved-var {:level :error}
:unsorted-required-namespaces {:level :error}
:unused-alias {:level :warning}
-9
View File
@@ -1,9 +0,0 @@
{:lint-as {promesa.core/-> clojure.core/->
promesa.core/->> clojure.core/->>
promesa.core/as-> clojure.core/as->
promesa.core/let clojure.core/let
promesa.core/plet clojure.core/let
promesa.core/loop clojure.core/loop
promesa.core/recur clojure.core/recur
promesa.core/with-redefs clojure.core/with-redefs
promesa.core/doseq clojure.core/doseq}}
@@ -1,5 +0,0 @@
{:lint-as
{rewrite-clj.zip/subedit-> clojure.core/->
rewrite-clj.zip/subedit->> clojure.core/->>
rewrite-clj.zip/edit-> clojure.core/->
rewrite-clj.zip/edit->> clojure.core/->>}}
-21
View File
@@ -1,21 +0,0 @@
(ns cljs.test
(:require [clj-kondo.hooks-api :as hooks]))
(defn deftest
"Verify test name passed to `cljs.test/deftest` is suffixed with -test and not
prefixed with test-."
[{:keys [node]}]
(let [[_ test-name-node & _] (:children node)
test-name (str (hooks/sexpr test-name-node))]
(when (and (hooks/token-node? test-name-node)
(or (not (re-find #"^.*-test$" test-name))
(re-find #"^test-.*$" test-name)))
(hooks/reg-finding! (assoc (meta test-name-node)
:message "Test name should be suffixed with -test"
:type :status-im.linter/inconsistent-test-name)))))
(comment
;; Invalid
(deftest {:node (hooks/parse-string "(deftest foo-tes (println :hello))")})
(deftest {:node (hooks/parse-string "(deftest test-foo-test (println :hello))")})
)
+2 -11
View File
@@ -1,11 +1,2 @@
{:hooks
{:analyze-call
{utils.i18n/label utils.i18n/label
test-helpers.component/get-all-by-translation-text utils.i18n/label
test-helpers.component/get-by-translation-text utils.i18n/label
test-helpers.component/query-all-by-translation-text utils.i18n/label
test-helpers.component/query-by-translation-text utils.i18n/label
cljs.test/deftest cljs.test/deftest}}
:linters {:status-im.linter/invalid-translation-keyword {:level :error}
:status-im.linter/inconsistent-test-name {:level :error}}}
{:hooks {:analyze-call {utils.i18n/label utils.i18n/label}}
:linters {:status-im.linter/invalid-translation-keyword {:level :error}}}
-1
View File
@@ -1 +0,0 @@
{:hooks {:analyze-call {taoensso.encore/defalias taoensso.encore/defalias}}}
@@ -1,16 +0,0 @@
(ns taoensso.encore
(:require
[clj-kondo.hooks-api :as hooks]))
(defn defalias [{:keys [node]}]
(let [[sym-raw src-raw] (rest (:children node))
src (if src-raw src-raw sym-raw)
sym (if src-raw
sym-raw
(symbol (name (hooks/sexpr src))))]
{:node (with-meta
(hooks/list-node
[(hooks/token-node 'def)
(hooks/token-node (hooks/sexpr sym))
(hooks/token-node (hooks/sexpr src))])
(meta src))}))
+2 -4
View File
@@ -4,6 +4,7 @@ DEFAULT_NETWORK=mainnet_rpc
DEV_BUILD=1
ETHEREUM_DEV_CLUSTER=1
EXTENSIONS=0
FLEET=status.prod
GROUP_CHATS_ENABLED=1
LOG_LEVEL=info
MAILSERVER_CONFIRMATIONS_ENABLED=1
@@ -25,6 +26,7 @@ APN_TOPIC=im.status.ethereum.pr
COMMUNITIES_ENABLED=1
DATABASE_MANAGEMENT_ENABLED=1
DELETE_MESSAGE_ENABLED=1
COLLECTIBLES_ENABLED=1
COMMANDS_ENABLED=1
TWO_MINUTES_SYNCING=1
SWAP_ENABLED=1
@@ -32,7 +34,3 @@ STICKERS_TEST_ENABLED=1
LOCAL_PAIRING_ENABLED=1
TEST_STATEOFUS=1
FAST_CREATE_COMMUNITY_ENABLED=1
TEST_NETWORKS_ENABLED=1
SHOW_NOT_IMPLEMENTED_FEATURES=0
ENABLE_ALERT_BANNER=0
FLAG_WALLET_CONNECT_ENABLED=1
+1 -8
View File
@@ -2,7 +2,7 @@ DEBUG_WEBVIEW=1
DEFAULT_NETWORK=goerli_rpc
ETHEREUM_DEV_CLUSTER=1
EXTENSIONS=0
FLEET=status.staging
FLEET=status.prod
GROUP_CHATS_ENABLED=1
LOG_LEVEL=debug
MAILSERVER_CONFIRMATIONS_ENABLED=0
@@ -33,10 +33,3 @@ TWO_MINUTES_SYNCING=1
STICKERS_TEST_ENABLED=1
LOCAL_PAIRING_ENABLED=1
FAST_CREATE_COMMUNITY_ENABLED=1
TEST_NETWORKS_ENABLED=1
SHOW_NOT_IMPLEMENTED_FEATURES=1
DELETE_MESSAGE_FOR_ME_UNDO_TIME_LIMIT=10000
DELETE_MESSAGE_UNDO_TIME_LIMIT=10000
ENABLE_ALERT_BANNER=0
FLAG_WALLET_CONNECT_ENABLED=1
MOBILE_DATA_SYNCING_TOGGLE_ENABLE=0
+1 -3
View File
@@ -3,6 +3,7 @@ DEBUG_WEBVIEW=1
DEFAULT_NETWORK=goerli_rpc
ETHEREUM_DEV_CLUSTER=1
EXTENSIONS=0
FLEET=status.prod
GROUP_CHATS_ENABLED=1
LOG_LEVEL=debug
MAILSERVER_CONFIRMATIONS_ENABLED=1
@@ -34,6 +35,3 @@ ENABLE_QUO_PREVIEW=1
STICKERS_TEST_ENABLED=1
LOCAL_PAIRING_ENABLED=1
FAST_CREATE_COMMUNITY_ENABLED=1
TEST_NETWORKS_ENABLED=1
ENABLE_ALERT_BANNER=1
FLAG_WALLET_CONNECT_ENABLED=1
+1 -3
View File
@@ -2,6 +2,7 @@ DEBUG_WEBVIEW=1
DEFAULT_NETWORK=mainnet_rpc
ETHEREUM_DEV_CLUSTER=1
EXTENSIONS=0
FLEET=status.prod
GROUP_CHATS_ENABLED=1
LOG_LEVEL=info
MAILSERVER_CONFIRMATIONS_ENABLED=1
@@ -21,6 +22,3 @@ COMMUNITIES_ENABLED=1
DATABASE_MANAGEMENT_ENABLED=1
DELETE_MESSAGE_ENABLED=1
FAST_CREATE_COMMUNITY_ENABLED=0
TEST_NETWORKS_ENABLED=0
ENABLE_ALERT_BANNER=1
FLAG_WALLET_CONNECT_ENABLED=1
+2 -3
View File
@@ -2,6 +2,7 @@ DEBUG_WEBVIEW=0
DEFAULT_NETWORK=mainnet_rpc
ETHEREUM_DEV_CLUSTER=0
EXTENSIONS=0
FLEET=status.prod
GROUP_CHATS_ENABLED=1
LOG_LEVEL=
MAILSERVER_CONFIRMATIONS_ENABLED=1
@@ -17,7 +18,5 @@ PARTITIONED_TOPIC=0
ENABLE_ROOT_ALERT=1
MAX_IMAGES_BATCH=1
DELETE_MESSAGE_ENABLED=1
COLLECTIBLES_ENABLED=1
FAST_CREATE_COMMUNITY_ENABLED=0
TEST_NETWORKS_ENABLED=0
STATUS_PROXY_STAGE_NAME=prod
FLAG_WALLET_CONNECT_ENABLED=1
+3 -3
View File
@@ -1,8 +1,8 @@
---
name: Bug Report
about: Bug Report
name: MVPBug Report
about: MVPBug Report
title: ''
labels: ['bug', ':1234: low prio']
labels: 'E:Mobile Bug MVP'
assignees: ''
---
-16
View File
@@ -70,19 +70,3 @@ Documentation change PR (review please): https://github.com/status-im/status.im/
| Please embed Image/Video here of the before and after. | Please embed Image/Video here of the before and after. | Please embed Image/Video here of the before and after. |
status: ready <!-- Can be ready or wip -->
<!-- Uncomment this section for status-go upgrade/dogfooding pull requests
- Specify potentially impacted user flows in _Areas that maybe impacted*.
- Ensure that _Steps to test_ is filled in.
### Risk
Described potential risks and worst case scenarios.
Tick **one**:
- [ ] Low risk: 2 devs MUST perform testing as specified above and attach their results as comments to this PR **before** merging.
- [ ] High risk: QA team MUST perform additional testing in the specified affected areas **before** merging.
-->
+4 -7
View File
@@ -83,9 +83,6 @@ shim.js
figwheel_server.log
.nrepl-port
# FlowStorm (Clojure debugger)
repl-client-debug
# Lein
#
.lein-failures
@@ -130,8 +127,6 @@ fastlane/README.md
# Clj
.cpcache/
src/user.cljs
src/dev/user.cljs
# emacs
.dir-locals.el
@@ -200,5 +195,7 @@ test/appium/tests/users.py
## git hooks
lefthook.yml
## build time logs
/logs/*.log
## clj-kondo
/.clj-kondo/taoensso/*
/.clj-kondo/babashka/*
/.clj-kondo/rewrite-clj/rewrite-clj/config.edn
+9 -14
View File
@@ -1,15 +1,10 @@
/*
# Format top-level js files.
*
!*.js
# Ignore all except src/js/**/*.js
!/src/
/src/*
!/src/js
!/src/js/**/*.js
# Ignore all except translations/en.json
!/translations/
/translations/*
!/translations/en.json
!*/
*.clj-kondo
*.shadow-cljs
modules
result
target
component-spec
/app
-4
View File
@@ -6,8 +6,4 @@ module.exports = {
tabWidth: 2,
trailingComma: 'all',
useTabs: false,
// JSON sorting
jsonSortOrder: '{ "/.*/": "caseInsensitiveLexical" } ',
plugins: ['prettier-plugin-sort-json'],
};
+42 -50
View File
@@ -1,62 +1,54 @@
;; -*- mode: clojure -*-
;; vi: ft=clojure
{:width 105
:remove {:fn-force-nl #{:noarg1-body}}
{:width 105
:style [;; community style
;; https://github.com/kkinnear/zprint/blob/main/doc/reference.md#community
:community
:style
[;; community style https://github.com/kkinnear/zprint/blob/main/doc/reference.md#community
:community
;; no comma in map
:no-comma
;; no comma in map
:no-comma
:custom-justify
:custom-justify
;; respect all newlines
;; https://github.com/kkinnear/zprint/blob/main/doc/reference.md#respect-nl
:respect-nl
;; respect all newlines https://github.com/kkinnear/zprint/blob/main/doc/reference.md#respect-nl
:respect-nl
;; respect blank line https://github.com/kkinnear/zprint/blob/main/doc/reference.md#respect-bl
:respect-bl
;; hang multiline left-hand-thing https://github.com/kkinnear/zprint/issues/273
:multi-lhs-hang]
;; respect blank line
;; https://github.com/kkinnear/zprint/blob/main/doc/reference.md#respect-bl
:respect-bl
;; hang multiline left-hand-thing
;; https://github.com/kkinnear/zprint/issues/273
:multi-lhs-hang]
:fn-map
{"reg-sub" :arg1-pair
"h/describe" :arg1-body
"h/describe-skip" :arg1-body
"h/describe-only" :arg1-body
"h/test" :arg1-body
"h/test-skip" :arg1-body
"h/test-only" :arg1-body
"test/async" :arg1-body
"test/use-fixtures" :arg1-body
"global.describe" :arg1-body
"global.test" :arg1-body
"list-comp" :binding
"defview" :arg1-body
"letsubs" :binding
"with-let" "let"
"reg-event-fx" :arg1-pair
"reg-fx" :arg1-pair
"testing" :arg1-body
"deftest-sub" :arg1-body
"deftest-event" :arg1-body
"test-async" :arg1-body
"wait-for" :arg1-body
"with-deps-check" :arg1-body
"schema/=>" :arg1-body
"->" [:noarg1-body
{:list {:constant-pair? false :force-nl? false}
:next-inner-restore [[:list :constant-pair?]]}]
"set!" "reset!"
"assoc-when" "assoc"
"assoc-some" "assoc"
"conj-when" "conj"
"conj-some" "conj"}
{"reg-sub" :arg1-pair
"h/describe" :arg1-body
"h/test" :arg1-body
"global.describe" :arg1-body
"global.test" :arg1-body
"list-comp" :binding
"defview" :arg1-body
"letsubs" :binding
"with-let" "let"
"reg-event-fx" :arg1-pair
"reg-fx" :arg1-pair
"testing" :arg1-body
"deftest-sub" :arg1-body
"wait-for" :arg1-body
"with-deps-check" :arg1-body
"schema/=>" :arg1-body
"->" [:noarg1-body
{:list {:constant-pair? false :force-nl? false}
:next-inner-restore [[:list :constant-pair?]]}]
"set!" "reset!"
"assoc-when" "assoc"
"assoc-some" "assoc"
"conj-when" "conj"
"conj-some" "conj"}
:remove {:fn-force-nl #{:noarg1-body}}
:style-map
{:no-comma {:map {:comma? false}}
{:no-comma {:map {:comma? false}}
:custom-justify
{:doc "Justify everything using pre-1.1.2 approach"
:binding {:justify? true :justify {:max-variance 1000}}
+69 -145
View File
@@ -32,12 +32,10 @@ ifndef BUILD_TAG
export BUILD_TAG := $(shell git rev-parse --short HEAD)
endif
# We don't want to use /run/user/$UID because it runs out of space too easily.
# We don't want to use /run/user/$UID because it runs out of space too easilly.
export TMPDIR = /tmp/tmp-status-mobile-$(BUILD_TAG)
# This has to be specified for both the Node.JS server process and the Qt process.
export REACT_SERVER_PORT ?= 5001
# Default metro port used by scripts/run-android.sh.
export RCT_METRO_PORT ?= 8081
# Fix for ERR_OSSL_EVP_UNSUPPORTED error.
export NODE_OPTIONS += --openssl-legacy-provider
# The path can be anything, but home is usually safest.
@@ -46,7 +44,7 @@ export KEYSTORE_PATH ?= $(HOME)/.gradle/status-im.keystore
# Our custom config is located in nix/nix.conf
export NIX_USER_CONF_FILES = $(PWD)/nix/nix.conf
# Location of symlinks to derivations that should not be garbage collected
export _NIX_GCROOTS = ./.nix-gcroots
export _NIX_GCROOTS = /nix/var/nix/gcroots/per-user/$(USER)/status-mobile
# Defines which variables will be kept for Nix pure shell, use semicolon as divider
export _NIX_KEEP ?= TMPDIR,BUILD_ENV,\
BUILD_TYPE,BUILD_NUMBER,COMMIT_HASH,\
@@ -56,6 +54,12 @@ export _NIX_KEEP ?= TMPDIR,BUILD_ENV,\
# Useful for Android release builds
TMP_BUILD_NUMBER := $(shell ./scripts/version/gen_build_no.sh | cut -c1-10)
# MacOS root is read-only, read nix/README.md for details
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Darwin)
export NIX_IGNORE_SYMLINK_STORE=1
endif
#----------------
# Nix targets
#----------------
@@ -139,7 +143,7 @@ _install-hooks: ##@prepare Create prepare-commit-msg git hook symlink
# Remove directories and ignored files
clean: SHELL := /bin/sh
clean: _fix-node-perms _tmpdir-rm ios-clean android-clean ##@prepare Remove all output folders
clean: _fix-node-perms _tmpdir-rm ##@prepare Remove all output folders
git clean -dXf
# Remove directories, ignored and non-ignored files
@@ -156,12 +160,10 @@ pod-install: export TARGET := ios
pod-install: ##@prepare Run 'pod install' to install podfiles and update Podfile.lock
cd ios && pod install; cd --
FLEETS_FILE := ./resources/config/fleets.json
update-fleets: ##@prepare Download up-to-date JSON file with current fleets state
curl -s https://fleets.status.im/ \
| sed 's/"warning": "/"warning": "DO NOT EDIT! /' \
> $(FLEETS_FILE)
echo >> $(FLEETS_FILE)
> resources/config/fleets.json
$(KEYSTORE_PATH): export TARGET := keytool
$(KEYSTORE_PATH):
@@ -196,10 +198,6 @@ xcode-clean: XCODE_HOME := $(HOME)/Library/Developer/Xcode
xcode-clean: ##@prepare Clean XCode derived data and archives
rm -fr $(XCODE_HOME)/DerivedData/StatusIm-* $(XCODE_HOME)/Archives/*/StatusIm*
ios-simulator-cache-clean: SHELL := /bin/sh
ios-simulator-cache-clean: ##@prepare Clean iOS Simulator Caches
rm -rf ~/Library/Developer/CoreSimulator/Cache
#----------------
# Release builds
#----------------
@@ -214,14 +212,16 @@ build-fdroid: ##@build Build release for F-Droid
build-android: export BUILD_ENV ?= prod
build-android: export BUILD_TYPE ?= nightly
build-android: export ORG_GRADLE_PROJECT_versionCode ?= $(TMP_BUILD_NUMBER)
build-android: export BUILD_NUMBER ?= $(TMP_BUILD_NUMBER)
build-android: export ANDROID_ABI_SPLIT ?= false
build-android: export ANDROID_ABI_INCLUDE ?= armeabi-v7a;arm64-v8a;x86
build-android: ##@build Build unsigned Android APK
@scripts/build-android.sh
release-android: export TARGET := keytool
release-android: export KEYSTORE_PATH ?= $(HOME)/.gradle/status-im.keystore
release-android: keystore build-android ##@build Build signed Android APK
@scripts/sign-android.sh result/app-arm64-v8a-release-unsigned.apk
@scripts/sign-android.sh result/app-release-unsigned.apk
release-ios: export TARGET := ios
release-ios: export IOS_STATUS_GO_TARGETS := ios/arm64
@@ -265,7 +265,7 @@ run-clojure: ##@run Watch for and build Clojure changes for mobile
run-metro: export TARGET := clojure
run-metro: ##@run Start Metro to build React Native changes
@scripts/run-metro.sh
@scripts/start-react-native.sh
run-re-frisk: export TARGET := clojure
run-re-frisk: ##@run Start re-frisk server
@@ -273,27 +273,31 @@ run-re-frisk: ##@run Start re-frisk server
# TODO: Migrate this to a Nix recipe, much the same way as nix/mobile/android/targets/release-android.nix
run-android: export TARGET := android
# Disabled for debug builds to avoid 'maximum call stack exceeded' errors.
# https://github.com/status-im/status-mobile/issues/18493
run-android: export ORG_GRADLE_PROJECT_hermesEnabled := false
# INFO: If it's empty (no devices attached, parsing issues, script error) - for Nix it's the same as not set.
run-android: export ANDROID_ABI_INCLUDE ?= $(shell ./scripts/adb_devices_abis.sh)
run-android: ##@run Build Android APK and start it on the device
@scripts/run-android.sh
npx react-native run-android --appIdSuffix debug
SIMULATOR=iPhone 13
# TODO: fix IOS_STATUS_GO_TARGETS to be either amd64 or arm64 when RN is upgraded
run-ios: export TARGET := ios
run-ios: export IOS_STATUS_GO_TARGETS := ios/arm64;iossimulator/amd64
run-ios: ##@run Build iOS app and start it in on the simulator
@scripts/run-ios.sh "${SIMULATOR}"
run-ios: export IOS_STATUS_GO_TARGETS := iossimulator/amd64
run-ios: ##@run Build iOS app and start it in a simulator/device
ifneq ("$(SIMULATOR)", "")
npx react-native run-ios --simulator="$(SIMULATOR)" | xcbeautify
else
npx react-native run-ios | xcbeautify
endif
show-ios-devices: ##@other shows connected ios device and its name
xcrun xctrace list devices
# TODO: fix IOS_STATUS_GO_TARGETS to be either amd64 or arm64 when RN is upgraded
run-ios-device: export TARGET := ios
run-ios-device: export IOS_STATUS_GO_TARGETS := ios/arm64;iossimulator/amd64
run-ios-device: ##@run iOS app and start it on the first connected iPhone
@scripts/run-ios-device.sh
run-ios-device: export IOS_STATUS_GO_TARGETS := ios/arm64
run-ios-device: ##@run iOS app and start it on a connected device by its name
ifndef DEVICE_NAME
$(error Usage: make run-ios-device DEVICE_NAME=your-device-name)
endif
react-native run-ios --device "$(DEVICE_NAME)"
#--------------
# Tests
@@ -301,7 +305,7 @@ run-ios-device: ##@run iOS app and start it on the first connected iPhone
# Get all clojure files, including untracked, excluding removed
define find_all_clojure_files
$$(comm -23 <(sort <(git ls-files --cached --others --exclude-standard)) <(sort <(git ls-files --deleted)) | grep -E '((\.clj-kondo\/status-im)|(src).*\.clj[sc]?$$)|((\.clj-kondo\/(status-im|config))|(src).*\.edn$$)|shadow-cljs\.edn')
$$(comm -23 <(sort <(git ls-files --cached --others --exclude-standard)) <(sort <(git ls-files --deleted)) | grep -e \.clj$$ -e \.cljs$$ -e \.cljc$$ -e \.edn)
endef
lint: export TARGET := clojure
@@ -315,7 +319,7 @@ lint: ##@test Run code style checks
scripts/lint/translations.clj && \
zprint '{:search-config? true}' -sfc $$ALL_CLOJURE_FILES && \
sh scripts/lint/trailing-newline.sh && \
node_modules/.bin/prettier --check .
node_modules/.bin/prettier --write .
# NOTE: We run the linter twice because of https://github.com/kkinnear/zprint/issues/271
lint-fix: export TARGET := clojure
@@ -323,7 +327,7 @@ lint-fix: ##@test Run code style checks and fix issues
ALL_CLOJURE_FILES=$(call find_all_clojure_files) && \
zprint '{:search-config? true}' -sw $$ALL_CLOJURE_FILES && \
zprint '{:search-config? true}' -sw $$ALL_CLOJURE_FILES && \
clojure-lsp --ns-exclude-regex ".*/\.clj-kondo/.*|.*/src/status_im/core\.cljs|.*/src/test_helpers/component_tests_preload\.cljs$$" clean-ns && \
clojure-lsp --ns-exclude-regex ".*/src/status_im/core\.cljs$$" clean-ns && \
sh scripts/lint/trailing-newline.sh --fix && \
node_modules/.bin/prettier --write .
@@ -331,89 +335,51 @@ shadow-server: export TARGET := clojure
shadow-server:##@ Start shadow-cljs in server mode for watching
yarn shadow-cljs server
_test-clojure: export TARGET := clojure
_test-clojure: export WATCH ?= false
_test-clojure: status-go-library
_test-clojure:
ifeq ($(WATCH), true)
yarn node-pre-gyp rebuild && \
yarn shadow-cljs compile mocks && \
nodemon --exec "yarn shadow-cljs compile test && node --require ./test-resources/override.js $$SHADOW_OUTPUT_TO" -e cljs
else
yarn node-pre-gyp rebuild && \
test-watch: export TARGET := clojure
test-watch: ##@ Watch tests and re-run no changes to cljs files
yarn install
nodemon --exec 'yarn shadow-cljs compile mocks && yarn shadow-cljs compile test && node --require ./test-resources/override.js target/test/test.js' -e cljs
test-watch-for-repl: export TARGET := clojure
test-watch-for-repl: ##@ Watch tests and support REPL connections
yarn install
rm -f target/test/test.js
concurrently --kill-others --prefix-colors 'auto' --names 'build,repl' \
'yarn shadow-cljs compile mocks && yarn shadow-cljs watch test --verbose' \
'until [ -f ./target/test/test.js ] ; do sleep 1 ; done ; node --require ./test-resources/override.js ./target/test/test.js --repl'
test: export TARGET := clojure
test: ##@test Run tests once in NodeJS
# Here we create the gyp bindings for nodejs
yarn install
yarn shadow-cljs compile mocks && \
yarn shadow-cljs compile test && \
node --require ./test-resources/override.js "$$SHADOW_OUTPUT_TO"
endif
node --require ./test-resources/override.js target/test/test.js
test: export SHADOW_OUTPUT_TO := target/test/test.js
test: export SHADOW_NS_REGEXP := .*-test$$
test: ##@test Run all Clojure tests
test: _test-clojure
# Note: we need to override the :output-to and :ns-regexp options because
# shadow-cljs has a bug where it will not read from the env vars to expand the
# configuration when the shadow-cljs mobile target is already running.
test-watch-for-repl: export TARGET := default
test-watch-for-repl: export SHADOW_OUTPUT_TO := target/test/test.js
test-watch-for-repl: export SHADOW_NS_REGEXP := .*-test$$
test-watch-for-repl: ##@test Watch all Clojure tests and support REPL connections
rm -f "$$SHADOW_OUTPUT_TO" && \
yarn install && shadow-cljs compile mocks && \
concurrently --kill-others --prefix-colors 'auto' --names 'build,repl' \
"yarn shadow-cljs watch test --verbose --config-merge '{:output-to \"$(SHADOW_OUTPUT_TO)\" :ns-regexp \"$(SHADOW_NS_REGEXP)\"}'" \
"until [ -f $$SHADOW_OUTPUT_TO ] ; do sleep 1 ; done ; node --require ./test-resources/override.js $$SHADOW_OUTPUT_TO --repl"
test-unit: export SHADOW_OUTPUT_TO := target/unit_test/test.js
test-unit: export SHADOW_NS_REGEXP := ^(?!tests\.integration-test)(?!tests\.contract-test).*-test$$
test-unit: ##@test Run unit tests
test-unit: _test-clojure
test-integration: export SHADOW_OUTPUT_TO := target/integration_test/test.js
test-integration: export SHADOW_NS_REGEXP := ^tests\.integration-test.*$$
test-integration: ##@test Run integration tests
test-integration: _test-clojure
test-contract: export SHADOW_OUTPUT_TO := target/contract_test/test.js
test-contract: export SHADOW_NS_REGEXP := ^tests\.contract-test.*$$
test-contract: ##@test Run contract tests
test-contract: _test-clojure
test-android: jsbundle
test-android: export TARGET := android
test-android: ##@test Android Gradle test
android-test: jsbundle
android-test: export TARGET := android
android-test:
cd android && ./gradlew test
test-component-watch: export TARGET := clojure
test-component-watch: export COMPONENT_TEST := true
test-component-watch: export BABEL_ENV := test
test-component-watch: export JEST_USE_SILENT_REPORTER := false
test-component-watch: ##@ Watch tests and re-run no changes to cljs files
@scripts/check-metro-shadow-process.sh
component-test-watch: export TARGET := clojure
component-test-watch: export COMPONENT_TEST := true
component-test-watch: export BABEL_ENV := test
component-test-watch: ##@ Watch tests and re-run no changes to cljs files
@@scripts/check-metro-shadow-process.sh
rm -rf ./component-spec
yarn install
nodemon --exec 'yarn shadow-cljs compile component-test && jest --config=test/jest/jest.config.js --testEnvironment node ' -e cljs
test-component: export TARGET := clojure
test-component: export COMPONENT_TEST := true
test-component: export BABEL_ENV := test
test-component: export JEST_USE_SILENT_REPORTER := false
test-component: ##@test Run component tests once in NodeJS
component-test: export TARGET := clojure
component-test: export COMPONENT_TEST := true
component-test: export BABEL_ENV := test
component-test: ##@test Run component tests once in NodeJS
@scripts/check-metro-shadow-process.sh
rm -rf ./component-spec
yarn install
yarn shadow-cljs compile component-test && \
jest --clearCache && jest --config=test/jest/jest.config.js --testEnvironment node
# Reference: https://flow-storm.github.io/flow-storm-debugger/user_guide.html#_debugging_react_native_applications
run-flow-storm: export SHADOW_CLJS_BUILD_ID := :mobile
run-flow-storm: export TARGET := clojure
run-flow-storm: export GDK_DPI_SCALE := 1.0
run-flow-storm: ##@run Start FlowStorm debugger
clj -Sforce -Sdeps '{:deps {com.github.jpmonettas/flow-storm-dbg {:mvn/version "3.7.5"}}}' \
-X flow-storm.debugger.main/start-debugger \
:port 7888 \
:repl-type :shadow \
:build-id $(SHADOW_CLJS_BUILD_ID)
#--------------
# Other
#--------------
@@ -424,48 +390,25 @@ geth-connect: ##@other Connect to Geth on the device
build/bin/geth attach http://localhost:8545
ios-clean: SHELL := /bin/sh
ios-clean: ios-simulator-cache-clean
ios-clean: ##@prepare Clean iOS build artifacts
git clean -dxf -f target/ios
android-clean: SHELL := /bin/sh
android-clean: export TARGET := gradle
android-clean: ##@prepare Clean Gradle state
git clean -dxf -f ./android/app/build; \
rm -rf android/.gradle \
rm -rf android/build \
rm -rf ~/.gradle
[[ -d android/.gradle ]] && cd android && ./gradlew clean
android-ports: export FLOWSTORM_PORT ?= 7722
android-ports: export TARGET := android-sdk
android-ports: export RCT_METRO_PORT ?= 8081
android-ports: ##@other Add proxies to Android Device/Simulator
adb reverse tcp:$(RCT_METRO_PORT) tcp:$(RCT_METRO_PORT) && \
adb reverse tcp:8081 tcp:8081 && \
adb reverse tcp:3449 tcp:3449 && \
adb reverse tcp:4567 tcp:4567 && \
adb reverse tcp:$(FLOWSTORM_PORT) tcp:$(FLOWSTORM_PORT) && \
adb forward tcp:5561 tcp:5561
android-devices: export TARGET := android-sdk
android-devices: ##@other Invoke adb devices
adb devices
android-pull-geth: export TARGET := android-sdk
android-pull-geth: export VERSION ?= debug
android-pull-geth:
adb pull "/storage/emulated/0/Android/data/im.status.ethereum$$( [ "$(VERSION)" = "release" ] || echo ".$(VERSION)" )/files/Download/geth.log"
android-tail-geth: export TARGET := android-sdk
android-tail-geth: export VERSION ?= debug
android-tail-geth:
adb shell 'while true; do cat; sleep 1; done < /storage/emulated/0/Android/data/im.status.ethereum$$( [ "$(VERSION)" = "release" ] || echo ".$(VERSION)" )/files/Download/geth.log'
android-clean-geth: export TARGET := android-sdk
android-clean-geth: export VERSION ?= debug
android-clean-geth:
adb shell 'rm /storage/emulated/0/Android/data/im.status.ethereum$$( [ "$(VERSION)" = "release" ] || echo ".$(VERSION)" )/files/Download/geth.log'
android-logcat: export TARGET := android-sdk
android-logcat: ##@other Read status-mobile logs from Android phone using adb
adb logcat | grep -e RNBootstrap -e ReactNativeJS -e ReactNative -e StatusModule -e StatusNativeLogs -e 'F DEBUG :' -e 'Go :' -e 'GoLog :' -e 'libc :'
@@ -479,10 +422,6 @@ _list: SHELL := /bin/sh
_list:
@$(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | sort | egrep -v -e '^[^[:alnum:]]' -e '^$@$$'
patch-file: export TARGET := default
patch-file: ##@other Generates patch file for npm deps
@scripts/patch-npm-lib.sh
#--------------
# REPLs
#--------------
@@ -492,18 +431,3 @@ repl-clojure: ##@repl Start Clojure repl for mobile App
yarn shadow-cljs cljs-repl mobile
repl-nix: nix-repl ##@repl Start an interactive Nix REPL
#--------------
# Dev Automation Flows
#--------------
auto-login: export TARGET := default
auto-login: ##@auto runs flow for login or onboarding app on simulator/emulator
maestro test "maestro/create-account-or-login.yaml"
auto-custom: export TARGET := default
auto-custom: ##@auto runs any custom maestro automation flow on simulator/emulator
ifndef FLOW
$(error Usage: make automate FLOW=your-maestro-flow-file.yaml)
endif
maestro test "$(FLOW)"
+3 -3
View File
@@ -37,7 +37,7 @@ project dependencies, coding guidelines and testing procedures.
Check out our [coding guidelines](doc/new-guidelines.md).
- **Community Management**
Metcalfe's law states that the value of a network is proportional to the square of the number of connected users of the system - without community Status is meaningless. We're looking to create a positive, fun environment to explore new ideas, experiment and grow the Status community. Building a community takes a lot of work but the people you'll meet and the long-lasting relationships you form will be well worth it, check out our [Mission and Community Principles](https://status.app/manifesto)
Metcalfe's law states that the value of a network is proportional to the square of the number of connected users of the system - without community Status is meaningless. We're looking to create a positive, fun environment to explore new ideas, experiment and grow the Status community. Building a community takes a lot of work but the people you'll meet and the long-lasting relationships you form will be well worth it, check out our [Mission and Community Principles](https://status.im/about)
- **Specification / Documentation**
John Dewey once said, "Education is not preparation for life; education is life *itself* ". Developers and Designers need guidance and it all starts from documentation and specifications. Our software is only as good as its documentation, check out our [docs](doc/) and see how you can improve what we have.
@@ -53,10 +53,10 @@ Status is a visual interface to make permanent changes on the Blockchain, it han
- **Evangelism**
Help us spread the word! Tell a friend *right now*, in fact, tell **everyone** - yell from a mountain if you have to, every person counts! If you've got a great story to tell or have some interesting way you've spread the word about Status let us know about it in our [chat](https://join.status.im/chat/public/status)
## Give me Binaries!
You can get our Beta builds for both Android and iOS on our [website](https://status.app), through our [nightly builds](https://status.im/nightly/), or by [building it yourself](doc/starting-guide.md).
You can get our Beta builds for both Android and iOS on our [website](https://status.im), through our [nightly builds](https://status.im/nightly/), or by [building it yourself](https://status.im/technical/build_status/).
## Core Contributors
+1 -1
View File
@@ -1 +1 @@
2.29.0
1.25.0
+24 -37
View File
@@ -1,5 +1,4 @@
apply plugin: "com.android.application"
apply plugin: "org.jetbrains.kotlin.android"
apply plugin: "com.facebook.react"
apply from: project(':react-native-config').projectDir.getPath() + "/dotenv.gradle"
@@ -59,7 +58,7 @@ react {
/**
* Set this to true to Run Proguard on Release builds to minify the Java bytecode.
*/
def enableProguardInReleaseBuilds = true
def enableProguardInReleaseBuilds = false
/**
* The preferred build flavor of JavaScriptCore (JSC)
@@ -83,6 +82,7 @@ def jscFlavor = 'org.webkit:android-jsc:+'
*/
def enableHermes = hermesEnabled.toBoolean();
def getCommitHash = { ->
if (project.hasProperty("commitHash")) {
return project.commitHash
@@ -137,24 +137,11 @@ def getEnvOrConfig = { varName ->
android {
ndkVersion rootProject.ext.ndkVersion
buildToolsVersion rootProject.ext.buildToolsVersion
compileSdk rootProject.ext.compileSdkVersion
kotlinOptions {
jvmTarget = JavaVersion.VERSION_17
}
// https://developer.android.com/studio/projects/install-ndk#vanilla_cmake
externalNativeBuild {
cmake {
// This version must match cmakeVersions inside nix/pkgs/android-sdk/compose.nix
version "3.22.1"
}
}
compileSdkVersion rootProject.ext.compileSdkVersion
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
}
namespace "im.status.ethereum"
@@ -206,12 +193,16 @@ android {
doNotStrip '*/mips/*.so'
doNotStrip '*/mips64/*.so'
}
dexOptions {
jumboMode true
javaMaxHeapSize "8g"
}
splits {
abi {
reset()
enable getEnvOrConfig('ANDROID_ABI_SPLIT').toBoolean()
include getEnvOrConfig('ANDROID_ABI_INCLUDE').split(";")
universalApk false
universalApk true
}
}
signingConfigs {
@@ -232,7 +223,6 @@ android {
}
release {
minifyEnabled enableProguardInReleaseBuilds
shrinkResources enableProguardInReleaseBuilds
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
signingConfig null
}
@@ -240,10 +230,10 @@ android {
initWith release
applicationIdSuffix ".pr"
versionNameSuffix ".pr"
debuggable false
debuggable false
matchingFallbacks = ["release"]
// necessary to make react-native-config's code generation work
resValue "string", "build_config_package", "im.status.ethereum"
// necessary to make react-native-config's code generation work
resValue "string", "build_config_package", "im.status.ethereum"
}
}
@@ -276,29 +266,26 @@ android {
dependencies {
// The version of react-native is set by the React Native Gradle Plugin
implementation("com.facebook.react:react-android")
implementation("androidx.core:core-splashscreen:1.0.0")
implementation "androidx.core:core-splashscreen:1.0.0"
if (enableHermes) {
if (hermesEnabled.toBoolean()) {
implementation("com.facebook.react:hermes-android")
} else {
// https://github.com/status-im/status-mobile/issues/18493
// we don't use hermes for debug builds because it crashes too often
implementation(jscFlavor)
} else {
implementation jscFlavor
}
// react-native-screens
implementation("androidx.appcompat:appcompat:1.1.0-rc01")
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0-alpha02")
implementation("androidx.multidex:multidex:2.0.1") // required by status-mobile/android/app/src/main/java/im/status/ethereum/MainApplication.java
implementation 'androidx.appcompat:appcompat:1.1.0-rc01'
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0-alpha02'
implementation 'androidx.multidex:multidex:2.0.1' // required by status-mobile/android/app/src/main/java/im/status/ethereum/MainApplication.java
implementation project(':react-native-blur')
implementation project(':react-native-status')
implementation project(':react-native-status-keycard')
implementation("com.github.status-im:function:0.0.1")
implementation("com.facebook.fresco:fresco:2.5.0")
implementation("com.facebook.fresco:animated-gif:2.5.0")
implementation("com.squareup.okhttp3:okhttp-tls:4.11.0")
implementation 'com.github.status-im:function:0.0.1'
implementation 'com.facebook.fresco:fresco:2.5.0'
implementation 'com.facebook.fresco:animated-gif:2.5.0'
implementation "com.squareup.okhttp3:okhttp-tls:4.9.2"
implementation("com.google.prefab:cli:2.0.0")
implementation("com.android.tools.build:aapt2:8.1.1-10154469")
}
+1 -13
View File
@@ -58,9 +58,6 @@
-keep interface okhttp3.** { *; }
-dontwarn okhttp3.**
# to fix : java.security.KeyStoreException: BKS not found
-keep class org.bouncycastle.** { *; }
# okio
-keep class sun.misc.Unsafe { *; }
@@ -78,13 +75,4 @@
-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
**[] $VALUES;
public *;
}
# react-native-config
# https://github.com/lugg/react-native-config?tab=readme-ov-file#problems-with-proguard
-keep class im.status.ethereum.BuildConfig {*;}
# react-native-navigation
# to fix : java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
# at com.reactnativenavigation.views.element.animators.PropertyAnimatorCreator.getChildClass(Unknown Source:13)
-keep class com.reactnativenavigation.** {*;}
}
+4 -2
View File
@@ -3,9 +3,11 @@
xmlns:tools="http://schemas.android.com/tools">
<!-- These are added by React Native for debug mode, but actually aren't needed in release mode -->
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission tools:node="remove" android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<!-- Remove licensing permission since we don't license our app and it blocks F-Droid submissions. -->
<uses-permission tools:node="remove" android:name="com.android.vending.CHECK_LICENSE"/>
<application tools:targetApi="28" tools:ignore="GoogleAppIndexingWarning" android:usesCleartextTraffic="true" />
<application tools:targetApi="28" tools:ignore="GoogleAppIndexingWarning" android:usesCleartextTraffic="true" >
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" android:exported="false" />
</application>
</manifest>
+1 -38
View File
@@ -2,16 +2,8 @@
xmlns:tools="http://schemas.android.com/tools"
android:installLocation="auto">
<queries>
<intent>
<action android:name="android.intent.action.SEND_MULTIPLE" />
<data android:mimeType="*/*" />
</intent>
</queries>
<!-- non-dangerous permissions -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.NFC"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
@@ -36,7 +28,6 @@
android:allowBackup="false"
android:label="@string/app_name"
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
android:theme="@style/Theme.AppSplash"
android:name=".MainApplication"
android:largeHeap="true"
@@ -71,30 +62,8 @@
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!-- Handles http and https URLs for status.app -->
<data android:scheme="http" android:host="status.app" />
<data android:scheme="https" android:host="status.app" />
<!-- Community paths -->
<data android:pathPattern="/c/.*" android:host="status.app" android:scheme="http" />
<data android:pathPattern="/c/.*" android:host="status.app" android:scheme="https" />
<!-- Community channel paths -->
<data android:pathPattern="/cc/.*" android:host="status.app" android:scheme="http" />
<data android:pathPattern="/cc/.*" android:host="status.app" android:scheme="https" />
<!-- User paths -->
<data android:pathPattern="/u/.*" android:host="status.app" android:scheme="http" />
<data android:pathPattern="/u/.*" android:host="status.app" android:scheme="https" />
<!-- Private chat paths -->
<data android:pathPattern="/p/.*" android:host="status.app" android:scheme="http" />
<data android:pathPattern="/p/.*" android:host="status.app" android:scheme="https" />
<!-- Community request paths -->
<data android:pathPattern="/cr/.*" android:host="status.app" android:scheme="http" />
<data android:pathPattern="/cr/.*" android:host="status.app" android:scheme="https" />
<!-- Group chat paths -->
<data android:pathPattern="/g/.*" android:host="status.app" android:scheme="http" />
<data android:pathPattern="/g/.*" android:host="status.app" android:scheme="https" />
<!-- Wallet paths -->
<data android:pathPattern="/wallet/.*" android:host="status.app" android:scheme="http" />
<data android:pathPattern="/wallet/.*" android:host="status.app" android:scheme="https" />
</intent-filter>
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
@@ -105,13 +74,7 @@
</intent-filter>
</activity>
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity"/>
<service
android:name="im.status.ethereum.pushnotifications.ForegroundService"
android:foregroundServiceType="specialUse">
<property
android:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE"
android:value="local notifications"/>
</service>
<service android:name="im.status.ethereum.pushnotifications.ForegroundService"></service>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
@@ -0,0 +1,268 @@
package im.status.ethereum;
import android.content.Context;
import android.annotation.TargetApi;
import androidx.annotation.Nullable;
import android.app.AlertDialog;
import android.app.ActivityManager;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.DialogInterface.OnClickListener;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Looper;
import android.preference.PreferenceManager;
import androidx.core.app.ActivityCompat;
import android.util.Log;
import android.view.WindowManager;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.provider.Settings;
import android.os.Bundle;
import android.os.Handler;
import com.facebook.react.ReactActivityDelegate;
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
import com.facebook.react.defaults.DefaultReactActivityDelegate;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.WritableMap;
import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView;
import com.reactnativenavigation.NavigationActivity;
import com.facebook.react.modules.core.PermissionListener;
import androidx.core.splashscreen.SplashScreen;
import java.util.Properties;
import im.status.ethereum.module.StatusThreadPoolExecutor;
import im.status.ethereum.MainApplication;
public class MainActivity extends NavigationActivity
implements ActivityCompat.OnRequestPermissionsResultCallback{
@Nullable private PermissionListener mPermissionListener;
private boolean keepSplash = true;
private final int SPLASH_DELAY = 3200;
/**
* Returns the name of the main component registered from JavaScript. This is used to schedule
* rendering of the component.
*/
protected String getMainComponentName() {
return "StatusIm";
}
private static void registerUncaughtExceptionHandler(final Context context) {
final Thread.UncaughtExceptionHandler defaultUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(final Thread thread, final Throwable t) {
// High priority, so don't use StatusThreadPoolExecutor
new Thread() {
@Override
public void run() {
Looper.prepare();
new AlertDialog.Builder(context)
.setTitle("Error")
.setMessage(t.toString())
.setNegativeButton("Exit", new DialogInterface.OnClickListener() {
public void onClick(final DialogInterface dialog, final int id) {
dialog.dismiss();
defaultUncaughtExceptionHandler.uncaughtException(thread, t);
}
}).show();
Looper.loop();
}
}.start();
}
});
}
private ActivityManager getActivityManager() {
return (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
}
private ActivityManager.MemoryInfo getAvailableMemory(final ActivityManager activityManager) {
final ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
activityManager.getMemoryInfo(memoryInfo);
return memoryInfo;
}
protected void configureStatus() {
// Required because of crazy APN settings redirecting localhost (found in GB)
Properties properties = System.getProperties();
properties.setProperty("http.nonProxyHosts", "localhost|127.0.0.1");
properties.setProperty("https.nonProxyHosts", "localhost|127.0.0.1");
}
private Intent createNotificationSettingsIntent() {
final Intent intent = new Intent();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
intent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
intent.putExtra(Settings.EXTRA_APP_PACKAGE, getPackageName());
} else {
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.setData(Uri.parse("package:" + getPackageName()));
}
return intent;
}
private void tryToEmit(String eventName, WritableMap event) {
try {
((MainApplication) getApplication()).getReactNativeHost()
.getReactInstanceManager()
.getCurrentReactContext()
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit("url", event);
} catch(Exception e) {/* we expect NPE on first start, which is OK because we have a fallback */}
}
@Override
public void onNewIntent(final Intent intent) {
super.onNewIntent(intent);
if (intent.getDataString() != null && intent.getData().getScheme().startsWith("app-settings")) {
startActivity(createNotificationSettingsIntent());
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
SplashScreen splashScreen = SplashScreen.installSplashScreen(this);
setTheme(R.style.DarkTheme);
// Make sure we get an Alert for every uncaught exceptions
registerUncaughtExceptionHandler(MainActivity.this);
// Report memory details for this application
final ActivityManager activityManager = getActivityManager();
Log.v("RNBootstrap", "Available system memory "+getAvailableMemory(activityManager).availMem + ", maximum usable application memory " + activityManager.getLargeMemoryClass()+"M");
setSecureFlag();
// NOTE: Try to not restore the state https://github.com/software-mansion/react-native-screens/issues/17
super.onCreate(null);
if (!shouldShowRootedNotification()) {
configureStatus();
} else {
AlertDialog dialog = new AlertDialog.Builder(MainActivity.this)
.setMessage(getResources().getString(R.string.root_warning))
.setPositiveButton(getResources().getString(R.string.root_okay), new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
rejectRootedNotification();
dialog.dismiss();
configureStatus();
}
})
.setNegativeButton(getResources().getString(R.string.root_cancel), new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
MainActivity.this.finishAffinity();
}
})
.setOnCancelListener(new OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
dialog.dismiss();
MainActivity.this.finishAffinity();
}
})
.create();
dialog.show();
}
Runnable r = new Runnable() {
@Override
public void run() {
System.loadLibrary("status-logs");
// when app is started but the Activity has been destroyed, the deep linking url event is
// not emitted when coming back to foreground. This is a workaround. If the problem is
// resolved in react-native this code should be removed
if (getIntent().getData() != null) {
WritableMap event = Arguments.createMap();
event.putString("url", getIntent().getDataString());
// on first start emit will (silently) fail, but the regular deep linking handler will work
tryToEmit("url", event);
}
}
};
splashScreen.setKeepOnScreenCondition(() -> keepSplash);
Handler handler = new Handler();
handler.postDelayed(() -> keepSplash = false, SPLASH_DELAY);
StatusThreadPoolExecutor.getInstance().execute(r);
}
@Override
protected void onDestroy() {
super.onDestroy();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Intent intent = new Intent("onConfigurationChanged");
intent.putExtra("newConfig", newConfig);
this.sendBroadcast(intent);
}
private static final String REJECTED_ROOTED_NOTIFICATION = "rejectedRootedNotification";
private static final Integer FREQUENCY_OF_REMINDER_IN_PERCENT = 5;
private boolean shouldShowRootedNotification() {
if (RootUtil.isDeviceRooted() && BuildConfig.ENABLE_ROOT_ALERT == "1") {
if (userRejectedRootedNotification()) {
return ((Math.random() * 100) < FREQUENCY_OF_REMINDER_IN_PERCENT);
} else return true;
} else {
return false;
}
}
private boolean userRejectedRootedNotification() {
SharedPreferences preferences = getPreferences(0);
return preferences.getBoolean(REJECTED_ROOTED_NOTIFICATION, false);
}
private void rejectRootedNotification() {
SharedPreferences preferences = getPreferences(0);
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean(REJECTED_ROOTED_NOTIFICATION, true);
editor.commit();
}
private void setSecureFlag() {
final SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
final boolean setSecure = sharedPrefs.getBoolean("BLANK_PREVIEW", false);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH && setSecure) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
} else {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE);
}
}
@TargetApi(Build.VERSION_CODES.M)
public void requestPermissions(String[] permissions, int requestCode, PermissionListener listener) {
mPermissionListener = listener;
requestPermissions(permissions, requestCode);
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (mPermissionListener != null && mPermissionListener.onRequestPermissionsResult(requestCode, permissions, grantResults)) {
mPermissionListener = null;
}
}
}
@@ -1,236 +0,0 @@
package im.status.ethereum
import android.annotation.TargetApi
import android.app.ActivityManager
import android.app.AlertDialog
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.content.SharedPreferences
import android.content.pm.PackageManager
import android.content.res.Configuration
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.preference.PreferenceManager
import android.provider.Settings
import android.util.Log
import android.view.WindowManager
import androidx.annotation.Nullable
import androidx.core.app.ActivityCompat
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import com.facebook.react.ReactActivityDelegate
import com.facebook.react.bridge.Arguments
import com.facebook.react.bridge.WritableMap
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint
import com.facebook.react.defaults.DefaultReactActivityDelegate
import com.facebook.react.modules.core.DeviceEventManagerModule
import com.facebook.react.modules.core.PermissionListener
import com.reactnativenavigation.NavigationActivity
import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView
import im.status.ethereum.MainApplication
import im.status.ethereum.module.StatusThreadPoolExecutor
import java.util.Properties
class MainActivity : NavigationActivity(), ActivityCompat.OnRequestPermissionsResultCallback {
@Nullable
private var mPermissionListener: PermissionListener? = null
private var keepSplash = true
private val SPLASH_DELAY = 3200
/**
* Returns the name of the main component registered from JavaScript. This is used to schedule
* rendering of the component.
*/
protected fun getMainComponentName(): String {
return "StatusIm"
}
private fun registerUncaughtExceptionHandler(context: Context) {
val defaultUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler()
// High priority, so don't use StatusThreadPoolExecutor
Thread.setDefaultUncaughtExceptionHandler { thread, t ->
Thread {
Looper.prepare()
AlertDialog.Builder(context)
.setTitle("Error")
.setMessage(t.toString())
.setNegativeButton("Exit") { dialog, id ->
dialog.dismiss()
defaultUncaughtExceptionHandler.uncaughtException(thread, t)
}.show()
Looper.loop()
}.start()
}
}
private fun getActivityManager(): ActivityManager {
return getSystemService(ACTIVITY_SERVICE) as ActivityManager
}
private fun getAvailableMemory(activityManager: ActivityManager): ActivityManager.MemoryInfo {
val memoryInfo = ActivityManager.MemoryInfo()
activityManager.getMemoryInfo(memoryInfo)
return memoryInfo
}
protected fun configureStatus() {
// Required because of crazy APN settings redirecting localhost (found in GB)
val properties = System.getProperties()
properties.setProperty("http.nonProxyHosts", "localhost|127.0.0.1")
properties.setProperty("https.nonProxyHosts", "localhost|127.0.0.1")
}
private fun createNotificationSettingsIntent(): Intent {
val intent = Intent()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
intent.action = Settings.ACTION_APP_NOTIFICATION_SETTINGS
intent.putExtra(Settings.EXTRA_APP_PACKAGE, packageName)
} else {
intent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
intent.addCategory(Intent.CATEGORY_DEFAULT)
intent.data = Uri.parse("package:$packageName")
}
return intent
}
private fun tryToEmit(eventName: String, event: WritableMap) {
try {
(getApplication() as MainApplication).reactNativeHost
.getReactInstanceManager()
.getCurrentReactContext()
?.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
?.emit("url", event)
} catch (e: Exception) { // we expect NPE on first start, which is OK because we have a fallback
}
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
if (intent.dataString != null && intent.data!!.scheme!!.startsWith("app-settings")) {
startActivity(createNotificationSettingsIntent())
}
}
override fun onCreate(savedInstanceState: Bundle?) {
val splashScreen = installSplashScreen();
setTheme(R.style.DarkTheme)
// Make sure we get an Alert for every uncaught exceptions
registerUncaughtExceptionHandler(this)
// Report memory details for this application
val activityManager = getActivityManager()
Log.v("RNBootstrap", "Available system memory " + getAvailableMemory(activityManager).availMem + ", maximum usable application memory " + activityManager.largeMemoryClass + "M")
setSecureFlag()
// NOTE: Try to not restore the state https://github.com/software-mansion/react-native-screens/issues/17
super.onCreate(null)
if (!shouldShowRootedNotification()) {
configureStatus()
} else {
val dialog = AlertDialog.Builder(this)
.setMessage(resources.getString(R.string.root_warning))
.setPositiveButton(resources.getString(R.string.root_okay)) { dialog, which ->
rejectRootedNotification()
dialog.dismiss()
configureStatus()
}
.setNegativeButton(resources.getString(R.string.root_cancel)) { dialog, which ->
dialog.dismiss()
finishAffinity()
}
.setOnCancelListener {
it.dismiss()
finishAffinity()
}
.create()
dialog.show()
}
val r = Runnable {
System.loadLibrary("status-logs")
// when app is started but the Activity has been destroyed, the deep linking url event is
// not emitted when coming back to foreground. This is a workaround. If the problem is
// resolved in react-native this code should be removed
if (intent.data != null) {
val event = Arguments.createMap()
event.putString("url", intent.dataString)
// on first start emit will (silently) fail, but the regular deep linking handler will work
tryToEmit("url", event)
}
}
splashScreen.setKeepOnScreenCondition { keepSplash }
val handler = Handler()
handler.postDelayed({ keepSplash = false }, SPLASH_DELAY.toLong())
StatusThreadPoolExecutor.getInstance().execute(r)
}
override fun onDestroy() {
super.onDestroy()
}
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
val intent = Intent("onConfigurationChanged")
intent.putExtra("newConfig", newConfig)
sendBroadcast(intent)
}
private val REJECTED_ROOTED_NOTIFICATION = "rejectedRootedNotification"
private val FREQUENCY_OF_REMINDER_IN_PERCENT = 5
private fun shouldShowRootedNotification(): Boolean {
if (RootUtil.isDeviceRooted() && BuildConfig.ENABLE_ROOT_ALERT == "1") {
return if (userRejectedRootedNotification()) {
(Math.random() * 100) < FREQUENCY_OF_REMINDER_IN_PERCENT
} else true
} else {
return false
}
}
private fun userRejectedRootedNotification(): Boolean {
val preferences = getPreferences(0)
return preferences.getBoolean(REJECTED_ROOTED_NOTIFICATION, false)
}
private fun rejectRootedNotification() {
val preferences = getPreferences(0)
val editor = preferences.edit()
editor.putBoolean(REJECTED_ROOTED_NOTIFICATION, true)
editor.commit()
}
private fun setSecureFlag() {
val sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this)
val setSecure = sharedPrefs.getBoolean("BLANK_PREVIEW", false)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH && setSecure) {
window.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
} else {
window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE)
}
}
@TargetApi(Build.VERSION_CODES.M)
override fun requestPermissions(permissions: Array<String>, requestCode: Int, listener: PermissionListener) {
mPermissionListener = listener
super.requestPermissions(permissions, requestCode)
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
if (mPermissionListener != null && mPermissionListener!!.onRequestPermissionsResult(requestCode, permissions, grantResults)) {
mPermissionListener = null
}
}
}
@@ -0,0 +1,87 @@
package im.status.ethereum;
import androidx.multidex.MultiDexApplication;
import android.webkit.WebView;
import java.lang.reflect.InvocationTargetException;
import com.facebook.react.PackageList;
import com.facebook.react.ReactApplication;
import cl.json.RNSharePackage;
import com.facebook.react.ReactNativeHost;
import com.reactnativenavigation.NavigationApplication;
import com.reactnativenavigation.react.NavigationReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
import com.facebook.react.modules.network.OkHttpClientProvider;
import com.reactnativecommunity.blurview.BlurViewPackage;
import java.util.List;
import im.status.ethereum.keycard.RNStatusKeycardPackage;
import im.status.ethereum.module.StatusPackage;
import im.status.ethereum.pushnotifications.PushNotificationPackage;
import im.status.ethereum.StatusOkHttpClientFactory;
import com.facebook.react.bridge.JSIModulePackage;
public class MainApplication extends NavigationApplication {
private final ReactNativeHost mReactNativeHost = new NavigationReactNativeHost(this) {
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected List<ReactPackage> getPackages() {
StatusPackage statusPackage = new StatusPackage(RootUtil.isDeviceRooted());
List<ReactPackage> packages = new PackageList(this).getPackages();
packages.add(statusPackage);
packages.add(new RNStatusKeycardPackage());
packages.add(new PushNotificationPackage());
packages.add(new BlurViewPackage());
return packages;
}
@Override
protected String getJSMainModuleName() {
return "index";
}
@Override
protected boolean isNewArchEnabled() {
return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
}
@Override
protected Boolean isHermesEnabled() {
return BuildConfig.IS_HERMES_ENABLED;
}
};
@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
@Override
public void onCreate() {
super.onCreate();
OkHttpClientProvider.setOkHttpClientFactory(new StatusOkHttpClientFactory());
WebView.setWebContentsDebuggingEnabled(BuildConfig.DEBUG_WEBVIEW == "1");
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
// If you opted-in for the New Architecture, we load the native entry point for this app.
DefaultNewArchitectureEntryPoint.load();
}
}
}
@@ -1,59 +0,0 @@
package im.status.ethereum
import android.webkit.WebView
import androidx.multidex.MultiDexApplication
import com.facebook.react.PackageList
import com.facebook.react.ReactApplication
import com.facebook.react.ReactNativeHost
import com.facebook.react.ReactPackage
import com.facebook.react.bridge.JSIModulePackage
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint
import com.facebook.react.modules.network.OkHttpClientProvider
import com.reactnativenavigation.NavigationApplication
import com.reactnativenavigation.react.NavigationReactNativeHost
import cl.json.RNSharePackage
import com.reactnativecommunity.blurview.BlurViewPackage
import im.status.ethereum.keycard.RNStatusKeycardPackage
import im.status.ethereum.module.StatusPackage
import im.status.ethereum.pushnotifications.PushNotificationPackage
import im.status.ethereum.StatusOkHttpClientFactory
class MainApplication : NavigationApplication() {
private val mReactNativeHost = object : NavigationReactNativeHost(this) {
override fun getUseDeveloperSupport(): Boolean {
return BuildConfig.DEBUG
}
override fun getPackages(): List<ReactPackage> =
PackageList(this).packages.apply {
// Packages that cannot be autolinked yet can be added manually here
add(StatusPackage(RootUtil.isDeviceRooted()))
add(RNStatusKeycardPackage())
add(PushNotificationPackage())
add(BlurViewPackage())
}
override fun getJSMainModuleName(): String = "index"
override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED
}
override val reactNativeHost: ReactNativeHost
get() = mReactNativeHost
override fun onCreate() {
super.onCreate()
OkHttpClientProvider.setOkHttpClientFactory(StatusOkHttpClientFactory())
WebView.setWebContentsDebuggingEnabled(BuildConfig.DEBUG_WEBVIEW == "1")
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
// If you opted-in for the New Architecture, we load the native entry point for this app.
DefaultNewArchitectureEntryPoint.load()
}
}
}
@@ -1,88 +0,0 @@
package im.status.ethereum
import android.util.Log
import com.facebook.react.modules.network.OkHttpClientFactory
import com.facebook.react.modules.network.OkHttpClientProvider
import okhttp3.OkHttpClient
import okhttp3.tls.HandshakeCertificates
import java.io.ByteArrayInputStream
import java.lang.RuntimeException
import java.lang.reflect.Field
import java.lang.reflect.Method
import java.security.cert.CertificateFactory
import java.security.cert.X509Certificate
import im.status.ethereum.module.StatusPackage
class StatusOkHttpClientFactory : OkHttpClientFactory {
companion object {
private const val TAG = "StatusOkHttpClientFactory"
private const val SLEEP_DURATION = 500L // milliseconds
}
override fun createNewNetworkModuleClient(): OkHttpClient? {
val certPem = getCertificatePem().takeIf { it.isNotEmpty() }
?: return logAndReturnNull("Certificate is empty, cannot create OkHttpClient without a valid certificate")
val cert = try {
induceSleep()
// Convert PEM certificate string to X509Certificate object
CertificateFactory.getInstance("X.509")
.generateCertificate(ByteArrayInputStream(certPem.toByteArray())) as? X509Certificate
?: return logAndReturnNull("Certificate could not be parsed as non-null")
} catch (e: Exception) {
return logAndReturnNull("Could not parse certificate", e)
}
val clientCertificates = try {
induceSleep()
// Create HandshakeCertificates object with our certificate
HandshakeCertificates.Builder()
.addPlatformTrustedCertificates()
.addTrustedCertificate(cert)
.build()
} catch (e: Exception) {
return logAndReturnNull("Could not build HandshakeCertificates", e)
}
return try {
OkHttpClientProvider.createClientBuilder()
.sslSocketFactory(clientCertificates.sslSocketFactory(), clientCertificates.trustManager)
.build()
} catch (e: Exception) {
logAndReturnNull("Could not create OkHttpClient", e)
}
}
private fun getCertificatePem(): String {
return try {
// Create OkHttpClient with custom SSL socket factory and trust manager
StatusPackage.getImageTLSCert().takeIf { !it.isNullOrBlank() }
?: logAndReturnEmpty("Certificate PEM string is null or empty")
} catch (e: Exception) {
logAndReturnEmpty("Could not getImageTLSCert", e)
}
}
private fun induceSleep() {
try {
// induce half second sleep because sometimes a cert is not immediately available
// TODO : remove sleep if App no longer crashes on Android 10 devices with
// java.lang.RuntimeException: Could not invoke WebSocketModule.connect
Thread.sleep(SLEEP_DURATION)
} catch (e: InterruptedException) {
Log.e(TAG, "Sleep interrupted", e)
}
}
private fun logAndReturnNull(message: String, e: Exception? = null): Nothing? {
Log.e(TAG, message, e)
return null
}
private fun logAndReturnEmpty(message: String, e: Exception? = null): String {
Log.e(TAG, message, e)
return ""
}
}
@@ -0,0 +1,95 @@
package im.status.ethereum;
import android.util.Log;
import com.facebook.react.modules.network.OkHttpClientFactory;
import com.facebook.react.modules.network.OkHttpClientProvider;
import okhttp3.OkHttpClient;
import okhttp3.Interceptor;
import okhttp3.tls.HandshakeCertificates;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.lang.RuntimeException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import im.status.ethereum.module.StatusPackage;
class StatusOkHttpClientFactory implements OkHttpClientFactory {
private static final String TAG = "StatusOkHttpClientFactory";
public OkHttpClient createNewNetworkModuleClient() {
X509Certificate cert = null;
HandshakeCertificates clientCertificates;
String certPem = "";
// Get TLS PEM certificate from status-go
try {
// induce half second sleep because sometimes a cert is not immediately available
// TODO : remove sleep if App no longer crashes on Android 10 devices with
// java.lang.RuntimeException: Could not invoke WebSocketModule.connect
Thread.sleep(500);
certPem = getCertificatePem();
} catch(Exception e) {
Log.e(TAG, "Could not getImageTLSCert",e);
}
if (certPem.isEmpty()) {
Log.e(TAG, "Certificate is empty, cannot create OkHttpClient without a valid certificate");
return null;
}
// Convert PEM certificate string to X509Certificate object
try {
// induce half second sleep because sometimes a cert is not immediately available
// TODO : remove sleep if App no longer crashes on Android 10 devices
// java.lang.RuntimeException: Could not invoke WebSocketModule.connect
Thread.sleep(500);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
cert = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(certPem.getBytes()));
} catch(Exception e) {
Log.e(TAG, "Could not parse certificate",e);
}
// Create HandshakeCertificates object with our certificate
try {
// induce half second sleep because sometimes a cert is not immediately available
// TODO : remove sleep if App no longer crashes on Android 10 devices
// java.lang.RuntimeException: Could not invoke WebSocketModule.connect
Thread.sleep(500);
clientCertificates = new HandshakeCertificates.Builder()
.addPlatformTrustedCertificates()
.addTrustedCertificate(cert)
.build();
} catch(Exception e) {
Log.e(TAG, "Could not build HandshakeCertificates", e);
return null;
}
// Create OkHttpClient with custom SSL socket factory and trust manager
try {
return OkHttpClientProvider.createClientBuilder()
.sslSocketFactory(clientCertificates.sslSocketFactory(), clientCertificates.trustManager())
.build();
} catch(Exception e) {
Log.e(TAG, "Could not create OkHttpClient", e);
return null;
}
}
private String getCertificatePem() {
try {
String certPem = StatusPackage.getImageTLSCert();
if (certPem == null || certPem.trim().isEmpty()) {
Log.e(TAG, "Certificate PEM string is null or empty");
return "";
}
return certPem;
} catch (Exception e) {
Log.e(TAG, "Could not getImageTLSCert", e);
return "";
}
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

After

Width:  |  Height:  |  Size: 92 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 940 B

After

Width:  |  Height:  |  Size: 498 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 266 B

After

Width:  |  Height:  |  Size: 272 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 100 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 972 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 452 B

After

Width:  |  Height:  |  Size: 495 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 108 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 824 B

After

Width:  |  Height:  |  Size: 826 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

After

Width:  |  Height:  |  Size: 118 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 825 B

After

Width:  |  Height:  |  Size: 826 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 123 KiB

After

Width:  |  Height:  |  Size: 69 KiB

@@ -2,5 +2,4 @@
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@mipmap/ic_background"/>
<foreground android:drawable="@mipmap/ic_foreground"/>
<monochrome android:drawable="@mipmap/ic_launcher_monochrome" />
</adaptive-icon>
</adaptive-icon>
@@ -2,5 +2,4 @@
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@mipmap/ic_background"/>
<foreground android:drawable="@mipmap/ic_foreground"/>
<monochrome android:drawable="@mipmap/ic_launcher_monochrome" />
</adaptive-icon>
</adaptive-icon>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 374 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

After

Width:  |  Height:  |  Size: 239 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 737 B

After

Width:  |  Height:  |  Size: 678 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 970 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 517 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 905 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 10 KiB

+2 -23
View File
@@ -5,7 +5,7 @@
*/
ext {
// kotlin_version is needed for react-native-camera-kit library
kotlin_version = project.kotlinPluginVersion
kotlin_version = project.kotlinVersion
RNNKotlinVersion = project.kotlinPluginVersion
RNGH_kotlinVersion = project.kotlinPluginVersion
buildToolsVersion = project.buildToolsVersion
@@ -14,9 +14,8 @@ ext {
targetSdkVersion = Integer.valueOf(project.targetSdkVersion)
supportLibVersion = project.supportLibVersion
gradlePluginVersion = project.gradlePluginVersion
kotlinVersion = project.kotlinPluginVersion
kotlinPluginVersion = project.kotlinPluginVersion
kotlinToolsVersion = project.kotlinPluginVersion
ndkVersion = "25.2.9519653"
}
@@ -30,7 +29,6 @@ buildscript {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${project.ext.kotlinPluginVersion}"
classpath("com.android.tools.build:gradle")
classpath("com.facebook.react:react-native-gradle-plugin")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin")
}
}
@@ -44,30 +42,11 @@ subprojects {
defaultConfig {
targetSdkVersion rootProject.ext.targetSdkVersion
}
// Speed up Tests Stage
tasks.withType(Test).configureEach {
// https://docs.gradle.org/current/userguide/performance.html#execute_tests_in_parallel
maxParallelForks = Runtime.runtime.availableProcessors().intdiv(2) ?: 1
// https://docs.gradle.org/current/userguide/performance.html#fork_tests_into_multiple_processes
forkEvery = 100
// https://docs.gradle.org/current/userguide/performance.html#disable_reports
reports.html.required = false
reports.junitXml.required = false
}
// Speed up Java Compile Stage
// https://docs.gradle.org/current/userguide/performance.html#run_the_compiler_as_a_separate_process
tasks.withType(JavaCompile).configureEach {
options.fork = true
}
}
}
}
}
apply plugin: "com.facebook.react.rootproject"
allprojects {
beforeEvaluate {
if (System.env.STATUS_GO_ANDROID_LIBDIR == null || System.env.STATUS_GO_ANDROID_LIBDIR == "") {
+11 -12
View File
@@ -21,14 +21,15 @@
# $keytool -genkey -v -keystore ./status-keystore.jks -keyalg RSA -keysize 2048 -validity 10000 -alias status
# Version requirements used throughout the Gradle scripts
kotlinVersion=1.7.22
minSdkVersion=24
compileSdkVersion=34
targetSdkVersion=34
buildToolsVersion=34.0.0
compileSdkVersion=33
targetSdkVersion=33
buildToolsVersion=33.0.0
supportLibVersion=28.0.0
# This should match version from nix/pkgs/aapt2/default.nix
gradlePluginVersion=7.4.2
kotlinPluginVersion=1.9.0
kotlinPluginVersion=1.7.22
android.useAndroidX=true
android.enableJetifier=true
@@ -38,12 +39,12 @@ KEYSTORE_PASSWORD=password
KEYSTORE_ALIAS=status
KEYSTORE_KEY_PASSWORD=password
# Splitting by CPU Architecture produces smaller APKs.
ANDROID_ABI_SPLIT=true
# By default its better to only build apk for most recent devices.
ANDROID_ABI_INCLUDE=arm64-v8a
# By default we build a mostly universal APK
ANDROID_ABI_SPLIT=false
# Some platforms are excluded though
ANDROID_ABI_INCLUDE=armeabi-v7a;arm64-v8a;x86;x86_64
org.gradle.jvmargs=-Xmx8704M -XX:+UseParallelGC
org.gradle.jvmargs=-Xmx8704M
versionCode=9999
commitHash=unknown
@@ -57,6 +58,4 @@ newArchEnabled=false
# Use this property to enable or disable the Hermes JS engine.
# If set to false, you will be using JSC instead.
# Disabled for debug builds to avoid 'maximum call stack exceeded' errors.
# https://github.com/status-im/status-mobile/issues/18493
hermesEnabled=false
hermesEnabled=true
+16 -1
View File
@@ -1,4 +1,19 @@
module.exports = {
presets: ['module:@react-native/babel-preset'],
presets: ['module:metro-react-native-babel-preset'],
plugins: ['react-native-reanimated/plugin', '@babel/plugin-transform-named-capturing-groups-regex'],
env: {
test: {
presets: [
'@babel/preset-react',
[
'@babel/preset-env',
{
targets: {
node: 'current',
},
},
],
],
},
},
};
+13 -9
View File
@@ -1,11 +1,11 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.8'
library 'status-jenkins-lib@v1.8.4'
/* Options section can't access functions in objects. */
def isPRBuild = utils.isPRBuild()
pipeline {
agent { label 'linux && x86_64 && nix-2.19' }
agent { label 'linux && x86_64 && nix-2.14' }
options {
timestamps()
@@ -15,7 +15,7 @@ pipeline {
buildDiscarder(logRotator(
numToKeepStr: '10',
daysToKeepStr: '20',
artifactNumToKeepStr: '1',
artifactNumToKeepStr: '10',
))
/* Allows combined build to copy */
copyArtifactPermission('/status-mobile/*')
@@ -34,10 +34,10 @@ pipeline {
}
environment {
LANG = 'en_US.UTF-8'
LC_ALL = 'en_US.UTF-8'
LANGUAGE = 'en_US.UTF-8'
PLATFORM = "android${utils.isE2EBuild() ? "-e2e" : ""}"
LANG = "en_US.UTF-8"
LC_ALL = "en_US.UTF-8"
LANGUAGE = "en_US.UTF-8"
TARGET = "android${utils.isE2EBuild() ? "-e2e" : ""}"
BUILD_ENV = 'prod'
NIX_CONF_DIR = "${env.WORKSPACE}/nix"
FASTLANE_DISABLE_COLORS = 1
@@ -71,8 +71,12 @@ pipeline {
}
stage('Upload') {
steps { script {
def urls = apks.collect { s5cmd.upload(it) }
env.PKG_URL = urls.first()
def urls = apks.collect { s3.uploadArtifact(it) }
if (urls.size() > 1) { /* Return only the universal APK. */
env.PKG_URL = urls.find { it.contains('universal') }
} else { /* If no universal is available pick first. */
env.PKG_URL = urls.first()
}
jenkins.setBuildDesc(APK: env.PKG_URL)
} }
}
+10 -27
View File
@@ -1,7 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.8'
import groovy.json.JsonBuilder
library 'status-jenkins-lib@v1.8.4'
pipeline {
agent { label 'linux' }
@@ -15,7 +13,7 @@ pipeline {
buildDiscarder(logRotator(
numToKeepStr: '10',
daysToKeepStr: '30',
artifactNumToKeepStr: '1',
artifactNumToKeepStr: '10',
))
}
@@ -37,6 +35,8 @@ pipeline {
stage('Prep') {
steps { script {
println("Current JOB: ${env.JOB_NAME}")
/* just for a shorter access */
btype = utils.getBuildType()
} }
}
stage('Build') {
@@ -74,7 +74,7 @@ pipeline {
iOS: utils.pkgUrl(ios),
Diawi: utils.getEnv(ios, 'DIAWI_URL'),
/* upload the sha256 checksums file too */
SHA: s5cmd.upload(sha),
SHA: s3.uploadArtifact(sha),
]
/* add URLs to the build description */
jenkins.setBuildDesc(urls)
@@ -83,9 +83,11 @@ pipeline {
stage('Publish') {
when { expression { params.PUBLISH } }
steps { script {
switch (utils.getBuildType()) {
case 'nightly': /* Create JSON file with newest build URLs */
updateBucketJSON(urls, 'latest.json');
switch (btype) {
case 'nightly':
/* Create JSON file with newest build URLs */
s3.updateBucketJSON(urls, 'latest.json');
build(job: 'website/status.im', wait: false);
break;
case 'release':
github.publishReleaseFiles(repo: 'status-mobile');
@@ -116,22 +118,3 @@ def Boolean getPublishDefault(Boolean previousValue) {
if (previousValue != null) { return previousValue }
return false
}
/* Helper for updating JSON with newest builds. */
def updateBucketJSON(urls, fileName) {
/* latest.json has slightly different key names */
def content = [
DIAWI: urls.Diawi,
APK: urls.Apk, IOS: urls.iOS,
APP: urls.App, MAC: urls.Mac,
WIN: urls.Win, SHA: urls.SHA
]
def filePath = "${pwd()}/pkg/${fileName}"
/* it might not exist */
sh "mkdir -p ${pwd()}/pkg"
def contentJson = new JsonBuilder(content).toPrettyString()
println "${filePath}:\n${contentJson}"
writeFile(file: filePath, text: contentJson)
return s5cmd.upload(filePath)
}
+3 -4
View File
@@ -1,12 +1,12 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.8'
library 'status-jenkins-lib@v1.8.4'
pipeline {
agent { label 'linux' }
triggers {
// Nightly at 0am
cron 'H 0 * * *'
// Nightly at 2am
cron 'H 2 * * *'
}
parameters {
@@ -23,7 +23,6 @@ pipeline {
buildDiscarder(logRotator(
numToKeepStr: '10',
daysToKeepStr: '30',
artifactNumToKeepStr: '1',
))
}
+10 -8
View File
@@ -1,11 +1,11 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.8'
library 'status-jenkins-lib@v1.8.4'
/* Options section can't access functions in objects. */
def isPRBuild = utils.isPRBuild()
pipeline {
agent { label 'macos && arm64 && nix-2.19 && xcode-15.1' }
agent { label 'macos && arm64 && nix-2.14 && xcode-14.3' }
parameters {
string(
@@ -23,7 +23,7 @@ pipeline {
buildDiscarder(logRotator(
numToKeepStr: '10',
daysToKeepStr: '20',
artifactNumToKeepStr: '1',
artifactNumToKeepStr: '10',
))
/* Allows combined build to copy */
copyArtifactPermission('/status-mobile/*')
@@ -34,11 +34,13 @@ pipeline {
}
environment {
LANG = 'en_US.UTF-8'
LC_ALL = 'en_US.UTF-8'
LANGUAGE = 'en_US.UTF-8'
PLATFORM = 'ios'
LANG = "en_US.UTF-8"
LC_ALL = "en_US.UTF-8"
LANGUAGE = "en_US.UTF-8"
TARGET = 'ios'
NIX_CONF_DIR = "${env.WORKSPACE}/nix"
/* See nix/README.md */
NIX_IGNORE_SYMLINK_STORE = 1
FASTLANE_DISABLE_COLORS = 1
BUNDLE_PATH = "${HOME}/.bundle"
}
@@ -63,7 +65,7 @@ pipeline {
}
post {
failure {
archiveArtifacts 'logs/*'
archiveArtifacts 'ios/logs/*'
}
}
}
+29 -38
View File
@@ -1,21 +1,21 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.8'
library 'status-jenkins-lib@v1.8.4'
/* Options section can't access functions in objects. */
def isPRBuild = utils.isPRBuild()
pipeline {
agent { label 'linux && x86_64 && nix-2.19' }
agent { label 'linux && x86_64 && nix-2.14' }
options {
timestamps()
/* Prevent Jenkins jobs from running forever */
timeout(time: 20, unit: 'MINUTES')
timeout(time: 15, unit: 'MINUTES')
/* Limit builds retained */
buildDiscarder(logRotator(
numToKeepStr: '10',
daysToKeepStr: '20',
artifactNumToKeepStr: '1',
artifactNumToKeepStr: '10',
))
/* Abort old PR builds. */
disableConcurrentBuilds(
@@ -29,53 +29,51 @@ pipeline {
description: 'Specify build type. Values: pr / e2e / nightly / release',
defaultValue: 'pr',
)
booleanParam(
name: 'RUN_CONTRACT_TESTS',
description: 'Whether to run optional and slow contract tests.',
defaultValue: false,
)
}
environment {
LANG = 'en_US.UTF-8'
LC_ALL = 'en_US.UTF-8'
LANGUAGE = 'en_US.UTF-8'
PLATFORM = 'tests'
LANG = "en_US.UTF-8"
LC_ALL = "en_US.UTF-8"
LANGUAGE = "en_US.UTF-8"
TARGET = 'tests'
BUILD_ENV = 'prod'
NIX_CONF_DIR = "${env.WORKSPACE}/nix"
LOG_FILE = utils.pkgFilename(ext: 'log', arch: 'tests')
CLJ_LINTER_PRINT_WARNINGS = 'true'
}
stages {
stage('Test') {
stage('Checks') {
parallel {
stage('Lint') {
steps { make('lint') }
steps {
sh """#!/bin/bash
set -eo pipefail
make lint CLJ_LINTER_PRINT_WARNINGS=true 2>&1 | tee ${LOG_FILE}
"""
}
}
stage('Unit') {
steps { make('test-unit') }
}
stage('Component') {
steps { make('test-component') }
stage('Tests') {
steps {
sh """#!/bin/bash
set -eo pipefail
make test 2>&1 | tee -a ${LOG_FILE}
"""
}
}
}
}
stage('Heavy Test') {
parallel {
stage('Contract') {
when { expression { params.RUN_CONTRACT_TESTS } }
steps { make('test-contract') }
}
stage('Integration') {
steps { make('test-integration') }
}
stage('Component Tests') {
steps {
sh """#!/bin/bash
set -eo pipefail
make component-test 2>&1 | tee -a ${LOG_FILE}
"""
}
}
stage('Upload') {
steps {
script {
env.PKG_URL = s5cmd.upload(LOG_FILE)
env.PKG_URL = s3.uploadArtifact(LOG_FILE)
}
}
}
@@ -86,10 +84,3 @@ pipeline {
always { sh 'make purge' }
}
}
def make(target) {
sh """#!/bin/bash
set -eo pipefail
make ${target} 2>&1 | tee -a ${LOG_FILE}
"""
}
+3 -15
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.8'
library 'status-jenkins-lib@v1.7.15'
pipeline {
@@ -29,17 +29,6 @@ pipeline {
options {
disableConcurrentBuilds()
buildDiscarder(logRotator(
numToKeepStr: '10',
daysToKeepStr: '30',
artifactNumToKeepStr: '1',
))
}
environment {
/* Avoid race conditions with other builds using virtualenv. */
VIRTUAL_ENV = "${WORKSPACE_TMP}/venv"
PATH = "${VIRTUAL_ENV}/bin:${PATH}"
}
stages {
@@ -58,8 +47,7 @@ pipeline {
stage('Setup') {
steps { script {
dir('test/appium') {
sh "python3 -m venv ${VIRTUAL_ENV}"
sh 'pip3 install -r requirements.txt'
sh 'pip3 install --user -r requirements.txt'
}
} }
}
@@ -99,7 +87,7 @@ pipeline {
--rerun_count=2 \
--testrail_report=True \
-m testrail_id \
-m \"nightly\" \
-m \"new_ui_critical or new_ui_medium\" \
-k \"${params.KEYWORD_EXPRESSION}\" \
--apk=${params.APK_URL ?: apk_path}
"""
+5 -15
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.8'
library 'status-jenkins-lib@v1.7.15'
pipeline {
@@ -35,27 +35,18 @@ pipeline {
description: 'OBSOLETE ARGUMENT TO BE REMOVED',
defaultValue: 'DUMMY',
)
/* Commented to use TEST_MARKERS values from job params
string(
name: 'TEST_MARKERS',
description: 'Marker expression for matching tests to run.',
defaultValue: 'smoke',
defaultValue: 'new_ui_critical',
)
*/
}
options {
disableConcurrentBuilds()
timeout(time: 90, unit: 'MINUTES')
buildDiscarder(logRotator(
numToKeepStr: '10',
daysToKeepStr: '30',
artifactNumToKeepStr: '1',
))
}
environment {
/* Avoid race conditions with other builds using virtualenv. */
VIRTUAL_ENV = "${WORKSPACE_TMP}/venv"
PATH = "${VIRTUAL_ENV}/bin:${PATH}"
}
stages {
@@ -83,8 +74,7 @@ pipeline {
stage('Setup') {
steps { script {
dir('test/appium') {
sh "python3 -m venv ${VIRTUAL_ENV}"
sh 'pip3 install -r requirements.txt'
sh 'pip3 install --user -r requirements.txt'
}
} }
}
+2 -13
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.8'
library 'status-jenkins-lib@v1.7.15'
pipeline {
@@ -28,18 +28,8 @@ pipeline {
options {
disableConcurrentBuilds()
buildDiscarder(logRotator(
numToKeepStr: '10',
daysToKeepStr: '30',
artifactNumToKeepStr: '1',
))
}
environment {
/* Avoid race conditions with other builds using virtualenv. */
VIRTUAL_ENV = "${WORKSPACE_TMP}/venv"
PATH = "${VIRTUAL_ENV}/bin:${PATH}"
}
stages {
stage('Prep') {
@@ -56,8 +46,7 @@ pipeline {
stage('Setup') {
steps { script {
dir('test/appium') {
sh "python3 -m venv ${VIRTUAL_ENV}"
sh 'pip3 install -r requirements.txt'
sh 'pip3 install --user -r requirements.txt'
}
} }
}
+7 -5
View File
@@ -1,15 +1,17 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.8'
library 'status-jenkins-lib@v1.7.15'
pipeline {
agent { label 'macos' }
environment {
LANG = 'en_US.UTF-8'
LANGUAGE = 'en_US.UTF-8'
LC_ALL = 'en_US.UTF-8'
PLATFORM = 'ios'
LANG = 'en_US.UTF-8'
LANGUAGE = 'en_US.UTF-8'
LC_ALL = 'en_US.UTF-8'
TARGET = 'ios'
FASTLANE_DISABLE_COLORS = 1
/* See nix/README.md */
NIX_IGNORE_SYMLINK_STORE = 1
/* avoid writing to r/o /nix */
GEM_HOME = '~/.rubygems'
}

Some files were not shown because too many files have changed in this diff Show More