diff --git a/app/libs/lbrysdk-0.64.0-release__arm.aar b/app/libs/lbrysdk-0.64.0-release__arm.aar index 70511baf..da6c2aef 100644 Binary files a/app/libs/lbrysdk-0.64.0-release__arm.aar and b/app/libs/lbrysdk-0.64.0-release__arm.aar differ diff --git a/app/libs/lbrysdk-0.64.0-release__arm64.aar b/app/libs/lbrysdk-0.64.0-release__arm64.aar index 8219fecf..8f1646b8 100644 Binary files a/app/libs/lbrysdk-0.64.0-release__arm64.aar and b/app/libs/lbrysdk-0.64.0-release__arm64.aar differ diff --git a/app/src/main/java/io/lbry/browser/DownloadManager.java b/app/src/main/java/io/lbry/browser/DownloadManager.java index bc57caac..1d8e82ab 100644 --- a/app/src/main/java/io/lbry/browser/DownloadManager.java +++ b/app/src/main/java/io/lbry/browser/DownloadManager.java @@ -12,10 +12,6 @@ import androidx.core.app.NotificationCompat; import androidx.core.app.NotificationManagerCompat; import androidx.core.content.ContextCompat; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.bridge.ReactContextBaseJavaModule; -import com.facebook.react.bridge.ReactMethod; - import io.lbry.browser.receivers.NotificationDeletedReceiver; import io.lbry.lbrysdk.LbrynetService; diff --git a/app/src/main/java/io/lbry/browser/LbrynetMessagingService.java b/app/src/main/java/io/lbry/browser/LbrynetMessagingService.java index 8d21a4b6..f5c4c4a8 100644 --- a/app/src/main/java/io/lbry/browser/LbrynetMessagingService.java +++ b/app/src/main/java/io/lbry/browser/LbrynetMessagingService.java @@ -116,7 +116,8 @@ public class LbrynetMessagingService extends FirebaseMessagingService { } else { if (!MainActivity.isServiceRunning(this, LbrynetService.class) && contentTitle != null && - channelUrl != null + channelUrl != null && + !url.startsWith("lbry://?") /* not a special url */ ) { // only enter lite mode when contentTitle and channelUrl are set (and the service isn't running yet) // cold start diff --git a/app/src/main/java/io/lbry/browser/MainActivity.java b/app/src/main/java/io/lbry/browser/MainActivity.java index 780f11e4..5d833c00 100644 --- a/app/src/main/java/io/lbry/browser/MainActivity.java +++ b/app/src/main/java/io/lbry/browser/MainActivity.java @@ -3,6 +3,7 @@ package io.lbry.browser; import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.app.PendingIntent; +import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.os.Environment; @@ -18,6 +19,7 @@ import android.content.SharedPreferences; import android.database.Cursor; import android.Manifest; import android.net.Uri; +import android.os.Handler; import android.provider.DocumentsContract; import android.provider.MediaStore; import android.provider.Settings; @@ -62,10 +64,12 @@ import io.lbry.browser.reactpackages.LbryReactPackage; import io.lbry.browser.reactmodules.BackgroundMediaModule; import io.lbry.lbrysdk.LbrynetService; import io.lbry.lbrysdk.ServiceHelper; +import io.lbry.lbrysdk.Utils; import java.io.File; import java.io.UnsupportedEncodingException; import java.math.BigInteger; +import java.net.ConnectException; import java.net.URISyntaxException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; @@ -84,51 +88,34 @@ import org.reactnative.camera.RNCameraPackage; public class MainActivity extends FragmentActivity implements DefaultHardwareBackBtnHandler, PermissionAwareActivity { private static Activity currentActivity = null; - private static final int OVERLAY_PERMISSION_REQ_CODE = 101; - private static final int STORAGE_PERMISSION_REQ_CODE = 201; - private static final int PHONE_STATE_PERMISSION_REQ_CODE = 202; - private static final int RECEIVE_SMS_PERMISSION_REQ_CODE = 203; - public static final int DOCUMENT_PICKER_RESULT_CODE = 301; + public static final String SHARED_PREFERENCES_NAME = "LBRY"; + public static final String SALT_KEY = "salt"; + public static final String DEVICE_ID_KEY = "deviceId"; + public static final String SOURCE_NOTIFICATION_ID_KEY = "sourceNotificationId"; + public static final String SETTING_KEEP_DAEMON_RUNNING = "keepDaemonRunning"; + public static List downloadNotificationIds = new ArrayList(); private BroadcastReceiver notificationsReceiver; - private BroadcastReceiver smsReceiver; - private BroadcastReceiver stopServiceReceiver; - private BroadcastReceiver downloadEventReceiver; - private FirebaseAnalytics firebaseAnalytics; - private ReactRootView mReactRootView; - private ReactInstanceManager mReactInstanceManager; - public static final String SHARED_PREFERENCES_NAME = "LBRY"; - - public static final String SALT_KEY = "salt"; - - public static final String DEVICE_ID_KEY = "deviceId"; - - public static final String SOURCE_NOTIFICATION_ID_KEY = "sourceNotificationId"; - - public static final String SETTING_KEEP_DAEMON_RUNNING = "keepDaemonRunning"; - - public static List downloadNotificationIds = new ArrayList(); - /** * Flag which indicates whether or not the service is running. Will be updated in the * onResume method. */ private boolean serviceRunning; - + private CheckSdkReadyTask checkSdkReadyTask; + private boolean lbrySdkReady; private boolean receivedStopService; - private PermissionListener permissionListener; protected String getMainComponentName() { @@ -158,12 +145,12 @@ public class MainActivity extends FragmentActivity implements DefaultHardwareBac // Check the dht setting SharedPreferences sp = getSharedPreferences(MainActivity.SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE); LbrynetService.setDHTEnabled(sp.getBoolean(UtilityModule.DHT_ENABLED, false)); - serviceRunning = isServiceRunning(this, LbrynetService.class); if (!serviceRunning) { CurrentLaunchTiming.setColdStart(true); ServiceHelper.start(this, "", LbrynetService.class, "lbrynetservice"); } + checkSdkReady(); if (LbrynetService.serviceInstance != null) { // TODO: Add a broadcast receiver to listen for the service started event, so that we can set this properly @@ -203,6 +190,22 @@ public class MainActivity extends FragmentActivity implements DefaultHardwareBac setContentView(mReactRootView); } + private void checkSdkReady() { + if (!lbrySdkReady) { + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + if (checkSdkReadyTask != null && checkSdkReadyTask.getStatus() != AsyncTask.Status.FINISHED) { + // task already running + return; + } + checkSdkReadyTask = new CheckSdkReadyTask(); + checkSdkReadyTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + } + }, 1000); + } + } + private void checkNotificationOpenIntent(Intent intent) { if (intent != null) { String notificationName = intent.getStringExtra("notification_name"); @@ -477,10 +480,13 @@ public class MainActivity extends FragmentActivity implements DefaultHardwareBac super.onResume(); SharedPreferences sp = getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE); + LbrynetService.setDHTEnabled(sp.getBoolean(UtilityModule.DHT_ENABLED, false)); + serviceRunning = isServiceRunning(this, LbrynetService.class); if (!serviceRunning) { ServiceHelper.start(this, "", LbrynetService.class, "lbrynetservice"); } + checkSdkReady(); if (mReactInstanceManager != null) { mReactInstanceManager.onHostResume(this, this); @@ -684,7 +690,6 @@ public class MainActivity extends FragmentActivity implements DefaultHardwareBac */ @SuppressLint("NewApi") public static String getRealPathFromURI_API19(final Context context, final Uri uri) { - final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; // DocumentProvider @@ -835,6 +840,51 @@ public class MainActivity extends FragmentActivity implements DefaultHardwareBac public static boolean isGooglePhotosUri(Uri uri) { return "com.google.android.apps.photos.content".equals(uri.getAuthority()); } + + private class CheckSdkReadyTask extends AsyncTask { + + public Boolean doInBackground(Void... params) { + boolean sdkReady = false; + try { + String response = Utils.sdkCall("status"); + if (response != null) { + JSONObject result = new JSONObject(response); + JSONObject status = result.getJSONObject("result"); + + // send status response for splash page updates + WritableMap sdkStatus = JSONObjectToMap(status); + ReactContext reactContext = mReactInstanceManager.getCurrentReactContext(); + if (reactContext != null) { + WritableMap evtParams = Arguments.createMap(); + evtParams.putMap("status", sdkStatus); + reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit("onSdkStatusResponse", evtParams); + } + + JSONObject startupStatus = status.getJSONObject("startup_status"); + sdkReady = startupStatus.has("stream_manager") && startupStatus.has("wallet") && + startupStatus.getBoolean("stream_manager") && startupStatus.getBoolean("wallet") && + (status.getJSONObject("wallet").getLong("blocks_behind") <= 0); + } + } catch (ConnectException ex) { + // pass + } catch (JSONException ex) { + // pass + } + + return sdkReady; + } + protected void onPostExecute(Boolean sdkReady) { + lbrySdkReady = sdkReady; + ReactContext reactContext = mReactInstanceManager.getCurrentReactContext(); + if (sdkReady && reactContext != null) { + reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit("onSdkReady", null); + } + + if (!sdkReady) { + checkSdkReady(); + } + } + } public static class LaunchTiming { private Date start; 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 32f77228..d0081701 100644 --- a/app/src/main/java/io/lbry/browser/reactmodules/UtilityModule.java +++ b/app/src/main/java/io/lbry/browser/reactmodules/UtilityModule.java @@ -34,6 +34,7 @@ import java.io.Closeable; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; +import java.io.PrintStream; import java.util.HashMap; import java.util.Map; import java.util.Random; @@ -93,6 +94,7 @@ public class UtilityModule extends ReactContextBaseJavaModule { public Map getConstants() { final Map constants = MapBuilder.newHashMap(); constants.put("language", language); + constants.put("dhtEnabled", LbrynetService.isDHTEnabled()); return constants; } @@ -422,13 +424,34 @@ public class UtilityModule extends ReactContextBaseJavaModule { } @ReactMethod - public void setNativeBooleanSetting(String key, boolean value) { + public void setNativeBooleanSetting(String key, final boolean value) { if (context != null) { SharedPreferences sp = context.getSharedPreferences(MainActivity.SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE); SharedPreferences.Editor editor = sp.edit(); editor.putBoolean(key, value); editor.commit(); } + + if (DHT_ENABLED.equalsIgnoreCase(key)) { + (new AsyncTask() { + protected Void doInBackground(Void... params) { + String fileContent = value ? "on" : "off"; + String path = String.format("%s/%s", Utils.getAppInternalStorageDir(context), "dht"); + PrintStream out = null; + try { + out = new PrintStream(new FileOutputStream(path)); + out.print(fileContent); + } catch (Exception ex) { + // pass + } finally { + if (out != null) { + out.close(); + } + } + return null; + } + }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + } } @ReactMethod