lbry.tv hybrid mode #869
6 changed files with 103 additions and 33 deletions
Binary file not shown.
Binary file not shown.
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<Integer> downloadNotificationIds = new ArrayList<Integer>();
|
||||
|
||||
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<Integer> downloadNotificationIds = new ArrayList<Integer>();
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
@ -836,6 +841,51 @@ public class MainActivity extends FragmentActivity implements DefaultHardwareBac
|
|||
return "com.google.android.apps.photos.content".equals(uri.getAuthority());
|
||||
}
|
||||
|
||||
private class CheckSdkReadyTask extends AsyncTask<Void, Void, Boolean> {
|
||||
|
||||
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;
|
||||
private boolean coldStart;
|
||||
|
|
|
@ -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<String, Object> getConstants() {
|
||||
final Map<String, Object> 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<Void, Void, Void>() {
|
||||
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
|
||||
|
|
Loading…
Reference in a new issue