generate install_id natively #1007
5 changed files with 145 additions and 13 deletions
|
@ -117,6 +117,7 @@ dependencies {
|
||||||
|
|
||||||
implementation 'com.arthenica:mobile-ffmpeg-full-gpl:4.3.1.LTS'
|
implementation 'com.arthenica:mobile-ffmpeg-full-gpl:4.3.1.LTS'
|
||||||
|
|
||||||
|
implementation 'org.bitcoinj:bitcoinj-tools:0.14.7'
|
||||||
implementation 'org.java-websocket:Java-WebSocket:1.5.1'
|
implementation 'org.java-websocket:Java-WebSocket:1.5.1'
|
||||||
|
|
||||||
compileOnly 'org.projectlombok:lombok:1.18.10'
|
compileOnly 'org.projectlombok:lombok:1.18.10'
|
||||||
|
|
|
@ -15,12 +15,22 @@ import androidx.appcompat.app.AppCompatActivity;
|
||||||
import androidx.core.text.HtmlCompat;
|
import androidx.core.text.HtmlCompat;
|
||||||
import androidx.preference.PreferenceManager;
|
import androidx.preference.PreferenceManager;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
|
||||||
import io.lbry.browser.exceptions.AuthTokenInvalidatedException;
|
import io.lbry.browser.exceptions.AuthTokenInvalidatedException;
|
||||||
import io.lbry.browser.utils.Helper;
|
import io.lbry.browser.utils.Helper;
|
||||||
import io.lbry.browser.utils.Lbry;
|
import io.lbry.browser.utils.Lbry;
|
||||||
import io.lbry.browser.utils.LbryAnalytics;
|
import io.lbry.browser.utils.LbryAnalytics;
|
||||||
import io.lbry.browser.utils.Lbryio;
|
import io.lbry.browser.utils.Lbryio;
|
||||||
import io.lbry.lbrysdk.LbrynetService;
|
import io.lbry.lbrysdk.LbrynetService;
|
||||||
|
import io.lbry.lbrysdk.ServiceHelper;
|
||||||
|
import io.lbry.lbrysdk.Utils;
|
||||||
|
|
||||||
public class FirstRunActivity extends AppCompatActivity {
|
public class FirstRunActivity extends AppCompatActivity {
|
||||||
|
|
||||||
|
@ -44,12 +54,7 @@ public class FirstRunActivity extends AppCompatActivity {
|
||||||
});
|
});
|
||||||
|
|
||||||
registerAuthReceiver();
|
registerAuthReceiver();
|
||||||
if (!Lbry.SDK_READY) {
|
findViewById(R.id.welcome_wait_container).setVisibility(View.VISIBLE);
|
||||||
findViewById(R.id.welcome_wait_container).setVisibility(View.VISIBLE);
|
|
||||||
} else {
|
|
||||||
authenticate();
|
|
||||||
}
|
|
||||||
|
|
||||||
IntentFilter filter = new IntentFilter();
|
IntentFilter filter = new IntentFilter();
|
||||||
filter.addAction(MainActivity.ACTION_SDK_READY);
|
filter.addAction(MainActivity.ACTION_SDK_READY);
|
||||||
filter.addAction(LbrynetService.ACTION_STOP_SERVICE);
|
filter.addAction(LbrynetService.ACTION_STOP_SERVICE);
|
||||||
|
@ -62,10 +67,38 @@ public class FirstRunActivity extends AppCompatActivity {
|
||||||
authenticate();
|
authenticate();
|
||||||
} else if (LbrynetService.ACTION_STOP_SERVICE.equals(action)) {
|
} else if (LbrynetService.ACTION_STOP_SERVICE.equals(action)) {
|
||||||
finish();
|
finish();
|
||||||
|
if (MainActivity.instance != null) {
|
||||||
|
MainActivity.instance.finish();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
registerReceiver(sdkReceiver, filter);
|
registerReceiver(sdkReceiver, filter);
|
||||||
|
|
||||||
|
CheckInstallIdTask task = new CheckInstallIdTask(this, new CheckInstallIdTask.InstallIdHandler() {
|
||||||
|
@Override
|
||||||
|
public void onInstallIdChecked(boolean result) {
|
||||||
|
// start the sdk from FirstRun
|
||||||
|
boolean serviceRunning = MainActivity.isServiceRunning(MainActivity.instance, LbrynetService.class);
|
||||||
|
if (!serviceRunning) {
|
||||||
|
Lbry.SDK_READY = false;
|
||||||
|
ServiceHelper.start(MainActivity.instance, "", LbrynetService.class, "lbrynetservice");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
// install_id generated and validated, authenticate now
|
||||||
|
authenticate();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we weren't able to generate the install_id ourselves, depend on the sdk for that
|
||||||
|
if (Lbry.SDK_READY) {
|
||||||
|
authenticate();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
|
@ -134,6 +167,75 @@ public class FirstRunActivity extends AppCompatActivity {
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void generateIdAndAuthenticate() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class CheckInstallIdTask extends AsyncTask<Void, Void, Boolean> {
|
||||||
|
private Context context;
|
||||||
|
private InstallIdHandler handler;
|
||||||
|
public CheckInstallIdTask(Context context, InstallIdHandler handler) {
|
||||||
|
this.context = context;
|
||||||
|
this.handler = handler;
|
||||||
|
}
|
||||||
|
protected Boolean doInBackground(Void... params) {
|
||||||
|
// Load the installation id from the file system
|
||||||
|
String lbrynetDir = String.format("%s/%s", Utils.getAppInternalStorageDir(context), "lbrynet");
|
||||||
|
File dir = new File(lbrynetDir);
|
||||||
|
boolean dirExists = dir.isDirectory();
|
||||||
|
if (!dirExists) {
|
||||||
|
dirExists = dir.mkdirs();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dirExists) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
String installIdPath = String.format("%s/install_id", lbrynetDir);
|
||||||
|
File file = new File(installIdPath);
|
||||||
|
String installId = null;
|
||||||
|
if (!file.exists()) {
|
||||||
|
// generate the install_id
|
||||||
|
installId = Lbry.generateId();
|
||||||
|
BufferedWriter writer = null;
|
||||||
|
try {
|
||||||
|
writer = new BufferedWriter(new FileWriter(file));
|
||||||
|
writer.write(installId);
|
||||||
|
android.util.Log.d("LbryMain", "Generated install ID=" + installId);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
return false;
|
||||||
|
} finally {
|
||||||
|
Helper.closeCloseable(writer);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// read the installation id from the file
|
||||||
|
BufferedReader reader = null;
|
||||||
|
try {
|
||||||
|
reader = new BufferedReader(new InputStreamReader(new FileInputStream(installIdPath)));
|
||||||
|
installId = reader.readLine();
|
||||||
|
} catch (IOException ex) {
|
||||||
|
return false;
|
||||||
|
} finally {
|
||||||
|
Helper.closeCloseable(reader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Helper.isNullOrEmpty(installId)) {
|
||||||
|
Lbry.INSTALLATION_ID = installId;
|
||||||
|
}
|
||||||
|
return !Helper.isNullOrEmpty(installId);
|
||||||
|
}
|
||||||
|
protected void onPostExecute(Boolean result) {
|
||||||
|
if (handler != null) {
|
||||||
|
handler.onInstallIdChecked(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface InstallIdHandler {
|
||||||
|
void onInstallIdChecked(boolean result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static class AuthenticateTask extends AsyncTask<Void, Void, Void> {
|
private static class AuthenticateTask extends AsyncTask<Void, Void, Void> {
|
||||||
private Context context;
|
private Context context;
|
||||||
public AuthenticateTask(Context context) {
|
public AuthenticateTask(Context context) {
|
||||||
|
|
|
@ -211,6 +211,7 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
private static final String SPECIAL_URL_PREFIX = "lbry://?";
|
private static final String SPECIAL_URL_PREFIX = "lbry://?";
|
||||||
private static final int REMOTE_NOTIFICATION_REFRESH_TTL = 300000; // 5 minutes
|
private static final int REMOTE_NOTIFICATION_REFRESH_TTL = 300000; // 5 minutes
|
||||||
public static final String SKU_SKIP = "lbryskip";
|
public static final String SKU_SKIP = "lbryskip";
|
||||||
|
public static MainActivity instance;
|
||||||
|
|
||||||
private boolean shuttingDown;
|
private boolean shuttingDown;
|
||||||
private Date remoteNotifcationsLastLoaded;
|
private Date remoteNotifcationsLastLoaded;
|
||||||
|
@ -393,6 +394,7 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
instance = this;
|
||||||
// workaround to fix dark theme because https://issuetracker.google.com/issues/37124582
|
// workaround to fix dark theme because https://issuetracker.google.com/issues/37124582
|
||||||
try {
|
try {
|
||||||
new WebView(this);
|
new WebView(this);
|
||||||
|
@ -1140,12 +1142,14 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
checkFirstRun();
|
checkFirstRun();
|
||||||
checkNowPlaying();
|
checkNowPlaying();
|
||||||
|
|
||||||
// check (and start) the LBRY SDK service
|
if (isFirstRunCompleted()) {
|
||||||
serviceRunning = isServiceRunning(this, LbrynetService.class);
|
// check (and start) the LBRY SDK service
|
||||||
if (!serviceRunning) {
|
serviceRunning = isServiceRunning(this, LbrynetService.class);
|
||||||
Lbry.SDK_READY = false;
|
if (!serviceRunning) {
|
||||||
//findViewById(R.id.global_sdk_initializing_status).setVisibility(View.VISIBLE);
|
Lbry.SDK_READY = false;
|
||||||
ServiceHelper.start(this, "", LbrynetService.class, "lbrynetservice");
|
//findViewById(R.id.global_sdk_initializing_status).setVisibility(View.VISIBLE);
|
||||||
|
ServiceHelper.start(this, "", LbrynetService.class, "lbrynetservice");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
checkSdkReady();
|
checkSdkReady();
|
||||||
showSignedInUser();
|
showSignedInUser();
|
||||||
|
@ -1156,6 +1160,11 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isFirstRunCompleted() {
|
||||||
|
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
|
return sp.getBoolean(PREFERENCE_KEY_INTERNAL_FIRST_RUN_COMPLETED, false);
|
||||||
|
}
|
||||||
|
|
||||||
private void checkPurchases() {
|
private void checkPurchases() {
|
||||||
if (billingClient != null) {
|
if (billingClient != null) {
|
||||||
Purchase.PurchasesResult result = billingClient.queryPurchases(BillingClient.SkuType.INAPP);
|
Purchase.PurchasesResult result = billingClient.queryPurchases(BillingClient.SkuType.INAPP);
|
||||||
|
|
|
@ -20,7 +20,6 @@ import android.provider.MediaStore;
|
||||||
import android.text.method.LinkMovementMethod;
|
import android.text.method.LinkMovementMethod;
|
||||||
import android.view.ContextMenu;
|
import android.view.ContextMenu;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.LinearLayout;
|
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
@ -32,6 +31,7 @@ import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import com.google.android.gms.common.util.Hex;
|
import com.google.android.gms.common.util.Hex;
|
||||||
|
|
||||||
|
import org.bitcoinj.core.Base58;
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
|
@ -2,12 +2,15 @@ package io.lbry.browser.utils;
|
||||||
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import org.bitcoinj.core.Base58;
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.KeyStore;
|
import java.security.KeyStore;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -17,6 +20,7 @@ import java.util.Iterator;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Random;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import io.lbry.browser.exceptions.ApiCallException;
|
import io.lbry.browser.exceptions.ApiCallException;
|
||||||
|
@ -522,4 +526,20 @@ public final class Lbry {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String generateId() {
|
||||||
|
return generateId(64);
|
||||||
|
}
|
||||||
|
public static String generateId(int numBytes) {
|
||||||
|
byte[] arr = new byte[numBytes];
|
||||||
|
new Random().nextBytes(arr);
|
||||||
|
try {
|
||||||
|
MessageDigest md = MessageDigest.getInstance("SHA-384");
|
||||||
|
byte[] hash = md.digest(arr);
|
||||||
|
return Base58.encode(hash);
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
// pass
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue