Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[GSoC] Android App Bundles #2237

Merged
merged 20 commits into from Jan 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -683,4 +683,10 @@ public interface Images extends Resources {
*/
@Source("com/google/appinventor/images/YRLogo.png")
ImageResource YRLogo();

/**
* Download app icon
*/
@Source("com/google/appinventor/images/get-app.png")
ImageResource GetApp();
}
Expand Up @@ -2270,7 +2270,7 @@ public void onSuccess(Void result) {
* @return nonce
*/
public String generateNonce() {
int v = random.nextInt(1000000);
int v = random.nextInt(10000000);
nonce = Integer.toString(v, 36); // Base 36 string
return nonce;
}
Expand Down
Expand Up @@ -625,21 +625,21 @@ public interface OdeMessages extends Messages, AutogeneratedOdeMessages {
@Description("Label of the button leading to build related cascade items")
String buildTabName();

@DefaultMessage("App ( provide QR code for .apk )")
@Description("Label of item for building a project and show barcode")
String showBarcodeMenuItem();
@DefaultMessage("Android App (.apk)")
@Description("Label of item for building a project as apk and showing the qr+download dialog")
String showExportAndroidApk();

@DefaultMessage("App for Google Play ( provide QR code for .apk )")
@Description("Label of item for building a project and show barcode")
String showBarcodeMenuItem2();
@DefaultMessage("[2] Android App (.apk)")
@Description("Label of item for building a project as apk and showing the qr+download dialog")
String showExportAndroidApk2();

@DefaultMessage("App ( save .apk to my computer )")
@Description("Label of item for building a project and downloading")
String downloadToComputerMenuItem();
@DefaultMessage("Android App Bundle (.aab)")
@Description("Label of item for building a project as aab and showing the qr+download dialog")
String showExportAndroidAab();

@DefaultMessage("App for Google Play ( save .apk to my computer )")
@Description("Label of item for building a project and downloading")
String downloadToComputerMenuItem2();
@DefaultMessage("[2] Android App Bundle (.aab)")
@Description("Label of item for building a project as aab and showing the qr+download dialog")
String showExportAndroidAab2();

@DefaultMessage("Generate YAIL")
@Description("Label of the cascade item for generating YAIL for a project")
Expand Down Expand Up @@ -1497,15 +1497,33 @@ public interface OdeMessages extends Messages, AutogeneratedOdeMessages {

// Used in explorer/commands/ShowBarcodeCommand.java

@DefaultMessage("Barcode link for {0}")
@Description("Title of barcode dialog.")
String barcodeTitle(String projectName);
@DefaultMessage("Android App for {0}")
@Description("Title of download apk dialog.")
String downloadApkDialogTitle(String projectName);

@DefaultMessage("Android App Bundle for {0} (to be used in Google Play Store)")
@Description("Title of download aab dialog.")
String downloadAabDialogTitle(String projectName);

@DefaultMessage("Download .apk now")
@Description("Download button shown in barcode dialog")
String barcodeDownloadApk();

@DefaultMessage("Download .aab now")
@Description("Download button shown in barcode dialog")
String barcodeDownloadAab();

@DefaultMessage("Note: this barcode is only valid for 2 hours. See {0} the FAQ {1} for info " +
"on how to share your app with others.")
@Description("Warning in barcode dialog.")
String barcodeWarning(String aTagStart, String aTagEnd);

@DefaultMessage("<b>Click the button to download the app, right-click on it to copy a download link, or scan the " +
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something we should check is whether this affects the translations. If so, we may want to keep it as two separate strings so we can reuse the existing translations.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May want to check the other entries for issues as well.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Humm, it will probably show the older version in the other languages until someone manually changes it. I have now moved it into a barcodeWarning2 key, to always force to display the updated one (although it will require a translation anyway) and don't show different content depending on language.

"code with a barcode scanner to install.</b><br>" +
"Note: this link and barcode are only valid for 2 hours. See {0} the FAQ {1} for info on how to share your " +
"app with others.")
@Description("Warning in barcode dialog.")
String barcodeWarning2(String aTagStart, String aTagEnd);

// Used in explorer/project/Project.java

@DefaultMessage("Server error: could not load project. Please try again later!")
Expand Down
Expand Up @@ -76,10 +76,10 @@ public class TopToolbar extends Composite {
private static final String WIDGET_NAME_CHECKPOINT = "Checkpoint";
private static final String WIDGET_NAME_MY_PROJECTS = "MyProjects";
private static final String WIDGET_NAME_BUILD = "Build";
private static final String WIDGET_NAME_BUILD_BARCODE = "Barcode";
private static final String WIDGET_NAME_BUILD_DOWNLOAD = "Download";
private static final String WIDGET_NAME_BUILD_BARCODE2 = "Barcode2";
private static final String WIDGET_NAME_BUILD_DOWNLOAD2 = "Download2";
private static final String WIDGET_NAME_BUILD_ANDROID_APK = "BuildApk";
private static final String WIDGET_NAME_BUILD_ANDROID_AAB = "BuildAab";
private static final String WIDGET_NAME_BUILD_ANDROID_APK2 = "BuildApk2";
private static final String WIDGET_NAME_BUILD_ANDROID_AAB2 = "BuildAab2";
private static final String WIDGET_NAME_BUILD_YAIL = "Yail";
private static final String WIDGET_NAME_CONNECT_TO = "ConnectTo";
private static final String WIDGET_NAME_WIRELESS_BUTTON = "Wireless";
Expand Down Expand Up @@ -293,10 +293,10 @@ private void createConnectMenu() {

private void createBuildMenu() {
List<DropDownItem> buildItems = Lists.newArrayList();
buildItems.add(new DropDownItem(WIDGET_NAME_BUILD_BARCODE, MESSAGES.showBarcodeMenuItem(),
new BarcodeAction(false)));
buildItems.add(new DropDownItem(WIDGET_NAME_BUILD_DOWNLOAD, MESSAGES.downloadToComputerMenuItem(),
new DownloadAction(false)));
buildItems.add(new DropDownItem(WIDGET_NAME_BUILD_ANDROID_APK, MESSAGES.showExportAndroidApk(),
new BarcodeAction(false, false)));
buildItems.add(new DropDownItem(WIDGET_NAME_BUILD_ANDROID_AAB, MESSAGES.showExportAndroidAab(),
new BarcodeAction(false, true)));

// Second Buildserver Menu Items
//
Expand All @@ -314,10 +314,10 @@ private void createBuildMenu() {

if (Ode.getInstance().hasSecondBuildserver()) {
buildItems.add(null);
buildItems.add(new DropDownItem(WIDGET_NAME_BUILD_BARCODE2, MESSAGES.showBarcodeMenuItem2(),
new BarcodeAction(true)));
buildItems.add(new DropDownItem(WIDGET_NAME_BUILD_DOWNLOAD2, MESSAGES.downloadToComputerMenuItem2(),
new DownloadAction(true)));
buildItems.add(new DropDownItem(WIDGET_NAME_BUILD_ANDROID_APK2, MESSAGES.showExportAndroidApk2(),
new BarcodeAction(true, false)));
buildItems.add(new DropDownItem(WIDGET_NAME_BUILD_ANDROID_AAB2, MESSAGES.showExportAndroidAab2(),
new BarcodeAction(true, true)));
}

if (AppInventorFeatures.hasYailGenerationOption() && Ode.getInstance().getUser().getIsAdmin()) {
Expand Down Expand Up @@ -538,9 +538,11 @@ public void execute() {
private class BarcodeAction implements Command {

private boolean secondBuildserver = false;
private boolean isAab;

public BarcodeAction(boolean secondBuildserver) {
public BarcodeAction(boolean secondBuildserver, boolean isAab) {
this.secondBuildserver = secondBuildserver;
this.isAab = isAab;
}

@Override
Expand All @@ -550,10 +552,10 @@ public void execute() {
String target = YoungAndroidProjectNode.YOUNG_ANDROID_TARGET_ANDROID;
ChainableCommand cmd = new SaveAllEditorsCommand(
new GenerateYailCommand(
new BuildCommand(target, secondBuildserver,
new BuildCommand(target, secondBuildserver, isAab,
new ShowProgressBarCommand(target,
new WaitForBuildResultCommand(target,
new ShowBarcodeCommand(target)), "BarcodeAction"))));
new ShowBarcodeCommand(target, isAab)), "BarcodeAction"))));
if (!Ode.getInstance().getWarnBuild(secondBuildserver)) {
cmd = new WarningDialogCommand(target, secondBuildserver, cmd);
Ode.getInstance().setWarnBuild(secondBuildserver, true);
Expand All @@ -568,38 +570,6 @@ public void execute() {
}
}

private class DownloadAction implements Command {

private boolean secondBuildserver = false;

DownloadAction(boolean secondBuildserver) {
this.secondBuildserver = secondBuildserver;
}

@Override
public void execute() {
ProjectRootNode projectRootNode = Ode.getInstance().getCurrentYoungAndroidProjectRootNode();
if (projectRootNode != null) {
String target = YoungAndroidProjectNode.YOUNG_ANDROID_TARGET_ANDROID;
ChainableCommand cmd = new SaveAllEditorsCommand(
new GenerateYailCommand(
new BuildCommand(target, secondBuildserver,
new ShowProgressBarCommand(target,
new WaitForBuildResultCommand(target,
new DownloadProjectOutputCommand(target)), "DownloadAction"))));
if (!Ode.getInstance().getWarnBuild(secondBuildserver)) {
cmd = new WarningDialogCommand(target, secondBuildserver, cmd);
Ode.getInstance().setWarnBuild(secondBuildserver, true);
}
cmd.startExecuteChain(Tracking.PROJECT_ACTION_BUILD_DOWNLOAD_YA, projectRootNode,
new Command() {
@Override
public void execute() {
}
});
}
}
}
private static class ExportProjectAction implements Command {
@Override
public void execute() {
Expand Down Expand Up @@ -1104,8 +1074,12 @@ public void updateFileMenuButtons(int view) {
fileDropDown.setItemEnabled(MESSAGES.saveMenuItem(), false);
fileDropDown.setItemEnabled(MESSAGES.saveAsMenuItem(), false);
fileDropDown.setItemEnabled(MESSAGES.checkpointMenuItem(), false);
buildDropDown.setItemEnabled(MESSAGES.showBarcodeMenuItem(), false);
buildDropDown.setItemEnabled(MESSAGES.downloadToComputerMenuItem(), false);
buildDropDown.setItemEnabled(MESSAGES.showExportAndroidApk(), false);
buildDropDown.setItemEnabled(MESSAGES.showExportAndroidAab(), false);
if (Ode.getInstance().hasSecondBuildserver()) {
buildDropDown.setItemEnabled(MESSAGES.showExportAndroidApk2(), false);
buildDropDown.setItemEnabled(MESSAGES.showExportAndroidAab2(), false);
}
} else { // We have to be in the Designer/Blocks view
fileDropDown.setItemEnabled(MESSAGES.deleteProjectButton(), true);
fileDropDown.setItemEnabled(MESSAGES.trashProjectMenuItem(), true);
Expand All @@ -1115,8 +1089,12 @@ public void updateFileMenuButtons(int view) {
fileDropDown.setItemEnabled(MESSAGES.saveMenuItem(), true);
fileDropDown.setItemEnabled(MESSAGES.saveAsMenuItem(), true);
fileDropDown.setItemEnabled(MESSAGES.checkpointMenuItem(), true);
buildDropDown.setItemEnabled(MESSAGES.showBarcodeMenuItem(), true);
buildDropDown.setItemEnabled(MESSAGES.downloadToComputerMenuItem(), true);
buildDropDown.setItemEnabled(MESSAGES.showExportAndroidApk(), true);
buildDropDown.setItemEnabled(MESSAGES.showExportAndroidAab(), true);
if (Ode.getInstance().hasSecondBuildserver()) {
buildDropDown.setItemEnabled(MESSAGES.showExportAndroidApk2(), true);
buildDropDown.setItemEnabled(MESSAGES.showExportAndroidAab2(), true);
}
}
updateKeystoreFileMenuButtons(true);
}
Expand Down
Expand Up @@ -31,14 +31,15 @@ public class BuildCommand extends ChainableCommand {

// Whether or not to use the second buildserver
private boolean secondBuildserver = false;
private boolean isAab;

/**
* Creates a new build command.
*
* @param target the build target
*/
public BuildCommand(String target, boolean secondBuildserver) {
this(target, secondBuildserver, null);
public BuildCommand(String target, boolean secondBuildserver, boolean isAab) {
this(target, secondBuildserver, isAab, null);
}

/**
Expand All @@ -48,8 +49,9 @@ public BuildCommand(String target, boolean secondBuildserver) {
* @param target the build target
* @param nextCommand the command to execute after the build has finished
*/
public BuildCommand(String target, boolean secondBuildserver, ChainableCommand nextCommand) {
public BuildCommand(String target, boolean secondBuildserver, boolean isAab, ChainableCommand nextCommand) {
super(nextCommand);
this.isAab = isAab;
this.target = target;
this.secondBuildserver = secondBuildserver;
}
Expand Down Expand Up @@ -126,6 +128,6 @@ public void onFailure(Throwable caught) {
};

String nonce = ode.generateNonce();
ode.getProjectService().build(node.getProjectId(), nonce, target, secondBuildserver, callback);
ode.getProjectService().build(node.getProjectId(), nonce, target, secondBuildserver, isAab, callback);
}
}