From e2f5107ba6c9b6c1b9f5f9bac007cabec61302c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20K=C3=BChrer?= <20903852+christxph@users.noreply.github.com> Date: Wed, 13 Mar 2019 16:49:37 +0100 Subject: [PATCH 1/9] (Android) Get rid of double bangs by using Kotlin view binding Instead of holding a nullable reference to the WebView, we are now accessing the WebView using the view binding utility of Kotlin's Android Extensions. Further reading: https://kotlinlang.org/docs/tutorials/android-plugin.html --- .../org/mozilla/firefoxsend/MainActivity.kt | 57 ++++++++++--------- .../app/src/main/res/layout/activity_main.xml | 2 +- 2 files changed, 31 insertions(+), 28 deletions(-) diff --git a/android/app/src/main/java/org/mozilla/firefoxsend/MainActivity.kt b/android/app/src/main/java/org/mozilla/firefoxsend/MainActivity.kt index 257b326f4..8dca385ef 100644 --- a/android/app/src/main/java/org/mozilla/firefoxsend/MainActivity.kt +++ b/android/app/src/main/java/org/mozilla/firefoxsend/MainActivity.kt @@ -1,6 +1,5 @@ package org.mozilla.firefoxsend - import android.support.v7.app.AppCompatActivity import android.os.Bundle import im.delight.android.webview.AdvancedWebView @@ -17,6 +16,7 @@ import android.view.View import android.webkit.ConsoleMessage import android.webkit.JavascriptInterface import android.webkit.WebChromeClient +import kotlinx.android.synthetic.main.activity_main.* import mozilla.components.service.fxa.Config import mozilla.components.service.fxa.FirefoxAccount import mozilla.components.service.fxa.Profile @@ -43,7 +43,7 @@ class WebAppInterface(private val mContext: MainActivity) { } class MainActivity : AppCompatActivity(), AdvancedWebView.Listener { - private var mWebView: AdvancedWebView? = null + private var mToShare: String? = null private var mToCall: String? = null private var mAccount: FirefoxAccount? = null @@ -55,20 +55,21 @@ class MainActivity : AppCompatActivity(), AdvancedWebView.Listener { // https://developers.google.com/web/tools/chrome-devtools/remote-debugging/webviews // WebView.setWebContentsDebuggingEnabled(true); // TODO only dev builds - mWebView = findViewById(R.id.webview) as AdvancedWebView - mWebView!!.setListener(this, this) - mWebView!!.setWebChromeClient(LoggingWebChromeClient()) - mWebView!!.addJavascriptInterface(WebAppInterface(this), "Android") - mWebView!!.setLayerType(View.LAYER_TYPE_HARDWARE, null); + webView.apply { + setListener(this@MainActivity, this@MainActivity) + addJavascriptInterface(WebAppInterface(this@MainActivity), JS_INTERFACE_NAME) + setLayerType(View.LAYER_TYPE_HARDWARE, null) + webChromeClient = LoggingWebChromeClient() - val webSettings = mWebView!!.getSettings() - webSettings.setUserAgentString("Send Android") - webSettings.setAllowUniversalAccessFromFileURLs(true) - webSettings.setJavaScriptEnabled(true) + settings.apply { + userAgentString = "Send Android" + allowUniversalAccessFromFileURLs = true + javaScriptEnabled = true + } + } - val intent = getIntent() - val action = intent.getAction() - val type = intent.getType() + val action = intent.action + val type = intent.type if (Intent.ACTION_SEND.equals(action) && type != null) { if (type.equals("text/plain")) { @@ -81,8 +82,7 @@ class MainActivity : AppCompatActivity(), AdvancedWebView.Listener { mToShare = "data:text/plain;base64," + Base64.encodeToString(imageUri.path.toByteArray(), 16).trim() } } - mWebView!!.loadUrl("file:///android_asset/android.html") - + webView.loadUrl("file:///android_asset/android.html") } fun beginOAuthFlow() { @@ -91,7 +91,7 @@ class MainActivity : AppCompatActivity(), AdvancedWebView.Listener { mAccount?.beginOAuthFlow(arrayOf("profile", "https://identity.mozilla.com/apps/send"), true)?.then(fun (url: String): FxaResult { Log.w("CONFIG", "GOT A URL " + url) this@MainActivity.runOnUiThread({ - mWebView!!.loadUrl(url) + webView.loadUrl(url) }) return FxaResult.fromValue(Unit) }) @@ -113,31 +113,31 @@ class MainActivity : AppCompatActivity(), AdvancedWebView.Listener { @SuppressLint("NewApi") override fun onResume() { super.onResume() - mWebView!!.onResume() + webView.onResume() // ... } @SuppressLint("NewApi") override fun onPause() { - mWebView!!.onPause() + webView.onPause() // ... super.onPause() } override fun onDestroy() { - mWebView!!.onDestroy() + webView.onDestroy() // ... super.onDestroy() } override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) { super.onActivityResult(requestCode, resultCode, intent) - mWebView!!.onActivityResult(requestCode, resultCode, intent) + webView.onActivityResult(requestCode, resultCode, intent) // ... } override fun onBackPressed() { - if (!mWebView!!.onBackPressed()) { + if (!webView.onBackPressed()) { return } // ... @@ -147,7 +147,7 @@ class MainActivity : AppCompatActivity(), AdvancedWebView.Listener { override fun onPageStarted(url: String, favicon: Bitmap?) { if (url.startsWith("https://send.firefox.com/fxa/android-redirect.html")) { // We load this here so the user doesn't see the android-redirect.html page - mWebView!!.loadUrl("file:///android_asset/android.html") + webView.loadUrl("file:///android_asset/android.html") val parsed = Uri.parse(url) val code = parsed.getQueryParameter("code") @@ -169,11 +169,11 @@ class MainActivity : AppCompatActivity(), AdvancedWebView.Listener { this@MainActivity.runOnUiThread({ // Clear the history so that the user can't use the back button to see broken pages // that were inserted into the history by the login process. - mWebView!!.clearHistory() + webView.clearHistory() // We also reload this here because we need to make sure onPageFinished runs after mToCall has been set. // We can't guarantee that onPageFinished wasn't already called at this point. - mWebView!!.loadUrl("file:///android_asset/android.html") + webView.loadUrl("file:///android_asset/android.html") }) @@ -191,12 +191,12 @@ class MainActivity : AppCompatActivity(), AdvancedWebView.Listener { if (mToShare != null) { Log.w("INTENT", mToShare) - mWebView?.postWebMessage(WebMessage(mToShare), Uri.EMPTY) + webView.postWebMessage(WebMessage(mToShare), Uri.EMPTY) mToShare = null } if (mToCall != null) { this@MainActivity.runOnUiThread({ - mWebView?.evaluateJavascript(mToCall, fun (value: String) { + webView.evaluateJavascript(mToCall, fun (value: String) { mToCall = null }) }) @@ -215,4 +215,7 @@ class MainActivity : AppCompatActivity(), AdvancedWebView.Listener { Log.w("MAIN", "onExternalPageRequest") } + companion object { + private const val JS_INTERFACE_NAME = "Android" + } } diff --git a/android/app/src/main/res/layout/activity_main.xml b/android/app/src/main/res/layout/activity_main.xml index 28f9b7324..4cd251982 100644 --- a/android/app/src/main/res/layout/activity_main.xml +++ b/android/app/src/main/res/layout/activity_main.xml @@ -7,7 +7,7 @@ tools:context=".MainActivity"> \ No newline at end of file From 37ad5f3fc2485a30eede7130a6b96973dd43e87e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20K=C3=BChrer?= <20903852+christxph@users.noreply.github.com> Date: Wed, 13 Mar 2019 16:55:43 +0100 Subject: [PATCH 2/9] (Android) Enable WebView debugging in debug builds This enables debugging the app's WebView using Chrome's DevTools. https://developers.google.com/web/tools/chrome-devtools/remote-debugging/webviews --- .../app/src/main/java/org/mozilla/firefoxsend/MainActivity.kt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/android/app/src/main/java/org/mozilla/firefoxsend/MainActivity.kt b/android/app/src/main/java/org/mozilla/firefoxsend/MainActivity.kt index 8dca385ef..168f6c32c 100644 --- a/android/app/src/main/java/org/mozilla/firefoxsend/MainActivity.kt +++ b/android/app/src/main/java/org/mozilla/firefoxsend/MainActivity.kt @@ -52,9 +52,7 @@ class MainActivity : AppCompatActivity(), AdvancedWebView.Listener { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) - // https://developers.google.com/web/tools/chrome-devtools/remote-debugging/webviews - // WebView.setWebContentsDebuggingEnabled(true); // TODO only dev builds - + WebView.setWebContentsDebuggingEnabled(BuildConfig.DEBUG) webView.apply { setListener(this@MainActivity, this@MainActivity) addJavascriptInterface(WebAppInterface(this@MainActivity), JS_INTERFACE_NAME) From 43df875a5031dca1f5ba004f259e560bb825c7a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20K=C3=BChrer?= <20903852+christxph@users.noreply.github.com> Date: Wed, 13 Mar 2019 22:56:53 +0100 Subject: [PATCH 3/9] (Android) Make MainActivity.kt adhere to common Kotlin conventions --- .../org/mozilla/firefoxsend/MainActivity.kt | 125 +++++++++--------- 1 file changed, 63 insertions(+), 62 deletions(-) diff --git a/android/app/src/main/java/org/mozilla/firefoxsend/MainActivity.kt b/android/app/src/main/java/org/mozilla/firefoxsend/MainActivity.kt index 168f6c32c..17bbfa42e 100644 --- a/android/app/src/main/java/org/mozilla/firefoxsend/MainActivity.kt +++ b/android/app/src/main/java/org/mozilla/firefoxsend/MainActivity.kt @@ -1,39 +1,38 @@ package org.mozilla.firefoxsend -import android.support.v7.app.AppCompatActivity -import android.os.Bundle -import im.delight.android.webview.AdvancedWebView -import android.graphics.Bitmap -import android.content.Intent -import android.annotation.SuppressLint import android.content.ComponentName +import android.content.Intent +import android.graphics.Bitmap import android.net.Uri -import android.webkit.WebView -import android.webkit.WebMessage -import android.util.Log +import android.os.Bundle +import android.support.v7.app.AppCompatActivity import android.util.Base64 +import android.util.Log import android.view.View -import android.webkit.ConsoleMessage -import android.webkit.JavascriptInterface -import android.webkit.WebChromeClient +import android.webkit.* +import im.delight.android.webview.AdvancedWebView import kotlinx.android.synthetic.main.activity_main.* import mozilla.components.service.fxa.Config import mozilla.components.service.fxa.FirefoxAccount -import mozilla.components.service.fxa.Profile import mozilla.components.service.fxa.FxaResult +import mozilla.components.service.fxa.Profile internal class LoggingWebChromeClient : WebChromeClient() { override fun onConsoleMessage(cm: ConsoleMessage): Boolean { - Log.w("CONTENT", String.format("%s @ %d: %s", + Log.d(TAG, String.format("%s @ %d: %s", cm.message(), cm.lineNumber(), cm.sourceId())) return true } + + companion object { + private const val TAG = "CONTENT" + } } class WebAppInterface(private val mContext: MainActivity) { @JavascriptInterface fun beginOAuthFlow() { - mContext.beginOAuthFlow(); + mContext.beginOAuthFlow() } @JavascriptInterface @@ -69,14 +68,14 @@ class MainActivity : AppCompatActivity(), AdvancedWebView.Listener { val action = intent.action val type = intent.type - if (Intent.ACTION_SEND.equals(action) && type != null) { - if (type.equals("text/plain")) { + if (Intent.ACTION_SEND == action && type != null) { + if (type == "text/plain") { val sharedText = intent.getStringExtra(Intent.EXTRA_TEXT) - Log.w("INTENT", "text/plain " + sharedText) + Log.d(TAG_INTENT, "text/plain " + sharedText) mToShare = "data:text/plain;base64," + Base64.encodeToString(sharedText.toByteArray(), 16).trim() } else if (type.startsWith("image/")) { val imageUri = intent.getParcelableExtra(Intent.EXTRA_STREAM) as Uri - Log.w("INTENT", "image/ " + imageUri) + Log.d(TAG_INTENT, "image/ " + imageUri) mToShare = "data:text/plain;base64," + Base64.encodeToString(imageUri.path.toByteArray(), 16).trim() } } @@ -84,61 +83,58 @@ class MainActivity : AppCompatActivity(), AdvancedWebView.Listener { } fun beginOAuthFlow() { - Config.release().then(fun (value: Config): FxaResult { + Config.release().then { value -> mAccount = FirefoxAccount(value, "20f7931c9054d833", "https://send.firefox.com/fxa/android-redirect.html") - mAccount?.beginOAuthFlow(arrayOf("profile", "https://identity.mozilla.com/apps/send"), true)?.then(fun (url: String): FxaResult { - Log.w("CONFIG", "GOT A URL " + url) - this@MainActivity.runOnUiThread({ - webView.loadUrl(url) - }) - return FxaResult.fromValue(Unit) - }) - Log.w("CONFIG", "CREATED FIREFOXACCOUNT") - return FxaResult.fromValue(Unit) - }) + mAccount?.beginOAuthFlow(arrayOf("profile", "https://identity.mozilla.com/apps/send"), true) + ?.then { url -> + Log.d(TAG_CONFIG, "GOT A URL " + url) + this@MainActivity.runOnUiThread { + webView.loadUrl(url) + } + FxaResult.fromValue(Unit) + } + Log.d(TAG_CONFIG, "CREATED FIREFOXACCOUNT") + FxaResult.fromValue(Unit) + } } fun shareUrl(url: String) { - val shareIntent = Intent() - shareIntent.action = Intent.ACTION_SEND - shareIntent.type = "text/plain" - shareIntent.putExtra(Intent.EXTRA_TEXT, url) + val shareIntent = Intent().apply { + action = Intent.ACTION_SEND + type = "text/plain" + putExtra(Intent.EXTRA_TEXT, url) + } + val chooser = Intent.createChooser(shareIntent, "") - chooser.putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS, arrayOf(ComponentName(applicationContext, MainActivity::class.java))) + .putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS, arrayOf(ComponentName(applicationContext, MainActivity::class.java))) + startActivity(chooser) } - @SuppressLint("NewApi") override fun onResume() { super.onResume() webView.onResume() - // ... } - @SuppressLint("NewApi") override fun onPause() { webView.onPause() - // ... super.onPause() } override fun onDestroy() { webView.onDestroy() - // ... super.onDestroy() } override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) { super.onActivityResult(requestCode, resultCode, intent) webView.onActivityResult(requestCode, resultCode, intent) - // ... } override fun onBackPressed() { if (!webView.onBackPressed()) { return } - // ... super.onBackPressed() } @@ -148,11 +144,8 @@ class MainActivity : AppCompatActivity(), AdvancedWebView.Listener { webView.loadUrl("file:///android_asset/android.html") val parsed = Uri.parse(url) - val code = parsed.getQueryParameter("code") - val state = parsed.getQueryParameter("state") - - code?.let { code -> - state?.let { state -> + parsed.getQueryParameter("code")?.let { code -> + parsed.getQueryParameter("state")?.let { state -> mAccount?.completeOAuthFlow(code, state)?.whenComplete { info -> //displayAndPersistProfile(code, state) val profile = mAccount?.getProfile(false)?.then(fun (profile: Profile): FxaResult { @@ -162,9 +155,9 @@ class MainActivity : AppCompatActivity(), AdvancedWebView.Listener { val displayName = profile.displayName val email = profile.email val uid = profile.uid - val toPass = "{\"accessToken\": \"${accessToken}\", \"keys\": '${keys}', \"avatar\": \"${avatar}\", \"displayName\": \"${displayName}\", \"email\": \"${email}\", \"uid\": \"${uid}\"}" - mToCall = "finishLogin(${toPass})" - this@MainActivity.runOnUiThread({ + val toPass = "{\"accessToken\": \"$accessToken\", \"keys\": '$keys', \"avatar\": \"$avatar\", \"displayName\": \"$displayName\", \"email\": \"$email\", \"uid\": \"$uid\"}" + mToCall = "finishLogin($toPass)" + this@MainActivity.runOnUiThread { // Clear the history so that the user can't use the back button to see broken pages // that were inserted into the history by the login process. webView.clearHistory() @@ -172,7 +165,7 @@ class MainActivity : AppCompatActivity(), AdvancedWebView.Listener { // We also reload this here because we need to make sure onPageFinished runs after mToCall has been set. // We can't guarantee that onPageFinished wasn't already called at this point. webView.loadUrl("file:///android_asset/android.html") - }) + } return FxaResult.fromValue(Unit) @@ -181,39 +174,47 @@ class MainActivity : AppCompatActivity(), AdvancedWebView.Listener { } } } - Log.w("MAIN", "onPageStarted"); + Log.d(TAG_MAIN, "onPageStarted") } override fun onPageFinished(url: String) { - Log.w("MAIN", "onPageFinished") + Log.d(TAG_MAIN, "onPageFinished") if (mToShare != null) { - Log.w("INTENT", mToShare) + Log.d(TAG_INTENT, mToShare) webView.postWebMessage(WebMessage(mToShare), Uri.EMPTY) mToShare = null } if (mToCall != null) { - this@MainActivity.runOnUiThread({ - webView.evaluateJavascript(mToCall, fun (value: String) { + this@MainActivity.runOnUiThread { + webView.evaluateJavascript(mToCall) { mToCall = null - }) - }) + } + } } } override fun onPageError(errorCode: Int, description: String, failingUrl: String) { - Log.w("MAIN", "onPageError " + description) + Log.d(TAG_MAIN, "onPageError($errorCode, $description, $failingUrl)") } - override fun onDownloadRequested(url: String, suggestedFilename: String, mimeType: String, contentLength: Long, contentDisposition: String, userAgent: String) { - Log.w("MAIN", "onDownloadRequested") + override fun onDownloadRequested(url: String, + suggestedFilename: String, + mimeType: String, + contentLength: Long, + contentDisposition: String, + userAgent: String) { + Log.d(TAG_MAIN, "onDownloadRequested") } override fun onExternalPageRequest(url: String) { - Log.w("MAIN", "onExternalPageRequest") + Log.d(TAG_MAIN, "onExternalPageRequest($url)") } companion object { + private const val TAG_MAIN = "MAIN" + private const val TAG_INTENT = "INTENT" + private const val TAG_CONFIG = "CONFIG" private const val JS_INTERFACE_NAME = "Android" } } From 99cb95e7f6f38e7b0ad2aad16c1b2cfa63625eb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20K=C3=BChrer?= <20903852+christxph@users.noreply.github.com> Date: Wed, 13 Mar 2019 22:59:10 +0100 Subject: [PATCH 4/9] (Android) Update dependencies and improve formatting of Gradle files This updates the Kotlin plugin to 1.3.21 and the Gradle plugin to 3.3.2 --- android/app/build.gradle | 4 +--- android/build.gradle | 11 +++-------- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 5d27365d5..471a3a213 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -1,7 +1,5 @@ apply plugin: 'com.android.application' - apply plugin: 'kotlin-android' - apply plugin: 'kotlin-android-extensions' android { @@ -31,7 +29,7 @@ dependencies { androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' implementation 'com.github.delight-im:Android-AdvancedWebView:v3.0.0' - implementation "org.mozilla.components:service-firefox-accounts:${rootProject.ext.android_components_version}" + implementation "org.mozilla.components:service-firefox-accounts:$android_components_version" } task generateAndLinkBundle(type: Exec, description: 'Generate the android.js bundle and link it into the assets directory') { diff --git a/android/build.gradle b/android/build.gradle index a20018c7b..bae18a8dd 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -8,20 +8,15 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:3.3.1' - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.20" - - // NOTE: Do not place your application dependencies here; they belong - // in the individual module build.gradle files + classpath 'com.android.tools.build:gradle:3.3.2' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.21" } } allprojects { repositories { google() - maven { - url "https://maven.mozilla.org/maven2" - } + maven { url "https://maven.mozilla.org/maven2" } jcenter() maven { url "https://jitpack.io" } } From 8b9d41021a1c83248f7cf481ce529cb3680f8dca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20K=C3=BChrer?= <20903852+christxph@users.noreply.github.com> Date: Wed, 13 Mar 2019 22:59:57 +0100 Subject: [PATCH 5/9] (Android) Remove unnecessary ConstraintLayout container Layout files should generally have as few nested layers as possible, because every layer affects the performance. --- android/app/src/main/res/layout/activity_main.xml | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/android/app/src/main/res/layout/activity_main.xml b/android/app/src/main/res/layout/activity_main.xml index 4cd251982..d2b2ba3f8 100644 --- a/android/app/src/main/res/layout/activity_main.xml +++ b/android/app/src/main/res/layout/activity_main.xml @@ -1,13 +1,7 @@ - - - - \ No newline at end of file + tools:context=".MainActivity" /> \ No newline at end of file From ef484e3c9f8662c4f529f1d1b54bc4fc2fe58bfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20K=C3=BChrer?= <20903852+christxph@users.noreply.github.com> Date: Wed, 13 Mar 2019 23:11:01 +0100 Subject: [PATCH 6/9] (Android) Use JSONObject class to construct a JSON string It is way safer to construct a JSON string using classes that are meant for doing that, instead of concatenating raw strings. --- .../org/mozilla/firefoxsend/MainActivity.kt | 33 +++++++++---------- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/android/app/src/main/java/org/mozilla/firefoxsend/MainActivity.kt b/android/app/src/main/java/org/mozilla/firefoxsend/MainActivity.kt index 17bbfa42e..5c11bdf34 100644 --- a/android/app/src/main/java/org/mozilla/firefoxsend/MainActivity.kt +++ b/android/app/src/main/java/org/mozilla/firefoxsend/MainActivity.kt @@ -15,7 +15,7 @@ import kotlinx.android.synthetic.main.activity_main.* import mozilla.components.service.fxa.Config import mozilla.components.service.fxa.FirefoxAccount import mozilla.components.service.fxa.FxaResult -import mozilla.components.service.fxa.Profile +import org.json.JSONObject internal class LoggingWebChromeClient : WebChromeClient() { override fun onConsoleMessage(cm: ConsoleMessage): Boolean { @@ -143,20 +143,19 @@ class MainActivity : AppCompatActivity(), AdvancedWebView.Listener { // We load this here so the user doesn't see the android-redirect.html page webView.loadUrl("file:///android_asset/android.html") - val parsed = Uri.parse(url) - parsed.getQueryParameter("code")?.let { code -> - parsed.getQueryParameter("state")?.let { state -> + val uri = Uri.parse(url) + uri.getQueryParameter("code")?.let { code -> + uri.getQueryParameter("state")?.let { state -> mAccount?.completeOAuthFlow(code, state)?.whenComplete { info -> - //displayAndPersistProfile(code, state) - val profile = mAccount?.getProfile(false)?.then(fun (profile: Profile): FxaResult { - val accessToken = info.accessToken - val keys = info.keys - val avatar = profile.avatar - val displayName = profile.displayName - val email = profile.email - val uid = profile.uid - val toPass = "{\"accessToken\": \"$accessToken\", \"keys\": '$keys', \"avatar\": \"$avatar\", \"displayName\": \"$displayName\", \"email\": \"$email\", \"uid\": \"$uid\"}" - mToCall = "finishLogin($toPass)" + mAccount?.getProfile(false)?.then { profile -> + val profileJsonPayload = JSONObject() + .put("accessToken", info.accessToken) + .put("keys", info.keys) + .put("avatar", profile.avatar) + .put("displayName", profile.displayName) + .put("email", profile.email) + .put("uid", profile.uid).toString() + mToCall = "finishLogin($profileJsonPayload)" this@MainActivity.runOnUiThread { // Clear the history so that the user can't use the back button to see broken pages // that were inserted into the history by the login process. @@ -166,10 +165,8 @@ class MainActivity : AppCompatActivity(), AdvancedWebView.Listener { // We can't guarantee that onPageFinished wasn't already called at this point. webView.loadUrl("file:///android_asset/android.html") } - - - return FxaResult.fromValue(Unit) - }) + FxaResult.fromValue(Unit) + } } } } From 9ace966e5f15d7da64e460a7ef9f48588d6300ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20K=C3=BChrer?= <20903852+christxph@users.noreply.github.com> Date: Wed, 13 Mar 2019 23:16:18 +0100 Subject: [PATCH 7/9] (Android) Suppress JavaScript lint warning --- .../app/src/main/java/org/mozilla/firefoxsend/MainActivity.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/android/app/src/main/java/org/mozilla/firefoxsend/MainActivity.kt b/android/app/src/main/java/org/mozilla/firefoxsend/MainActivity.kt index 5c11bdf34..0f563b95b 100644 --- a/android/app/src/main/java/org/mozilla/firefoxsend/MainActivity.kt +++ b/android/app/src/main/java/org/mozilla/firefoxsend/MainActivity.kt @@ -47,6 +47,7 @@ class MainActivity : AppCompatActivity(), AdvancedWebView.Listener { private var mToCall: String? = null private var mAccount: FirefoxAccount? = null + @SuppressLint("SetJavaScriptEnabled") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) From c97f96edb6a621f1a8aef4c101c8b33422c97df9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20K=C3=BChrer?= <20903852+christxph@users.noreply.github.com> Date: Wed, 13 Mar 2019 23:21:12 +0100 Subject: [PATCH 8/9] (Android) Use Kotlin string templates instead of concatenating strings --- .../java/org/mozilla/firefoxsend/MainActivity.kt | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/android/app/src/main/java/org/mozilla/firefoxsend/MainActivity.kt b/android/app/src/main/java/org/mozilla/firefoxsend/MainActivity.kt index 0f563b95b..9a7a723b1 100644 --- a/android/app/src/main/java/org/mozilla/firefoxsend/MainActivity.kt +++ b/android/app/src/main/java/org/mozilla/firefoxsend/MainActivity.kt @@ -66,17 +66,15 @@ class MainActivity : AppCompatActivity(), AdvancedWebView.Listener { } } - val action = intent.action val type = intent.type - - if (Intent.ACTION_SEND == action && type != null) { + if (Intent.ACTION_SEND == intent.action && type != null) { if (type == "text/plain") { val sharedText = intent.getStringExtra(Intent.EXTRA_TEXT) - Log.d(TAG_INTENT, "text/plain " + sharedText) + Log.d(TAG_INTENT, "text/plain $sharedText") mToShare = "data:text/plain;base64," + Base64.encodeToString(sharedText.toByteArray(), 16).trim() } else if (type.startsWith("image/")) { val imageUri = intent.getParcelableExtra(Intent.EXTRA_STREAM) as Uri - Log.d(TAG_INTENT, "image/ " + imageUri) + Log.d(TAG_INTENT, "image/ $imageUri") mToShare = "data:text/plain;base64," + Base64.encodeToString(imageUri.path.toByteArray(), 16).trim() } } @@ -88,7 +86,7 @@ class MainActivity : AppCompatActivity(), AdvancedWebView.Listener { mAccount = FirefoxAccount(value, "20f7931c9054d833", "https://send.firefox.com/fxa/android-redirect.html") mAccount?.beginOAuthFlow(arrayOf("profile", "https://identity.mozilla.com/apps/send"), true) ?.then { url -> - Log.d(TAG_CONFIG, "GOT A URL " + url) + Log.d(TAG_CONFIG, "GOT A URL $url") this@MainActivity.runOnUiThread { webView.loadUrl(url) } @@ -106,8 +104,9 @@ class MainActivity : AppCompatActivity(), AdvancedWebView.Listener { putExtra(Intent.EXTRA_TEXT, url) } + val components = arrayOf(ComponentName(applicationContext, MainActivity::class.java)) val chooser = Intent.createChooser(shareIntent, "") - .putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS, arrayOf(ComponentName(applicationContext, MainActivity::class.java))) + .putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS, components) startActivity(chooser) } From 4763c5827acc76904c3852d7bb5336c642ad8f32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20K=C3=BChrer?= <20903852+christxph@users.noreply.github.com> Date: Wed, 20 Mar 2019 22:33:06 +0100 Subject: [PATCH 9/9] (Android) Add missing SuppressLint import --- .../app/src/main/java/org/mozilla/firefoxsend/MainActivity.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/android/app/src/main/java/org/mozilla/firefoxsend/MainActivity.kt b/android/app/src/main/java/org/mozilla/firefoxsend/MainActivity.kt index 9a7a723b1..21ed9ea33 100644 --- a/android/app/src/main/java/org/mozilla/firefoxsend/MainActivity.kt +++ b/android/app/src/main/java/org/mozilla/firefoxsend/MainActivity.kt @@ -1,5 +1,6 @@ package org.mozilla.firefoxsend +import android.annotation.SuppressLint import android.content.ComponentName import android.content.Intent import android.graphics.Bitmap