Skip to content
This repository was archived by the owner on Jan 6, 2023. It is now read-only.

Rust client APK build #1310

Merged
merged 17 commits into from
Jul 26, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions native/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,11 @@ dependencies {
// compile "com.android.support:appcompat-v7:23.0.1"
compile "com.android.support:appcompat-v7:25.3.1"
compile "com.facebook.react:react-native:+" // From node_modules
compile "org.mozilla.components:fxa:0.16"
}

repositories {
mavenLocal()
}

// Run this once to be able to run the application with BUCK
Expand Down
6 changes: 6 additions & 0 deletions native/android/app/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,10 @@
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
-dontwarn okio.**

# Firefox accounts component

-dontwarn java.awt.*
-keep class com.sun.jna.* { *; }
-keepclassmembers class * extends com.sun.jna.* { public *; }

-ignorewarnings
1 change: 1 addition & 0 deletions native/android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
android:path="/notes/fxa/android-redirect.html"/>
</intent-filter>
</activity>
<activity android:name="com.notes.FxaLoginActivity"></activity>
</application>

</manifest>
87 changes: 87 additions & 0 deletions native/android/app/src/main/java/com/notes/FxaLoginActivity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package com.notes;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.webkit.CookieManager;
import android.webkit.WebStorage;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.RelativeLayout;

import org.mozilla.testpilot.notes.R;

public class FxaLoginActivity extends AppCompatActivity {

private WebView mWebView;

@SuppressLint("SetJavaScriptEnabled")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fxa_login);
Intent intent = getIntent();
final String authUrl = intent.getStringExtra("authUrl");
final String redirectUrl = intent.getStringExtra("redirectUrl");

RelativeLayout view = (RelativeLayout) findViewById(R.id.webviewLayout);
WebView webView = new WebView(getBaseContext());
view.addView(webView);

webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setDomStorageEnabled(true);
CookieManager.getInstance().setAcceptCookie(true);
WebStorage.getInstance().deleteAllData();

final FxaLoginActivity act = this;

final WebViewClient client = new WebViewClient() {
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
if (url != null && url.startsWith(redirectUrl)) {
Uri uri = Uri.parse(url);
String code = uri.getQueryParameter("code");
String state = uri.getQueryParameter("state");
if (code != null && state != null) {
Intent data = new Intent();
data.putExtra("code", code);
data.putExtra("state", state);
setResult(2, data);

act.finish();
}
}
super.onPageStarted(view, url, favicon);
}
};

webView.setWebViewClient(client);

this.mWebView = webView;
webView.loadUrl(authUrl);
}

@Override
protected void onPause() {
mWebView.onPause();
super.onPause();
}

@Override
protected void onResume() {
mWebView.onResume();
super.onResume();
}

@Override
public void onBackPressed() {
if (mWebView.canGoBack()) {
mWebView.goBack();
} else {
super.onBackPressed();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import io.sentry.RNSentryPackage;

import com.notes.advancedwebview.AdvancedWebviewPackage;
import com.notes.fxaclient.FxaClientPackage;
import com.oblador.vectoricons.VectorIconsPackage;
import com.oblador.keychain.KeychainPackage;
import com.bitgo.randombytes.RandomBytesPackage;
Expand Down Expand Up @@ -39,7 +40,8 @@ protected List<ReactPackage> getPackages() {
new KeychainPackage(),
new RandomBytesPackage(),
new RNAppAuthPackage(),
new AdvancedWebviewPackage()
new AdvancedWebviewPackage(),
new FxaClientPackage()
);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
package com.notes.fxaclient;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.text.TextUtils;

import com.facebook.react.bridge.ActivityEventListener;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.notes.FxaLoginActivity;

import org.json.JSONException;
import org.json.JSONObject;

import mozilla.components.service.fxa.Config;
import mozilla.components.service.fxa.FirefoxAccount;
import mozilla.components.service.fxa.FxaResult;
import mozilla.components.service.fxa.OAuthInfo;
import mozilla.components.service.fxa.Profile;


public class FxaClientModule extends ReactContextBaseJavaModule implements ActivityEventListener {

private static final String CLIENT_ID = "7f368c6886429f19";
private static final String REDIRECT_URL = "https://mozilla.github.io/notes/fxa/android-redirect.html";
private static final String CONFIG_URL = "https://accounts.firefox.com";

private static final String[] scopes = new String[]{ "profile", "https://identity.mozilla.com/apps/notes" };
private static final Boolean wantsKeys = true;
private FirefoxAccount account;

public static final String REACT_CLASS = "FxaClient";
public ReactContext REACT_CONTEXT;

private Callback successCallback;
private Callback errorCallback;

@Override
public String getName(){
return REACT_CLASS;
}

@SuppressWarnings("unused")
public Activity getActivity() {
return getCurrentActivity();
}

public ReactContext getReactContext(){
return REACT_CONTEXT;
}

public FxaClientModule(ReactApplicationContext reactContext) {
super(reactContext);
REACT_CONTEXT = reactContext;
reactContext.addActivityEventListener(this);
}

@ReactMethod
public void begin(final Callback successCallback,
final Callback errorCallback) {
this.successCallback = successCallback;
this.errorCallback = errorCallback;
final Context context = getReactApplicationContext();
final Intent intent = new Intent(context, FxaLoginActivity.class);

Config.Companion.custom(CONFIG_URL).then(new FxaResult.OnValueListener<Config, String>() {
public FxaResult<String> onValue(Config config) {
account = new FirefoxAccount(config, CLIENT_ID, REDIRECT_URL);
return account.beginOAuthFlow(scopes, wantsKeys);
}
}, new FxaResult.OnExceptionListener<String>() {
public FxaResult<String> onException(Exception e) {
errorCallback.invoke();
return null;
}
}).then(new FxaResult.OnValueListener<String, Void>() {
public FxaResult<Void> onValue(String authUrl) {
intent.putExtra("authUrl", authUrl);
intent.putExtra("redirectUrl", REDIRECT_URL);
try {
getCurrentActivity().startActivityForResult(intent, 2);
} catch (Exception e) {
errorCallback.invoke();
}
return null;
}
}, new FxaResult.OnExceptionListener<Void>() {
public FxaResult<Void> onException(Exception e) {
errorCallback.invoke();
return null;
}
});
}

@Override
public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
if (data == null) {
errorCallback.invoke();
return;
}

final JSONObject loginDetails = new JSONObject();
final JSONObject oauthResponse = new JSONObject();

String code = data.getStringExtra("code");
String state = data.getStringExtra("state");

account.completeOAuthFlow(code, state).then(new FxaResult.OnValueListener<OAuthInfo, Profile>() {
public FxaResult<Profile> onValue(OAuthInfo oAuthInfo) {
return account.getProfile();
}
}, new FxaResult.OnExceptionListener<Profile>() {
public FxaResult<Profile> onException(Exception e) {
errorCallback.invoke();
return null;
}
}).then(new FxaResult.OnValueListener<Profile, Void>() {
public FxaResult<Void> onValue(Profile profile) {
try {
JSONObject accountObject = new JSONObject(account.toJSONString())
.getJSONObject("oauth_cache")
.getJSONObject(TextUtils.join(" ", scopes));
oauthResponse.put("accessToken", accountObject.getString("access_token"));
oauthResponse.put("refreshToken", accountObject.getString("refresh_token"));
loginDetails.put("oauthResponse", oauthResponse);
loginDetails.put("keys", new JSONObject(accountObject.getString("keys")));
} catch (JSONException e) {
e.printStackTrace();
}

successCallback.invoke(loginDetails.toString());
return null;
}
}, new FxaResult.OnExceptionListener<Void>() {
public FxaResult<Void> onException(Exception e) {
errorCallback.invoke();
return null;
}
});
}

@Override
public void onNewIntent(Intent intent) {

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.notes.fxaclient;

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class FxaClientPackage implements ReactPackage {

@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}

@Override
public List<NativeModule> createNativeModules(
ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();

modules.add(new FxaClientModule(reactContext));

return modules;
}

}
9 changes: 9 additions & 0 deletions native/android/app/src/main/res/layout/activity_fxa_login.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/webviewLayout"
tools:context="com.notes.FxaLoginActivity">

</RelativeLayout>
5 changes: 5 additions & 0 deletions native/app/components/FxaClient.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/**
* This exposes the native Firefox Accounts component module as a JS module.
*/
import {NativeModules} from 'react-native';
module.exports = NativeModules.FxaClient;
Loading