[Android] Decouple Play Core dependency to bring app into compliance for F-Droid (#13830)

This commit is contained in:
Braden Farmer 2022-04-05 00:38:54 -06:00 committed by GitHub
parent fb2da8e8fd
commit ee6c9384e9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 178 additions and 78 deletions

View file

@ -1,15 +1,9 @@
package com.retroarch.browser.retroactivity;
import com.google.android.play.core.splitinstall.SplitInstallManager;
import com.google.android.play.core.splitinstall.SplitInstallManagerFactory;
import com.google.android.play.core.splitinstall.SplitInstallRequest;
import com.google.android.play.core.splitinstall.SplitInstallSessionState;
import com.google.android.play.core.splitinstall.SplitInstallStateUpdatedListener;
import com.google.android.play.core.splitinstall.model.SplitInstallSessionStatus;
import com.google.android.play.core.tasks.OnFailureListener;
import com.google.android.play.core.tasks.OnSuccessListener;
import com.retroarch.BuildConfig;
import com.retroarch.browser.preferences.util.UserPreferences;
import com.retroarch.playcore.PlayCoreManager;
import android.annotation.TargetApi;
import android.app.NativeActivity;
import android.content.res.Configuration;
@ -38,7 +32,6 @@ import android.util.Log;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.Locale;
@ -63,58 +56,21 @@ public class RetroActivityCommon extends NativeActivity
public static int FRONTEND_ORIENTATION_270 = 3;
public static int RETRO_RUMBLE_STRONG = 0;
public static int RETRO_RUMBLE_WEAK = 1;
public static int INSTALL_STATUS_DOWNLOADING = 0;
public static int INSTALL_STATUS_INSTALLING = 1;
public static int INSTALL_STATUS_INSTALLED = 2;
public static int INSTALL_STATUS_FAILED = 3;
public boolean sustainedPerformanceMode = true;
public int screenOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
private final SplitInstallStateUpdatedListener listener = new SplitInstallStateUpdatedListener() {
@Override
public void onStateUpdate(SplitInstallSessionState state) {
List<String> moduleNames = state.moduleNames();
String[] coreNames = new String[moduleNames.size()];
for(int i = 0; i < moduleNames.size(); i++) {
coreNames[i] = unsanitizeCoreName(moduleNames.get(i));
}
switch(state.status()) {
case SplitInstallSessionStatus.DOWNLOADING:
coreInstallStatusChanged(coreNames, INSTALL_STATUS_DOWNLOADING, state.bytesDownloaded(), state.totalBytesToDownload());
break;
case SplitInstallSessionStatus.INSTALLING:
coreInstallStatusChanged(coreNames, INSTALL_STATUS_INSTALLING, state.bytesDownloaded(), state.totalBytesToDownload());
break;
case SplitInstallSessionStatus.INSTALLED:
updateSymlinks();
coreInstallStatusChanged(coreNames, INSTALL_STATUS_INSTALLED, state.bytesDownloaded(), state.totalBytesToDownload());
break;
case SplitInstallSessionStatus.FAILED:
coreInstallStatusChanged(coreNames, INSTALL_STATUS_FAILED, state.bytesDownloaded(), state.totalBytesToDownload());
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
cleanupSymlinks();
updateSymlinks();
SplitInstallManager manager = SplitInstallManagerFactory.create(this);
manager.registerListener(listener);
PlayCoreManager.getInstance().onCreate(this);
super.onCreate(savedInstanceState);
}
@Override
protected void onDestroy() {
SplitInstallManager manager = SplitInstallManagerFactory.create(this);
manager.unregisterListener(listener);
PlayCoreManager.getInstance().onDestroy();
super.onDestroy();
}
@ -442,8 +398,7 @@ public class RetroActivityCommon extends NativeActivity
* @return the list of installed cores
*/
public String[] getInstalledCores() {
SplitInstallManager manager = SplitInstallManagerFactory.create(this);
String[] modules = manager.getInstalledModules().toArray(new String[0]);
String[] modules = PlayCoreManager.getInstance().getInstalledModules();
List<String> cores = new ArrayList<>();
List<String> availableCores = Arrays.asList(getAvailableCores());
@ -473,25 +428,7 @@ public class RetroActivityCommon extends NativeActivity
SharedPreferences prefs = UserPreferences.getPreferences(this);
prefs.edit().remove("core_deleted_" + coreName).apply();
SplitInstallManager manager = SplitInstallManagerFactory.create(this);
SplitInstallRequest request = SplitInstallRequest.newBuilder()
.addModule(sanitizeCoreName(coreName))
.build();
manager.startInstall(request)
.addOnSuccessListener(new OnSuccessListener<Integer>() {
@Override
public void onSuccess(Integer result) {
coreInstallInitiated(coreName, true);
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
coreInstallInitiated(coreName, false);
}
});
PlayCoreManager.getInstance().downloadCore(coreName);
}
/**
@ -511,8 +448,7 @@ public class RetroActivityCommon extends NativeActivity
SharedPreferences prefs = UserPreferences.getPreferences(this);
prefs.edit().putBoolean("core_deleted_" + coreName, true).apply();
SplitInstallManager manager = SplitInstallManagerFactory.create(this);
manager.deferredUninstall(Collections.singletonList(sanitizeCoreName(coreName)));
PlayCoreManager.getInstance().deleteCore(coreName);
}
@ -527,7 +463,7 @@ public class RetroActivityCommon extends NativeActivity
* @param coreName Name of the core that the install is initiated for.
* @param successful true if success, false if failure
*/
private native void coreInstallInitiated(String coreName, boolean successful);
public native void coreInstallInitiated(String coreName, boolean successful);
/**
* Called when the status of a core install has changed.
@ -538,7 +474,7 @@ public class RetroActivityCommon extends NativeActivity
* @param bytesDownloaded Number of bytes downloaded.
* @param totalBytesToDownload Total number of bytes to download.
*/
private native void coreInstallStatusChanged(String[] coreNames, int status, long bytesDownloaded, long totalBytesToDownload);
public native void coreInstallStatusChanged(String[] coreNames, int status, long bytesDownloaded, long totalBytesToDownload);
@ -554,7 +490,7 @@ public class RetroActivityCommon extends NativeActivity
* @param coreName Name of the core to sanitize.
* @return The sanitized core name.
*/
private String sanitizeCoreName(String coreName) {
public String sanitizeCoreName(String coreName) {
return "core_" + coreName.replace('-', '_');
}
@ -564,7 +500,7 @@ public class RetroActivityCommon extends NativeActivity
* @param coreName Name of the core to unsanitize.
* @return The unsanitized core name.
*/
private String unsanitizeCoreName(String coreName) {
public String unsanitizeCoreName(String coreName) {
if(coreName.equals("core_mesen_s")) {
return "mesen-s";
}
@ -605,7 +541,7 @@ public class RetroActivityCommon extends NativeActivity
* Triggers a symlink update in the known places that Dynamic Feature Modules
* are installed to.
*/
private void updateSymlinks() {
public void updateSymlinks() {
if(!isPlayStoreBuild()) return;
traverseFilesystem(getFilesDir());

View file

@ -15,7 +15,7 @@
<uses-permission android:name="android.permission.VIBRATE" />
<application
android:name="com.google.android.play.core.splitcompat.SplitCompatApplication"
android:name="com.retroarch.playcore.RetroArchApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"

View file

@ -104,9 +104,22 @@ android {
jni.srcDirs = []
res.srcDirs = ['res', '../phoenix-common/res']
}
normal {
java.srcDirs += ['../play-core-stub']
}
aarch64 {
java.srcDirs += ['../play-core-stub']
res.srcDirs = ['res', 'res64']
}
ra32 {
java.srcDirs += ['../play-core-stub']
}
playStoreNormal {
java.srcDirs += ['../play-core-impl']
}
playStorePlus {
java.srcDirs += ['../play-core-impl']
}
}
externalNativeBuild {
@ -140,8 +153,11 @@ android {
}
}
def playCore = 'com.google.android.play:core:1.8.0'
dependencies {
implementation 'com.google.android.play:core:1.8.0'
playStoreNormalImplementation playCore
playStorePlusImplementation playCore
}
def dynamicFeatures = file("dynamic_features.gradle")

View file

@ -0,0 +1,110 @@
package com.retroarch.playcore;
import com.google.android.play.core.splitinstall.SplitInstallManager;
import com.google.android.play.core.splitinstall.SplitInstallManagerFactory;
import com.google.android.play.core.splitinstall.SplitInstallRequest;
import com.google.android.play.core.splitinstall.SplitInstallSessionState;
import com.google.android.play.core.splitinstall.SplitInstallStateUpdatedListener;
import com.google.android.play.core.splitinstall.model.SplitInstallSessionStatus;
import com.google.android.play.core.tasks.OnFailureListener;
import com.google.android.play.core.tasks.OnSuccessListener;
import com.retroarch.browser.retroactivity.RetroActivityCommon;
import java.util.Collections;
import java.util.List;
public class PlayCoreManager {
private PlayCoreManager() {}
private RetroActivityCommon activity;
private static PlayCoreManager instance;
public static int INSTALL_STATUS_DOWNLOADING = 0;
public static int INSTALL_STATUS_INSTALLING = 1;
public static int INSTALL_STATUS_INSTALLED = 2;
public static int INSTALL_STATUS_FAILED = 3;
private final SplitInstallStateUpdatedListener listener = new SplitInstallStateUpdatedListener() {
@Override
public void onStateUpdate(SplitInstallSessionState state) {
List<String> moduleNames = state.moduleNames();
String[] coreNames = new String[moduleNames.size()];
for(int i = 0; i < moduleNames.size(); i++) {
coreNames[i] = activity.unsanitizeCoreName(moduleNames.get(i));
}
switch(state.status()) {
case SplitInstallSessionStatus.DOWNLOADING:
activity.coreInstallStatusChanged(coreNames, INSTALL_STATUS_DOWNLOADING, state.bytesDownloaded(), state.totalBytesToDownload());
break;
case SplitInstallSessionStatus.INSTALLING:
activity.coreInstallStatusChanged(coreNames, INSTALL_STATUS_INSTALLING, state.bytesDownloaded(), state.totalBytesToDownload());
break;
case SplitInstallSessionStatus.INSTALLED:
activity.updateSymlinks();
activity.coreInstallStatusChanged(coreNames, INSTALL_STATUS_INSTALLED, state.bytesDownloaded(), state.totalBytesToDownload());
break;
case SplitInstallSessionStatus.FAILED:
activity.coreInstallStatusChanged(coreNames, INSTALL_STATUS_FAILED, state.bytesDownloaded(), state.totalBytesToDownload());
break;
}
}
};
public static PlayCoreManager getInstance() {
if (instance == null) {
instance = new PlayCoreManager();
}
return instance;
}
public void onCreate(RetroActivityCommon newActivity) {
activity = newActivity;
SplitInstallManager manager = SplitInstallManagerFactory.create(activity);
manager.registerListener(listener);
}
public void onDestroy() {
SplitInstallManager manager = SplitInstallManagerFactory.create(activity);
manager.unregisterListener(listener);
activity = null;
}
public String[] getInstalledModules() {
SplitInstallManager manager = SplitInstallManagerFactory.create(activity);
return manager.getInstalledModules().toArray(new String[0]);
}
public void downloadCore(final String coreName) {
SplitInstallManager manager = SplitInstallManagerFactory.create(activity);
SplitInstallRequest request = SplitInstallRequest.newBuilder()
.addModule(activity.sanitizeCoreName(coreName))
.build();
manager.startInstall(request)
.addOnSuccessListener(new OnSuccessListener<Integer>() {
@Override
public void onSuccess(Integer result) {
activity.coreInstallInitiated(coreName, true);
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
activity.coreInstallInitiated(coreName, false);
}
});
}
public void deleteCore(String coreName) {
SplitInstallManager manager = SplitInstallManagerFactory.create(activity);
manager.deferredUninstall(Collections.singletonList(activity.sanitizeCoreName(coreName)));
}
}

View file

@ -0,0 +1,5 @@
package com.retroarch.playcore;
import com.google.android.play.core.splitcompat.SplitCompatApplication;
public class RetroArchApplication extends SplitCompatApplication {}

View file

@ -0,0 +1,28 @@
package com.retroarch.playcore;
import com.retroarch.browser.retroactivity.RetroActivityCommon;
public class PlayCoreManager {
private PlayCoreManager() {}
private static PlayCoreManager instance;
public static PlayCoreManager getInstance() {
if (instance == null) {
instance = new PlayCoreManager();
}
return instance;
}
public void onCreate(RetroActivityCommon newActivity) {}
public void onDestroy() {}
public String[] getInstalledModules() {
return new String[0];
}
public void downloadCore(final String coreName) {}
public void deleteCore(String coreName) {}
}

View file

@ -0,0 +1,5 @@
package com.retroarch.playcore;
import android.app.Application;
public class RetroArchApplication extends Application {}