[tool] Install the corresponding APK in flutter run
(#113622)
This commit is contained in:
parent
1b4b99b488
commit
3d94b8fd1d
@ -114,8 +114,8 @@ void main() {
|
|||||||
|
|
||||||
_findNextMatcherInList(
|
_findNextMatcherInList(
|
||||||
stdout,
|
stdout,
|
||||||
(String line) => line.startsWith('Installing build/app/outputs/flutter-apk/app.apk...'),
|
(String line) => line.startsWith('Installing build/app/outputs/flutter-apk/app-release.apk...'),
|
||||||
'Installing build/app/outputs/flutter-apk/app.apk...',
|
'Installing build/app/outputs/flutter-apk/app-release.apk...',
|
||||||
);
|
);
|
||||||
|
|
||||||
_findNextMatcherInList(
|
_findNextMatcherInList(
|
||||||
|
@ -103,11 +103,20 @@ class AndroidApk extends ApplicationPackage implements PrebuiltApplicationPackag
|
|||||||
required ProcessUtils processUtils,
|
required ProcessUtils processUtils,
|
||||||
required Logger logger,
|
required Logger logger,
|
||||||
required FileSystem fileSystem,
|
required FileSystem fileSystem,
|
||||||
|
BuildInfo? buildInfo,
|
||||||
}) async {
|
}) async {
|
||||||
File apkFile;
|
final File apkFile;
|
||||||
|
final String filename;
|
||||||
|
if (buildInfo == null) {
|
||||||
|
filename = 'app.apk';
|
||||||
|
} else if (buildInfo.flavor == null) {
|
||||||
|
filename = 'app-${buildInfo.mode.name}.apk';
|
||||||
|
} else {
|
||||||
|
filename = 'app-${buildInfo.lowerCasedFlavor}-${buildInfo.mode.name}.apk';
|
||||||
|
}
|
||||||
|
|
||||||
if (androidProject.isUsingGradle && androidProject.isSupportedVersion) {
|
if (androidProject.isUsingGradle && androidProject.isSupportedVersion) {
|
||||||
apkFile = getApkDirectory(androidProject.parent).childFile('app.apk');
|
apkFile = getApkDirectory(androidProject.parent).childFile(filename);
|
||||||
if (apkFile.existsSync()) {
|
if (apkFile.existsSync()) {
|
||||||
// Grab information from the .apk. The gradle build script might alter
|
// Grab information from the .apk. The gradle build script might alter
|
||||||
// the application Id, so we need to look at what was actually built.
|
// the application Id, so we need to look at what was actually built.
|
||||||
@ -124,7 +133,7 @@ class AndroidApk extends ApplicationPackage implements PrebuiltApplicationPackag
|
|||||||
// command will grab a new AndroidApk after building, to get the updated
|
// command will grab a new AndroidApk after building, to get the updated
|
||||||
// IDs.
|
// IDs.
|
||||||
} else {
|
} else {
|
||||||
apkFile = fileSystem.file(fileSystem.path.join(getAndroidBuildDirectory(), 'app.apk'));
|
apkFile = fileSystem.file(fileSystem.path.join(getAndroidBuildDirectory(), filename));
|
||||||
}
|
}
|
||||||
|
|
||||||
final File manifest = androidProject.appManifestFile;
|
final File manifest = androidProject.appManifestFile;
|
||||||
|
@ -465,41 +465,39 @@ class AndroidGradleBuilder implements AndroidBuilder {
|
|||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Gradle produced an APK.
|
// Gradle produced APKs.
|
||||||
final Iterable<String> apkFilesPaths = project.isModule
|
final Iterable<String> apkFilesPaths = project.isModule
|
||||||
? findApkFilesModule(project, androidBuildInfo, _logger, _usage)
|
? findApkFilesModule(project, androidBuildInfo, _logger, _usage)
|
||||||
: listApkPaths(androidBuildInfo);
|
: listApkPaths(androidBuildInfo);
|
||||||
final Directory apkDirectory = getApkDirectory(project);
|
final Directory apkDirectory = getApkDirectory(project);
|
||||||
final File apkFile = apkDirectory.childFile(apkFilesPaths.first);
|
|
||||||
if (!apkFile.existsSync()) {
|
// Generate sha1 for every generated APKs.
|
||||||
_exitWithExpectedFileNotFound(
|
for (final File apkFile in apkFilesPaths.map(apkDirectory.childFile)) {
|
||||||
project: project,
|
if (!apkFile.existsSync()) {
|
||||||
fileExtension: '.apk',
|
_exitWithExpectedFileNotFound(
|
||||||
logger: _logger,
|
project: project,
|
||||||
usage: _usage,
|
fileExtension: '.apk',
|
||||||
|
logger: _logger,
|
||||||
|
usage: _usage,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
final String filename = apkFile.basename;
|
||||||
|
_logger.printTrace('Calculate SHA1: $apkDirectory/$filename');
|
||||||
|
final File apkShaFile = apkDirectory.childFile('$filename.sha1');
|
||||||
|
apkShaFile.writeAsStringSync(_calculateSha(apkFile));
|
||||||
|
|
||||||
|
final String appSize = (buildInfo.mode == BuildMode.debug)
|
||||||
|
? '' // Don't display the size when building a debug variant.
|
||||||
|
: ' (${getSizeAsMB(apkFile.lengthSync())})';
|
||||||
|
_logger.printStatus(
|
||||||
|
'${_logger.terminal.successMark} Built ${_fileSystem.path.relative(apkFile.path)}$appSize.',
|
||||||
|
color: TerminalColor.green,
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
// Copy the first APK to app.apk, so `flutter run` can find it.
|
if (buildInfo.codeSizeDirectory != null) {
|
||||||
// TODO(egarciad): Handle multiple APKs.
|
await _performCodeSizeAnalysis('apk', apkFile, androidBuildInfo);
|
||||||
apkFile.copySync(apkDirectory
|
}
|
||||||
.childFile('app.apk')
|
|
||||||
.path);
|
|
||||||
_logger.printTrace('calculateSha: $apkDirectory/app.apk');
|
|
||||||
|
|
||||||
final File apkShaFile = apkDirectory.childFile('app.apk.sha1');
|
|
||||||
apkShaFile.writeAsStringSync(_calculateSha(apkFile));
|
|
||||||
|
|
||||||
final String appSize = (buildInfo.mode == BuildMode.debug)
|
|
||||||
? '' // Don't display the size when building a debug variant.
|
|
||||||
: ' (${getSizeAsMB(apkFile.lengthSync())})';
|
|
||||||
_logger.printStatus(
|
|
||||||
'${_logger.terminal.successMark} Built ${_fileSystem.path.relative(apkFile.path)}$appSize.',
|
|
||||||
color: TerminalColor.green,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (buildInfo.codeSizeDirectory != null) {
|
|
||||||
await _performCodeSizeAnalysis('apk', apkFile, androidBuildInfo);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,6 +66,7 @@ class FlutterApplicationPackageFactory extends ApplicationPackageFactory {
|
|||||||
androidSdk: _androidSdk,
|
androidSdk: _androidSdk,
|
||||||
userMessages: _userMessages,
|
userMessages: _userMessages,
|
||||||
fileSystem: _fileSystem,
|
fileSystem: _fileSystem,
|
||||||
|
buildInfo: buildInfo,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return AndroidApk.fromApk(
|
return AndroidApk.fromApk(
|
||||||
|
@ -65,7 +65,7 @@ void main() {
|
|||||||
platform: FakePlatform(),
|
platform: FakePlatform(),
|
||||||
androidSdk: androidSdk,
|
androidSdk: androidSdk,
|
||||||
);
|
);
|
||||||
final File apkFile = fileSystem.file('app.apk')..createSync();
|
final File apkFile = fileSystem.file('app-debug.apk')..createSync();
|
||||||
final AndroidApk apk = AndroidApk(
|
final AndroidApk apk = AndroidApk(
|
||||||
id: 'FlutterApp',
|
id: 'FlutterApp',
|
||||||
applicationPackage: apkFile,
|
applicationPackage: apkFile,
|
||||||
@ -88,7 +88,7 @@ void main() {
|
|||||||
command: <String>['adb', '-s', '1234', 'shell', 'pm', 'list', 'packages', 'FlutterApp'],
|
command: <String>['adb', '-s', '1234', 'shell', 'pm', 'list', 'packages', 'FlutterApp'],
|
||||||
));
|
));
|
||||||
processManager.addCommand(const FakeCommand(
|
processManager.addCommand(const FakeCommand(
|
||||||
command: <String>['adb', '-s', '1234', 'install', '-t', '-r', 'app.apk'],
|
command: <String>['adb', '-s', '1234', 'install', '-t', '-r', 'app-debug.apk'],
|
||||||
));
|
));
|
||||||
processManager.addCommand(kShaCommand);
|
processManager.addCommand(kShaCommand);
|
||||||
processManager.addCommand(const FakeCommand(
|
processManager.addCommand(const FakeCommand(
|
||||||
@ -132,7 +132,7 @@ void main() {
|
|||||||
platform: FakePlatform(),
|
platform: FakePlatform(),
|
||||||
androidSdk: androidSdk,
|
androidSdk: androidSdk,
|
||||||
);
|
);
|
||||||
final File apkFile = fileSystem.file('app.apk')..createSync();
|
final File apkFile = fileSystem.file('app-debug.apk')..createSync();
|
||||||
final AndroidApk apk = AndroidApk(
|
final AndroidApk apk = AndroidApk(
|
||||||
id: 'FlutterApp',
|
id: 'FlutterApp',
|
||||||
applicationPackage: apkFile,
|
applicationPackage: apkFile,
|
||||||
@ -170,7 +170,7 @@ void main() {
|
|||||||
platform: FakePlatform(),
|
platform: FakePlatform(),
|
||||||
androidSdk: androidSdk,
|
androidSdk: androidSdk,
|
||||||
);
|
);
|
||||||
final File apkFile = fileSystem.file('app.apk')..createSync();
|
final File apkFile = fileSystem.file('app-debug.apk')..createSync();
|
||||||
final AndroidApk apk = AndroidApk(
|
final AndroidApk apk = AndroidApk(
|
||||||
id: 'FlutterApp',
|
id: 'FlutterApp',
|
||||||
applicationPackage: apkFile,
|
applicationPackage: apkFile,
|
||||||
@ -200,7 +200,7 @@ void main() {
|
|||||||
'-r',
|
'-r',
|
||||||
'--user',
|
'--user',
|
||||||
'10',
|
'10',
|
||||||
'app.apk',
|
'app-debug.apk',
|
||||||
],
|
],
|
||||||
stdout: '\n\nThe Dart VM service is listening on http://127.0.0.1:456\n\n',
|
stdout: '\n\nThe Dart VM service is listening on http://127.0.0.1:456\n\n',
|
||||||
));
|
));
|
||||||
|
@ -31,7 +31,7 @@ const FakeCommand kInstallCommand = FakeCommand(
|
|||||||
'-r',
|
'-r',
|
||||||
'--user',
|
'--user',
|
||||||
'10',
|
'10',
|
||||||
'app.apk',
|
'app-debug.apk',
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
const FakeCommand kStoreShaCommand = FakeCommand(
|
const FakeCommand kStoreShaCommand = FakeCommand(
|
||||||
@ -71,7 +71,7 @@ void main() {
|
|||||||
stdout: '[ro.build.version.sdk]: [11]',
|
stdout: '[ro.build.version.sdk]: [11]',
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
final File apk = fileSystem.file('app.apk')..createSync();
|
final File apk = fileSystem.file('app-debug.apk')..createSync();
|
||||||
final AndroidApk androidApk = AndroidApk(
|
final AndroidApk androidApk = AndroidApk(
|
||||||
applicationPackage: apk,
|
applicationPackage: apk,
|
||||||
id: 'app',
|
id: 'app',
|
||||||
@ -87,7 +87,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWithoutContext('Cannot install app if APK file is missing', () async {
|
testWithoutContext('Cannot install app if APK file is missing', () async {
|
||||||
final File apk = fileSystem.file('app.apk');
|
final File apk = fileSystem.file('app-debug.apk');
|
||||||
final AndroidApk androidApk = AndroidApk(
|
final AndroidApk androidApk = AndroidApk(
|
||||||
applicationPackage: apk,
|
applicationPackage: apk,
|
||||||
id: 'app',
|
id: 'app',
|
||||||
@ -115,7 +115,7 @@ void main() {
|
|||||||
kInstallCommand,
|
kInstallCommand,
|
||||||
kStoreShaCommand,
|
kStoreShaCommand,
|
||||||
]);
|
]);
|
||||||
final File apk = fileSystem.file('app.apk')..createSync();
|
final File apk = fileSystem.file('app-debug.apk')..createSync();
|
||||||
final AndroidApk androidApk = AndroidApk(
|
final AndroidApk androidApk = AndroidApk(
|
||||||
applicationPackage: apk,
|
applicationPackage: apk,
|
||||||
id: 'app',
|
id: 'app',
|
||||||
@ -144,7 +144,7 @@ void main() {
|
|||||||
kInstallCommand,
|
kInstallCommand,
|
||||||
kStoreShaCommand,
|
kStoreShaCommand,
|
||||||
]);
|
]);
|
||||||
final File apk = fileSystem.file('app.apk')..createSync();
|
final File apk = fileSystem.file('app-debug.apk')..createSync();
|
||||||
final AndroidApk androidApk = AndroidApk(
|
final AndroidApk androidApk = AndroidApk(
|
||||||
applicationPackage: apk,
|
applicationPackage: apk,
|
||||||
id: 'app',
|
id: 'app',
|
||||||
@ -182,13 +182,13 @@ void main() {
|
|||||||
'-r',
|
'-r',
|
||||||
'--user',
|
'--user',
|
||||||
'jane',
|
'jane',
|
||||||
'app.apk',
|
'app-debug.apk',
|
||||||
],
|
],
|
||||||
exitCode: 1,
|
exitCode: 1,
|
||||||
stderr: 'Exception occurred while executing: java.lang.IllegalArgumentException: Bad user number: jane',
|
stderr: 'Exception occurred while executing: java.lang.IllegalArgumentException: Bad user number: jane',
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
final File apk = fileSystem.file('app.apk')..createSync();
|
final File apk = fileSystem.file('app-debug.apk')..createSync();
|
||||||
final AndroidApk androidApk = AndroidApk(
|
final AndroidApk androidApk = AndroidApk(
|
||||||
applicationPackage: apk,
|
applicationPackage: apk,
|
||||||
id: 'app',
|
id: 'app',
|
||||||
@ -221,8 +221,8 @@ void main() {
|
|||||||
stdout: 'example_sha',
|
stdout: 'example_sha',
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
final File apk = fileSystem.file('app.apk')..createSync();
|
final File apk = fileSystem.file('app-debug.apk')..createSync();
|
||||||
fileSystem.file('app.apk.sha1').writeAsStringSync('example_sha');
|
fileSystem.file('app-debug.apk.sha1').writeAsStringSync('example_sha');
|
||||||
final AndroidApk androidApk = AndroidApk(
|
final AndroidApk androidApk = AndroidApk(
|
||||||
applicationPackage: apk,
|
applicationPackage: apk,
|
||||||
id: 'app',
|
id: 'app',
|
||||||
@ -254,7 +254,7 @@ void main() {
|
|||||||
stdout: 'different_example_sha',
|
stdout: 'different_example_sha',
|
||||||
),
|
),
|
||||||
const FakeCommand(
|
const FakeCommand(
|
||||||
command: <String>['adb', '-s', '1234', 'install', '-t', '-r', '--user', '10', 'app.apk'],
|
command: <String>['adb', '-s', '1234', 'install', '-t', '-r', '--user', '10', 'app-debug.apk'],
|
||||||
exitCode: 1,
|
exitCode: 1,
|
||||||
stderr: '[INSTALL_FAILED_INSUFFICIENT_STORAGE]',
|
stderr: '[INSTALL_FAILED_INSUFFICIENT_STORAGE]',
|
||||||
),
|
),
|
||||||
@ -262,8 +262,8 @@ void main() {
|
|||||||
kInstallCommand,
|
kInstallCommand,
|
||||||
const FakeCommand(command: <String>['adb', '-s', '1234', 'shell', 'echo', '-n', 'example_sha', '>', '/data/local/tmp/sky.app.sha1']),
|
const FakeCommand(command: <String>['adb', '-s', '1234', 'shell', 'echo', '-n', 'example_sha', '>', '/data/local/tmp/sky.app.sha1']),
|
||||||
]);
|
]);
|
||||||
final File apk = fileSystem.file('app.apk')..createSync();
|
final File apk = fileSystem.file('app-debug.apk')..createSync();
|
||||||
fileSystem.file('app.apk.sha1').writeAsStringSync('example_sha');
|
fileSystem.file('app-debug.apk.sha1').writeAsStringSync('example_sha');
|
||||||
final AndroidApk androidApk = AndroidApk(
|
final AndroidApk androidApk = AndroidApk(
|
||||||
applicationPackage: apk,
|
applicationPackage: apk,
|
||||||
id: 'app',
|
id: 'app',
|
||||||
@ -291,12 +291,12 @@ void main() {
|
|||||||
stdout: '\n'
|
stdout: '\n'
|
||||||
),
|
),
|
||||||
const FakeCommand(
|
const FakeCommand(
|
||||||
command: <String>['adb', '-s', '1234', 'install', '-t', '-r', '--user', '10', 'app.apk'],
|
command: <String>['adb', '-s', '1234', 'install', '-t', '-r', '--user', '10', 'app-debug.apk'],
|
||||||
exitCode: 1,
|
exitCode: 1,
|
||||||
stderr: '[INSTALL_FAILED_INSUFFICIENT_STORAGE]',
|
stderr: '[INSTALL_FAILED_INSUFFICIENT_STORAGE]',
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
final File apk = fileSystem.file('app.apk')..createSync();
|
final File apk = fileSystem.file('app-debug.apk')..createSync();
|
||||||
final AndroidApk androidApk = AndroidApk(
|
final AndroidApk androidApk = AndroidApk(
|
||||||
applicationPackage: apk,
|
applicationPackage: apk,
|
||||||
id: 'app',
|
id: 'app',
|
||||||
|
@ -121,6 +121,20 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
group('listApkPaths', () {
|
group('listApkPaths', () {
|
||||||
|
testWithoutContext('Finds APK without flavor in debug', () {
|
||||||
|
final Iterable<String> apks = listApkPaths(
|
||||||
|
const AndroidBuildInfo(BuildInfo(BuildMode.debug, '', treeShakeIcons: false)),
|
||||||
|
);
|
||||||
|
expect(apks, <String>['app-debug.apk']);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWithoutContext('Finds APK with flavor in debug', () {
|
||||||
|
final Iterable<String> apks = listApkPaths(
|
||||||
|
const AndroidBuildInfo(BuildInfo(BuildMode.debug, 'flavor1', treeShakeIcons: false)),
|
||||||
|
);
|
||||||
|
expect(apks, <String>['app-flavor1-debug.apk']);
|
||||||
|
});
|
||||||
|
|
||||||
testWithoutContext('Finds APK without flavor in release', () {
|
testWithoutContext('Finds APK without flavor in release', () {
|
||||||
final Iterable<String> apks = listApkPaths(
|
final Iterable<String> apks = listApkPaths(
|
||||||
const AndroidBuildInfo(BuildInfo(BuildMode.release, '', treeShakeIcons: false)),
|
const AndroidBuildInfo(BuildInfo(BuildMode.release, '', treeShakeIcons: false)),
|
||||||
|
@ -57,7 +57,7 @@ void main() {
|
|||||||
|
|
||||||
testUsingContext('Licenses not available, platform and buildtools available, apk exists', () async {
|
testUsingContext('Licenses not available, platform and buildtools available, apk exists', () async {
|
||||||
const String aaptPath = 'aaptPath';
|
const String aaptPath = 'aaptPath';
|
||||||
final File apkFile = globals.fs.file('app.apk');
|
final File apkFile = globals.fs.file('app-debug.apk');
|
||||||
final FakeAndroidSdkVersion sdkVersion = FakeAndroidSdkVersion();
|
final FakeAndroidSdkVersion sdkVersion = FakeAndroidSdkVersion();
|
||||||
sdkVersion.aaptPath = aaptPath;
|
sdkVersion.aaptPath = aaptPath;
|
||||||
sdk.latestVersion = sdkVersion;
|
sdk.latestVersion = sdkVersion;
|
||||||
@ -81,7 +81,7 @@ void main() {
|
|||||||
TargetPlatform.android_arm,
|
TargetPlatform.android_arm,
|
||||||
applicationBinary: apkFile,
|
applicationBinary: apkFile,
|
||||||
))!;
|
))!;
|
||||||
expect(applicationPackage.name, 'app.apk');
|
expect(applicationPackage.name, 'app-debug.apk');
|
||||||
expect(applicationPackage, isA<PrebuiltApplicationPackage>());
|
expect(applicationPackage, isA<PrebuiltApplicationPackage>());
|
||||||
expect((applicationPackage as PrebuiltApplicationPackage).applicationPackage.path, apkFile.path);
|
expect((applicationPackage as PrebuiltApplicationPackage).applicationPackage.path, apkFile.path);
|
||||||
expect(fakeProcessManager, hasNoRemainingExpectations);
|
expect(fakeProcessManager, hasNoRemainingExpectations);
|
||||||
@ -103,7 +103,7 @@ void main() {
|
|||||||
|
|
||||||
await ApplicationPackageFactory.instance!.getPackageForPlatform(
|
await ApplicationPackageFactory.instance!.getPackageForPlatform(
|
||||||
TargetPlatform.android_arm,
|
TargetPlatform.android_arm,
|
||||||
applicationBinary: globals.fs.file('app.apk'),
|
applicationBinary: globals.fs.file('app-debug.apk'),
|
||||||
);
|
);
|
||||||
expect(fakeProcessManager, hasNoRemainingExpectations);
|
expect(fakeProcessManager, hasNoRemainingExpectations);
|
||||||
}, overrides: overrides);
|
}, overrides: overrides);
|
||||||
|
@ -312,7 +312,7 @@ void main() {
|
|||||||
<FlutterDevice>[
|
<FlutterDevice>[
|
||||||
flutterDevice,
|
flutterDevice,
|
||||||
],
|
],
|
||||||
applicationBinary: globals.fs.file('app.apk'),
|
applicationBinary: globals.fs.file('app-debug.apk'),
|
||||||
stayResident: false,
|
stayResident: false,
|
||||||
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
|
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
|
||||||
target: 'main.dart',
|
target: 'main.dart',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user