diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ba98acaf..285c216d 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -3,6 +3,9 @@ stages: - deploy - release +variables: + REACT_NATIVE_BRANCH: "master" + build apk: stage: build image: lbry/android-base:platform-28 @@ -14,7 +17,7 @@ build apk: - ln -fs /opt/node-v10.19.0-linux-x64/bin/npx /usr/bin/npx - chmod u+x $CI_PROJECT_DIR/gradlew - export ANDROID_SDK_ROOT=~/.buildozer/android/platform/android-sdk-23 - - export BUILD_VERSION=$($CI_PROJECT_DIR/gradlew -q printVersionName --console=plain | tail -1) + - export BUILD_VERSION=$($CI_PROJECT_DIR/gradlew -q printVersionName --console=plain | tail -1) artifacts: paths: - bin/browser-*-release__arm.apk @@ -31,7 +34,7 @@ build apk: - git secret reveal - npm install -g react-native-cli - cd ~/ - - git clone https://github.com/lbryio/lbry-react-native + - git clone --single-branch --branch $REACT_NATIVE_BRANCH https://github.com/lbryio/lbry-react-native - cd lbry-react-native - chmod u+x bundle-android.sh - yarn @@ -44,7 +47,7 @@ build apk: - cd $CI_PROJECT_DIR - cp bin/browser-$BUILD_VERSION-release__arm.apk /dev/null - cp bin/browser-$BUILD_VERSION-release__arm64.apk /dev/null - + deploy build.lbry.io: image: python:stretch stage: deploy diff --git a/app/src/main/java/io/lbry/browser/LbrynetMessagingService.java b/app/src/main/java/io/lbry/browser/LbrynetMessagingService.java index b43b553e..7b9cd57a 100644 --- a/app/src/main/java/io/lbry/browser/LbrynetMessagingService.java +++ b/app/src/main/java/io/lbry/browser/LbrynetMessagingService.java @@ -18,8 +18,11 @@ import com.google.firebase.analytics.FirebaseAnalytics; import com.google.firebase.messaging.FirebaseMessagingService; import com.google.firebase.messaging.RemoteMessage; +import io.lbry.lbrysdk.LbrynetService; import io.lbry.browser.reactmodules.UtilityModule; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -54,6 +57,12 @@ public class LbrynetMessagingService extends FirebaseMessagingService { String title = payload.get("title"); String body = payload.get("body"); String name = payload.get("name"); // notification name + String contentTitle = payload.get("contentTitle"); + String channelUrl = payload.get("channelUrl"); + String publishTime = payload.get("publishTime"); + for (Map.Entry entry : payload.entrySet()) { + android.util.Log.d("ReactNativeJS", "payload[" + entry.getKey() + "]=" + entry.getValue()); + } if (type != null && getEnabledTypes().indexOf(type) > -1 && body != null && body.trim().length() > 0) { // only log the receive event for valid notifications received if (firebaseAnalytics != null) { @@ -62,7 +71,7 @@ public class LbrynetMessagingService extends FirebaseMessagingService { firebaseAnalytics.logEvent("lbry_notification_receive", bundle); } - sendNotification(title, body, type, url, name); + sendNotification(title, body, type, url, name, contentTitle, channelUrl, publishTime); } } } @@ -94,7 +103,8 @@ public class LbrynetMessagingService extends FirebaseMessagingService { * * @param messageBody FCM message body received. */ - private void sendNotification(String title, String messageBody, String type, String url, String name) { + private void sendNotification(String title, String messageBody, String type, String url, String name, + String contentTitle, String channelUrl, String publishTime) { //Intent intent = new Intent(this, MainActivity.class); //intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); if (url == null) { @@ -104,6 +114,24 @@ public class LbrynetMessagingService extends FirebaseMessagingService { // default to home page url = "lbry://?discover"; } + } else { + if (!MainActivity.isServiceRunning(this, LbrynetService.class)) { + // cold start + url = url + ((url.indexOf("?") > -1) ? "&liteMode=1" : "?liteMode=1"); + try { + if (contentTitle != null) { + url = url + "&contentTitle=" + URLEncoder.encode(contentTitle, "UTF-8"); + } + if (channelUrl != null) { + url = url + "&channelUrl=" + URLEncoder.encode(channelUrl, "UTF-8"); + } + if (publishTime != null) { + url = url + "&publishTime=" + URLEncoder.encode(publishTime, "UTF-8"); + } + } catch (UnsupportedEncodingException ex) { + // shouldn't happen + } + } } Intent launchIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); diff --git a/app/src/main/java/io/lbry/browser/MainActivity.java b/app/src/main/java/io/lbry/browser/MainActivity.java index f60abcb3..917dca52 100644 --- a/app/src/main/java/io/lbry/browser/MainActivity.java +++ b/app/src/main/java/io/lbry/browser/MainActivity.java @@ -2,6 +2,7 @@ package io.lbry.browser; import android.annotation.SuppressLint; import android.annotation.TargetApi; +import android.app.PendingIntent; import android.os.Build; import android.os.Bundle; import android.os.Environment; @@ -153,12 +154,20 @@ public class MainActivity extends FragmentActivity implements DefaultHardwareBac registerDownloadEventReceiver(); // Start the daemon service if it is not started - serviceRunning = isServiceRunning(LbrynetService.class); + serviceRunning = isServiceRunning(this, LbrynetService.class); if (!serviceRunning) { CurrentLaunchTiming.setColdStart(true); ServiceHelper.start(this, "", LbrynetService.class, "lbrynetservice"); } + if (LbrynetService.serviceInstance != null) { + // TODO: Add a broadcast receiver to listen for the service started event, so that we can set this properly + Context context = getApplicationContext(); + Intent contextIntent = new Intent(context, MainActivity.class); + PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, contextIntent, PendingIntent.FLAG_UPDATE_CURRENT); + LbrynetService.serviceInstance.setPendingContextIntent(pendingIntent); + } + checkNotificationOpenIntent(getIntent()); mReactRootView = new RNGestureHandlerEnabledRootView(this); @@ -383,9 +392,9 @@ public class MainActivity extends FragmentActivity implements DefaultHardwareBac switch (requestCode) { case STORAGE_PERMISSION_REQ_CODE: if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { - if (BuildConfig.DEBUG && !Settings.canDrawOverlays(this)) { + if (BuildConfig.DEBUG && Build.VERSION.SDK_INT >= 23 && !Settings.canDrawOverlays(this)) { Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, - Uri.parse("package:" + getPackageName())); + Uri.parse("package:" + getPackageName())); startActivityForResult(intent, OVERLAY_PERMISSION_REQ_CODE); } if (reactContext != null) { @@ -444,37 +453,6 @@ public class MainActivity extends FragmentActivity implements DefaultHardwareBac } } - public static String acquireDeviceId(Context context) { - TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); - String id = null; - try { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - id = telephonyManager.getImei(); // GSM - if (id == null) { - id = telephonyManager.getMeid(); // CDMA - } - } else { - id = telephonyManager.getDeviceId(); - } - } catch (SecurityException ex) { - // Maybe the permission was not granted? Try to acquire permission - checkPhoneStatePermission(context); - } catch (Exception ex) { - // id could not be obtained. Display a warning that rewards cannot be claimed. - } - - if (id == null || id.trim().length() == 0) { - Toast.makeText(context, "Rewards cannot be claimed because we could not identify your device.", Toast.LENGTH_LONG).show(); - } - - SharedPreferences sp = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE); - SharedPreferences.Editor editor = sp.edit(); - editor.putString(DEVICE_ID_KEY, id); - editor.commit(); - - return id; - } - @Override public void invokeDefaultOnBackPressed() { super.onBackPressed(); @@ -494,7 +472,7 @@ public class MainActivity extends FragmentActivity implements DefaultHardwareBac super.onResume(); SharedPreferences sp = getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE); - serviceRunning = isServiceRunning(LbrynetService.class); + serviceRunning = isServiceRunning(this, LbrynetService.class); if (!serviceRunning) { ServiceHelper.start(this, "", LbrynetService.class, "lbrynetservice"); } @@ -510,7 +488,7 @@ public class MainActivity extends FragmentActivity implements DefaultHardwareBac SharedPreferences sp = getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE); boolean shouldKeepDaemonRunning = sp.getBoolean(SETTING_KEEP_DAEMON_RUNNING, true); if (!shouldKeepDaemonRunning) { - serviceRunning = isServiceRunning(LbrynetService.class); + serviceRunning = isServiceRunning(this, LbrynetService.class); if (serviceRunning) { ServiceHelper.stop(this, LbrynetService.class); } @@ -544,7 +522,7 @@ public class MainActivity extends FragmentActivity implements DefaultHardwareBac notificationManager.cancel(downloadNotificationIds.get(i)); } } - if (receivedStopService || !isServiceRunning(LbrynetService.class)) { + if (receivedStopService || !isServiceRunning(this, LbrynetService.class)) { notificationManager.cancelAll(); } super.onDestroy(); @@ -635,8 +613,8 @@ public class MainActivity extends FragmentActivity implements DefaultHardwareBac true); } - private boolean isServiceRunning(Class serviceClass) { - ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); + public static boolean isServiceRunning(Context context, Class serviceClass) { + ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); for (ActivityManager.RunningServiceInfo serviceInfo : manager.getRunningServices(Integer.MAX_VALUE)) { if (serviceClass.getName().equals(serviceInfo.service.getClassName())) { return true; diff --git a/app/src/main/java/io/lbry/browser/reactmodules/UtilityModule.java b/app/src/main/java/io/lbry/browser/reactmodules/UtilityModule.java index 721abd27..e6bd02bc 100644 --- a/app/src/main/java/io/lbry/browser/reactmodules/UtilityModule.java +++ b/app/src/main/java/io/lbry/browser/reactmodules/UtilityModule.java @@ -470,4 +470,16 @@ public class UtilityModule extends ReactContextBaseJavaModule { // This obtains a public default download directory after the storage permission has been granted promise.resolve(Utils.getConfiguredDownloadDirectory(context)); } + + @ReactMethod + public void getLbrynetDirectory(Promise promise) { + String path = String.format("%s/%s", Utils.getAppInternalStorageDir(context), "lbrynet"); + promise.resolve(path); + } + + @ReactMethod + public void getPlatform(Promise promise) { + String platform = String.format("Android %s (API %s)", Utils.getAndroidRelease(), Utils.getAndroidSdk()); + promise.resolve(platform); + } }