Merge branch 'random-improvements' into 'master'
Random improvements See merge request !262
This commit is contained in:
commit
d902612f41
@ -65,7 +65,7 @@ In order to run the F-Droid test suite, you will need to have either a real devi
|
|||||||
connected via `adb`, or an emulator running. Then, execute the following from the
|
connected via `adb`, or an emulator running. Then, execute the following from the
|
||||||
command line:
|
command line:
|
||||||
|
|
||||||
./gradlew connectedCheck
|
./gradlew check
|
||||||
|
|
||||||
Note that the CI already runs the tests on an emulator, so you don't
|
Note that the CI already runs the tests on an emulator, so you don't
|
||||||
necessarily have to do this yourself if you open a merge request as the tests
|
necessarily have to do this yourself if you open a merge request as the tests
|
||||||
|
@ -210,7 +210,7 @@ pmd {
|
|||||||
task pmd(type: Pmd, dependsOn: assembleDebug) {
|
task pmd(type: Pmd, dependsOn: assembleDebug) {
|
||||||
ruleSets = [
|
ruleSets = [
|
||||||
//'java-basic',
|
//'java-basic',
|
||||||
//'java-unusedcode',
|
'java-unusedcode',
|
||||||
'java-android',
|
'java-android',
|
||||||
'java-clone',
|
'java-clone',
|
||||||
'java-finalizers',
|
'java-finalizers',
|
||||||
@ -218,7 +218,7 @@ task pmd(type: Pmd, dependsOn: assembleDebug) {
|
|||||||
'java-migrating',
|
'java-migrating',
|
||||||
//'java-unnecessary', // too nitpicky with parenthesis
|
//'java-unnecessary', // too nitpicky with parenthesis
|
||||||
]
|
]
|
||||||
source 'src/main/java'
|
source 'src/main/java', 'src/test/java', 'src/androidTest/java'
|
||||||
include '**/*.java'
|
include '**/*.java'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,6 +27,9 @@ import android.os.Build;
|
|||||||
import android.test.mock.MockContentResolver;
|
import android.test.mock.MockContentResolver;
|
||||||
import android.test.mock.MockContext;
|
import android.test.mock.MockContext;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -132,6 +135,7 @@ public abstract class ProviderTestCase2MockContext<T extends ContentProvider> ex
|
|||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@Before
|
||||||
protected void setUp() throws Exception {
|
protected void setUp() throws Exception {
|
||||||
super.setUp();
|
super.setUp();
|
||||||
|
|
||||||
@ -165,6 +169,7 @@ public abstract class ProviderTestCase2MockContext<T extends ContentProvider> ex
|
|||||||
* {@link android.content.ContentProvider} represented by mProvider.
|
* {@link android.content.ContentProvider} represented by mProvider.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@After
|
||||||
protected void tearDown() throws Exception {
|
protected void tearDown() throws Exception {
|
||||||
shutdownProvider();
|
shutdownProvider();
|
||||||
super.tearDown();
|
super.tearDown();
|
||||||
|
@ -18,7 +18,6 @@ import static org.junit.Assert.fail;
|
|||||||
|
|
||||||
@RunWith(AndroidJUnit4.class)
|
@RunWith(AndroidJUnit4.class)
|
||||||
public class RepoUpdaterTest {
|
public class RepoUpdaterTest {
|
||||||
private static final String TAG = "RepoUpdaterTest";
|
|
||||||
|
|
||||||
private Context context;
|
private Context context;
|
||||||
private RepoUpdater repoUpdater;
|
private RepoUpdater repoUpdater;
|
||||||
|
@ -91,7 +91,6 @@ public class AndroidXMLDecompress {
|
|||||||
|
|
||||||
while (offset < binaryXml.length) {
|
while (offset < binaryXml.length) {
|
||||||
int tag0 = littleEndianWord(binaryXml, offset);
|
int tag0 = littleEndianWord(binaryXml, offset);
|
||||||
int nameStringIndex = littleEndianWord(binaryXml, offset + 5 * 4);
|
|
||||||
|
|
||||||
if (tag0 == startTag) {
|
if (tag0 == startTag) {
|
||||||
int numbAttrs = littleEndianWord(binaryXml, offset + 7 * 4);
|
int numbAttrs = littleEndianWord(binaryXml, offset + 7 * 4);
|
||||||
@ -114,11 +113,10 @@ public class AndroidXMLDecompress {
|
|||||||
attributes.put(attributeName, attributeValue);
|
attributes.put(attributeName, attributeValue);
|
||||||
}
|
}
|
||||||
return attributes;
|
return attributes;
|
||||||
} else {
|
}
|
||||||
// we only need the first <manifest> start tag
|
// we only need the first <manifest> start tag
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return new HashMap<String, Object>(0);
|
return new HashMap<String, Object>(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,6 +79,7 @@ public final class Preferences implements SharedPreferences.OnSharedPreferenceCh
|
|||||||
private static final boolean DEFAULT_EXPERT = false;
|
private static final boolean DEFAULT_EXPERT = false;
|
||||||
private static final boolean DEFAULT_ENABLE_PROXY = false;
|
private static final boolean DEFAULT_ENABLE_PROXY = false;
|
||||||
public static final String DEFAULT_THEME = "light";
|
public static final String DEFAULT_THEME = "light";
|
||||||
|
@SuppressWarnings("PMD.AvoidUsingHardCodedIP")
|
||||||
public static final String DEFAULT_PROXY_HOST = "127.0.0.1";
|
public static final String DEFAULT_PROXY_HOST = "127.0.0.1";
|
||||||
public static final int DEFAULT_PROXY_PORT = 8118;
|
public static final int DEFAULT_PROXY_PORT = 8118;
|
||||||
private static final boolean DEFAULT_SHOW_NFC_DURING_SWAP = true;
|
private static final boolean DEFAULT_SHOW_NFC_DURING_SWAP = true;
|
||||||
|
@ -92,6 +92,15 @@ public class RepoUpdater {
|
|||||||
return hasChanged;
|
return hasChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void cleanupDownloader(Downloader d) {
|
||||||
|
if (d == null || d.outputFile == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!d.outputFile.delete()) {
|
||||||
|
Log.w(TAG, "Couldn't delete file: " + d.outputFile.getAbsolutePath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Downloader downloadIndex() throws UpdateException {
|
private Downloader downloadIndex() throws UpdateException {
|
||||||
Downloader downloader = null;
|
Downloader downloader = null;
|
||||||
try {
|
try {
|
||||||
@ -106,11 +115,7 @@ public class RepoUpdater {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
if (downloader != null && downloader.outputFile != null) {
|
cleanupDownloader(downloader);
|
||||||
if (!downloader.outputFile.delete()) {
|
|
||||||
Log.w(TAG, "Couldn't delete file: " + downloader.outputFile.getAbsolutePath());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new UpdateException(repo, "Error getting index file", e);
|
throw new UpdateException(repo, "Error getting index file", e);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
@ -197,13 +202,11 @@ public class RepoUpdater {
|
|||||||
} finally {
|
} finally {
|
||||||
FDroidApp.enableSpongyCastleOnLollipop();
|
FDroidApp.enableSpongyCastleOnLollipop();
|
||||||
Utils.closeQuietly(indexInputStream);
|
Utils.closeQuietly(indexInputStream);
|
||||||
if (downloadedFile != null) {
|
if (downloadedFile != null && !downloadedFile.delete()) {
|
||||||
if (!downloadedFile.delete()) {
|
|
||||||
Log.w(TAG, "Couldn't delete file: " + downloadedFile.getAbsolutePath());
|
Log.w(TAG, "Couldn't delete file: " + downloadedFile.getAbsolutePath());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private void commitToDb() throws UpdateException {
|
private void commitToDb() throws UpdateException {
|
||||||
Log.i(TAG, "Repo signature verified, saving app metadata to database.");
|
Log.i(TAG, "Repo signature verified, saving app metadata to database.");
|
||||||
|
@ -673,14 +673,13 @@ public final class Utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (File f : files) {
|
for (File f : files) {
|
||||||
if ((startsWith != null && f.getName().startsWith(startsWith))
|
if (((startsWith != null && f.getName().startsWith(startsWith))
|
||||||
|| (endsWith != null && f.getName().endsWith(endsWith))) {
|
|| (endsWith != null && f.getName().endsWith(endsWith)))
|
||||||
if (!f.delete()) {
|
&& !f.delete()) {
|
||||||
Log.w(TAG, "Couldn't delete cache file " + f);
|
Log.w(TAG, "Couldn't delete cache file " + f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public static void debugLog(String tag, String msg) {
|
public static void debugLog(String tag, String msg) {
|
||||||
if (BuildConfig.DEBUG) {
|
if (BuildConfig.DEBUG) {
|
||||||
|
@ -178,11 +178,9 @@ public abstract class Installer {
|
|||||||
Map<String, Object> attributes = AndroidXMLDecompress.getManifestHeaderAttributes(apkFile.getAbsolutePath());
|
Map<String, Object> attributes = AndroidXMLDecompress.getManifestHeaderAttributes(apkFile.getAbsolutePath());
|
||||||
|
|
||||||
/* This isn't really needed, but might as well since we have the data already */
|
/* This isn't really needed, but might as well since we have the data already */
|
||||||
if (attributes.containsKey("packageName")) {
|
if (attributes.containsKey("packageName") && !TextUtils.equals(packageName, (String) attributes.get("packageName"))) {
|
||||||
if (!TextUtils.equals(packageName, (String) attributes.get("packageName"))) {
|
|
||||||
throw new InstallFailedException(apkFile + " has packageName that clashes with " + packageName);
|
throw new InstallFailedException(apkFile + " has packageName that clashes with " + packageName);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!attributes.containsKey("versionCode")) {
|
if (!attributes.containsKey("versionCode")) {
|
||||||
throw new InstallFailedException(apkFile + " is missing versionCode!");
|
throw new InstallFailedException(apkFile + " is missing versionCode!");
|
||||||
|
@ -119,24 +119,18 @@ public final class LocalRepoManager {
|
|||||||
xmlIndexJar = new SanitizedFile(repoDir, "index.jar");
|
xmlIndexJar = new SanitizedFile(repoDir, "index.jar");
|
||||||
xmlIndexJarUnsigned = new SanitizedFile(repoDir, "index.unsigned.jar");
|
xmlIndexJarUnsigned = new SanitizedFile(repoDir, "index.unsigned.jar");
|
||||||
|
|
||||||
if (!fdroidDir.exists()) {
|
if (!fdroidDir.exists() && !fdroidDir.mkdir()) {
|
||||||
if (!fdroidDir.mkdir()) {
|
|
||||||
Log.e(TAG, "Unable to create empty base: " + fdroidDir);
|
Log.e(TAG, "Unable to create empty base: " + fdroidDir);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!repoDir.exists()) {
|
if (!repoDir.exists() && !repoDir.mkdir()) {
|
||||||
if (!repoDir.mkdir()) {
|
|
||||||
Log.e(TAG, "Unable to create empty repo: " + repoDir);
|
Log.e(TAG, "Unable to create empty repo: " + repoDir);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!iconsDir.exists()) {
|
if (!iconsDir.exists() && !iconsDir.mkdir()) {
|
||||||
if (!iconsDir.mkdir()) {
|
|
||||||
Log.e(TAG, "Unable to create icons folder: " + iconsDir);
|
Log.e(TAG, "Unable to create icons folder: " + iconsDir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private String writeFdroidApkToWebroot() {
|
private String writeFdroidApkToWebroot() {
|
||||||
ApplicationInfo appInfo;
|
ApplicationInfo appInfo;
|
||||||
|
@ -228,8 +228,7 @@ public class LocalHTTPD extends NanoHTTPD {
|
|||||||
long startFrom = 0;
|
long startFrom = 0;
|
||||||
long endAt = -1;
|
long endAt = -1;
|
||||||
String range = header.get("range");
|
String range = header.get("range");
|
||||||
if (range != null) {
|
if (range != null && range.startsWith("bytes=")) {
|
||||||
if (range.startsWith("bytes=")) {
|
|
||||||
range = range.substring("bytes=".length());
|
range = range.substring("bytes=".length());
|
||||||
int minus = range.indexOf('-');
|
int minus = range.indexOf('-');
|
||||||
try {
|
try {
|
||||||
@ -240,7 +239,6 @@ public class LocalHTTPD extends NanoHTTPD {
|
|||||||
} catch (NumberFormatException ignored) {
|
} catch (NumberFormatException ignored) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Change return code and add Content-Range header when skipping is
|
// Change return code and add Content-Range header when skipping is
|
||||||
// requested
|
// requested
|
||||||
|
@ -266,8 +266,7 @@ public class BluetoothServer extends Thread {
|
|||||||
long startFrom = 0;
|
long startFrom = 0;
|
||||||
long endAt = -1;
|
long endAt = -1;
|
||||||
String range = header.get("range");
|
String range = header.get("range");
|
||||||
if (range != null) {
|
if (range != null && range.startsWith("bytes=")) {
|
||||||
if (range.startsWith("bytes=")) {
|
|
||||||
range = range.substring("bytes=".length());
|
range = range.substring("bytes=".length());
|
||||||
int minus = range.indexOf('-');
|
int minus = range.indexOf('-');
|
||||||
try {
|
try {
|
||||||
@ -278,7 +277,6 @@ public class BluetoothServer extends Thread {
|
|||||||
} catch (NumberFormatException ignored) {
|
} catch (NumberFormatException ignored) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Change return code and add Content-Range header when skipping is
|
// Change return code and add Content-Range header when skipping is
|
||||||
// requested
|
// requested
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
package org.fdroid.fdroid.net.bluetooth;
|
|
||||||
|
|
||||||
class UnexpectedResponseException extends Exception {
|
|
||||||
|
|
||||||
UnexpectedResponseException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
UnexpectedResponseException(String message, Throwable cause) {
|
|
||||||
super("Unexpected response from Bluetooth server: '" + message + "'", cause);
|
|
||||||
}
|
|
||||||
}
|
|
@ -29,8 +29,7 @@ public class InstallExtensionBootReceiver extends BroadcastReceiver {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
|
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED) && Preferences.get().isPostPrivilegedInstall()) {
|
||||||
if (Preferences.get().isPostPrivilegedInstall()) {
|
|
||||||
Preferences.get().setPostPrivilegedInstall(false);
|
Preferences.get().setPostPrivilegedInstall(false);
|
||||||
|
|
||||||
Intent postInstall = new Intent(context.getApplicationContext(), InstallExtensionDialogActivity.class);
|
Intent postInstall = new Intent(context.getApplicationContext(), InstallExtensionDialogActivity.class);
|
||||||
@ -39,5 +38,4 @@ public class InstallExtensionBootReceiver extends BroadcastReceiver {
|
|||||||
context.startActivity(postInstall);
|
context.startActivity(postInstall);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
@ -269,11 +269,9 @@ public class AppSecurityPermissions {
|
|||||||
String permName = strList[i];
|
String permName = strList[i];
|
||||||
// If we are only looking at an existing app, then we only
|
// If we are only looking at an existing app, then we only
|
||||||
// care about permissions that have actually been granted to it.
|
// care about permissions that have actually been granted to it.
|
||||||
if (installedPkgInfo != null && info == installedPkgInfo) {
|
if (installedPkgInfo != null && info == installedPkgInfo && (flagsList[i] & PackageInfo.REQUESTED_PERMISSION_GRANTED) == 0) {
|
||||||
if ((flagsList[i] & PackageInfo.REQUESTED_PERMISSION_GRANTED) == 0) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
PermissionInfo tmpPermInfo = mPm.getPermissionInfo(permName, 0);
|
PermissionInfo tmpPermInfo = mPm.getPermissionInfo(permName, 0);
|
||||||
if (tmpPermInfo == null) {
|
if (tmpPermInfo == null) {
|
||||||
|
@ -9,9 +9,8 @@ public class AvailableAppListAdapter extends AppListAdapter {
|
|||||||
public static AvailableAppListAdapter create(Context context, Cursor cursor, int flags) {
|
public static AvailableAppListAdapter create(Context context, Cursor cursor, int flags) {
|
||||||
if (Build.VERSION.SDK_INT >= 11) {
|
if (Build.VERSION.SDK_INT >= 11) {
|
||||||
return new AvailableAppListAdapter(context, cursor, flags);
|
return new AvailableAppListAdapter(context, cursor, flags);
|
||||||
} else {
|
|
||||||
return new AvailableAppListAdapter(context, cursor);
|
|
||||||
}
|
}
|
||||||
|
return new AvailableAppListAdapter(context, cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
private AvailableAppListAdapter(Context context, Cursor c) {
|
private AvailableAppListAdapter(Context context, Cursor c) {
|
||||||
|
@ -9,9 +9,8 @@ public class CanUpdateAppListAdapter extends AppListAdapter {
|
|||||||
public static CanUpdateAppListAdapter create(Context context, Cursor cursor, int flags) {
|
public static CanUpdateAppListAdapter create(Context context, Cursor cursor, int flags) {
|
||||||
if (Build.VERSION.SDK_INT >= 11) {
|
if (Build.VERSION.SDK_INT >= 11) {
|
||||||
return new CanUpdateAppListAdapter(context, cursor, flags);
|
return new CanUpdateAppListAdapter(context, cursor, flags);
|
||||||
} else {
|
|
||||||
return new CanUpdateAppListAdapter(context, cursor);
|
|
||||||
}
|
}
|
||||||
|
return new CanUpdateAppListAdapter(context, cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
private CanUpdateAppListAdapter(Context context, Cursor c) {
|
private CanUpdateAppListAdapter(Context context, Cursor c) {
|
||||||
|
@ -9,9 +9,8 @@ public class InstalledAppListAdapter extends AppListAdapter {
|
|||||||
public static InstalledAppListAdapter create(Context context, Cursor cursor, int flags) {
|
public static InstalledAppListAdapter create(Context context, Cursor cursor, int flags) {
|
||||||
if (Build.VERSION.SDK_INT >= 11) {
|
if (Build.VERSION.SDK_INT >= 11) {
|
||||||
return new InstalledAppListAdapter(context, cursor, flags);
|
return new InstalledAppListAdapter(context, cursor, flags);
|
||||||
} else {
|
|
||||||
return new InstalledAppListAdapter(context, cursor);
|
|
||||||
}
|
}
|
||||||
|
return new InstalledAppListAdapter(context, cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
private InstalledAppListAdapter(Context context, Cursor c) {
|
private InstalledAppListAdapter(Context context, Cursor c) {
|
||||||
|
@ -26,9 +26,8 @@ public class RepoAdapter extends CursorAdapter {
|
|||||||
public static RepoAdapter create(Context context, Cursor cursor, int flags) {
|
public static RepoAdapter create(Context context, Cursor cursor, int flags) {
|
||||||
if (Build.VERSION.SDK_INT >= 11) {
|
if (Build.VERSION.SDK_INT >= 11) {
|
||||||
return new RepoAdapter(context, cursor, flags);
|
return new RepoAdapter(context, cursor, flags);
|
||||||
} else {
|
|
||||||
return new RepoAdapter(context, cursor);
|
|
||||||
}
|
}
|
||||||
|
return new RepoAdapter(context, cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
private RepoAdapter(Context context, Cursor c, int flags) {
|
private RepoAdapter(Context context, Cursor c, int flags) {
|
||||||
|
@ -290,12 +290,10 @@ public class SwapWorkflowActivity extends AppCompatActivity {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!forceReload) {
|
if (!forceReload && (container.getVisibility() == View.GONE || currentView != null && currentView.getStep() == service.getStep())) {
|
||||||
if (container.getVisibility() == View.GONE || currentView != null && currentView.getStep() == service.getStep()) {
|
|
||||||
// Already showing the correct step, so don't bother changing anything.
|
// Already showing the correct step, so don't bother changing anything.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
switch (service.getStep()) {
|
switch (service.getStep()) {
|
||||||
case SwapService.STEP_INTRO:
|
case SwapService.STEP_INTRO:
|
||||||
|
@ -7,7 +7,3 @@ buildscript {
|
|||||||
classpath files('libs/gradle-witness.jar')
|
classpath files('libs/gradle-witness.jar')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
task wrapper(type: Wrapper) {
|
|
||||||
gradleVersion = '2.11'
|
|
||||||
}
|
|
||||||
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
5
gradle/wrapper/gradle-wrapper.properties
vendored
5
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,7 +1,6 @@
|
|||||||
#Mon Feb 15 16:30:29 GMT 2016
|
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.11-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-2.12-bin.zip
|
||||||
distributionSha256Sum=8d7437082356c9fd6309a4479c8db307673965546daea445c6c72759cd6b1ed6
|
distributionSha256Sum=e77064981906cd0476ff1e0de3e6fef747bd18e140960f1915cca8ff6c33ab5c
|
||||||
|
Loading…
x
Reference in New Issue
Block a user