2016-08-09 21:38:13 +00:00
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
2018-05-31 08:33:15 +00:00
import ' dart:convert ' ;
2019-02-23 17:56:57 +00:00
import ' dart:io ' show ProcessResult ;
2018-05-31 08:33:15 +00:00
2018-08-15 03:33:58 +00:00
import ' package:file/file.dart ' ;
import ' package:file/memory.dart ' ;
2018-11-05 15:56:30 +00:00
import ' package:flutter_tools/src/base/platform.dart ' ;
2019-02-23 17:56:57 +00:00
import ' package:flutter_tools/src/build_info.dart ' ;
import ' package:flutter_tools/src/cache.dart ' ;
2019-06-03 21:31:56 +00:00
import ' package:flutter_tools/src/fuchsia/application_package.dart ' ;
2019-02-23 17:56:57 +00:00
import ' package:flutter_tools/src/project.dart ' ;
2018-08-15 03:33:58 +00:00
import ' package:mockito/mockito.dart ' ;
2016-08-09 21:38:13 +00:00
import ' package:flutter_tools/src/application_package.dart ' ;
2019-02-23 17:56:57 +00:00
import ' package:flutter_tools/src/android/android_sdk.dart ' ;
2018-05-31 08:33:15 +00:00
import ' package:flutter_tools/src/base/context.dart ' ;
import ' package:flutter_tools/src/base/file_system.dart ' ;
import ' package:flutter_tools/src/base/logger.dart ' ;
import ' package:flutter_tools/src/base/os.dart ' ;
import ' package:flutter_tools/src/ios/ios_workflow.dart ' ;
2019-02-23 17:56:57 +00:00
import ' package:process/process.dart ' ;
2018-08-15 03:33:58 +00:00
import ' src/common.dart ' ;
2016-08-09 21:38:13 +00:00
import ' src/context.dart ' ;
2018-11-05 15:56:30 +00:00
final Generator _kNoColorTerminalPlatform = ( ) = > FakePlatform . fromPlatform ( const LocalPlatform ( ) ) . . stdoutSupportsAnsi = false ;
final Map < Type , Generator > noColorTerminalOverride = < Type , Generator > {
Platform: _kNoColorTerminalPlatform ,
} ;
2019-02-23 17:56:57 +00:00
class MockitoProcessManager extends Mock implements ProcessManager { }
class MockitoAndroidSdk extends Mock implements AndroidSdk { }
class MockitoAndroidSdkVersion extends Mock implements AndroidSdkVersion { }
2016-08-09 21:38:13 +00:00
void main ( ) {
2019-02-23 17:56:57 +00:00
group ( ' Apk with partial Android SDK works ' , ( ) {
AndroidSdk sdk ;
ProcessManager mockProcessManager ;
MemoryFileSystem fs ;
File gradle ;
final Map < Type , Generator > overrides = < Type , Generator > {
AndroidSdk: ( ) = > sdk ,
ProcessManager: ( ) = > mockProcessManager ,
FileSystem: ( ) = > fs ,
} ;
setUp ( ( ) async {
sdk = MockitoAndroidSdk ( ) ;
mockProcessManager = MockitoProcessManager ( ) ;
fs = MemoryFileSystem ( ) ;
Cache . flutterRoot = ' ../.. ' ;
when ( sdk . licensesAvailable ) . thenReturn ( true ) ;
when ( mockProcessManager . canRun ( any ) ) . thenReturn ( true ) ;
when ( mockProcessManager . run (
any ,
workingDirectory: anyNamed ( ' workingDirectory ' ) ,
environment: anyNamed ( ' environment ' ) ,
) ) . thenAnswer ( ( _ ) async = > ProcessResult ( 1 , 0 , ' stdout ' , ' stderr ' ) ) ;
when ( mockProcessManager . runSync ( any ) ) . thenReturn ( ProcessResult ( 1 , 0 , ' stdout ' , ' stderr ' ) ) ;
2019-04-29 15:21:32 +00:00
final FlutterProject project = FlutterProject . current ( ) ;
2019-02-23 17:56:57 +00:00
gradle = fs . file ( project . android . hostAppGradleRoot . childFile (
platform . isWindows ? ' gradlew.bat ' : ' gradlew ' ,
) . path ) . . createSync ( recursive: true ) ;
} ) ;
2019-03-07 18:45:29 +00:00
testUsingContext ( ' Licenses not available, platform and buildtools available, apk exists ' , ( ) async {
const String aaptPath = ' aaptPath ' ;
final File apkFile = fs . file ( ' app.apk ' ) ;
final AndroidSdkVersion sdkVersion = MockitoAndroidSdkVersion ( ) ;
when ( sdkVersion . aaptPath ) . thenReturn ( aaptPath ) ;
when ( sdk . latestVersion ) . thenReturn ( sdkVersion ) ;
when ( sdk . platformToolsAvailable ) . thenReturn ( true ) ;
when ( sdk . licensesAvailable ) . thenReturn ( false ) ;
when ( mockProcessManager . runSync (
argThat ( equals ( < String > [
aaptPath ,
' dump ' ,
' xmltree ' ,
apkFile . path ,
' AndroidManifest.xml ' ,
] ) ) ,
workingDirectory: anyNamed ( ' workingDirectory ' ) ,
environment: anyNamed ( ' environment ' ) ,
) ,
) . thenReturn ( ProcessResult ( 0 , 0 , _aaptDataWithDefaultEnabledAndMainLauncherActivity , null ) ) ;
final ApplicationPackage applicationPackage = await ApplicationPackageFactory . instance . getPackageForPlatform (
TargetPlatform . android_arm ,
applicationBinary: apkFile ,
) ;
expect ( applicationPackage . name , ' app.apk ' ) ;
} , overrides: overrides ) ;
2019-02-23 17:56:57 +00:00
testUsingContext ( ' Licenses available, build tools not, apk exists ' , ( ) async {
when ( sdk . latestVersion ) . thenReturn ( null ) ;
2019-04-29 15:21:32 +00:00
final FlutterProject project = FlutterProject . current ( ) ;
2019-02-23 17:56:57 +00:00
final File gradle = project . android . hostAppGradleRoot . childFile (
platform . isWindows ? ' gradlew.bat ' : ' gradlew ' ,
) . . createSync ( recursive: true ) ;
await ApplicationPackageFactory . instance . getPackageForPlatform (
TargetPlatform . android_arm ,
applicationBinary: fs . file ( ' app.apk ' ) ,
) ;
verify (
mockProcessManager . run (
argThat ( equals ( < String > [ gradle . path , ' dependencies ' ] ) ) ,
workingDirectory: anyNamed ( ' workingDirectory ' ) ,
environment: anyNamed ( ' environment ' ) ,
) ,
) . called ( 1 ) ;
} , overrides: overrides ) ;
testUsingContext ( ' Licenses available, build tools available, does not call gradle dependencies ' , ( ) async {
final AndroidSdkVersion sdkVersion = MockitoAndroidSdkVersion ( ) ;
when ( sdk . latestVersion ) . thenReturn ( sdkVersion ) ;
await ApplicationPackageFactory . instance . getPackageForPlatform (
TargetPlatform . android_arm ,
) ;
verifyNever (
mockProcessManager . run (
argThat ( equals ( < String > [ gradle . path , ' dependencies ' ] ) ) ,
workingDirectory: anyNamed ( ' workingDirectory ' ) ,
environment: anyNamed ( ' environment ' ) ,
) ,
) ;
} , overrides: overrides ) ;
} ) ;
2016-08-09 21:38:13 +00:00
group ( ' ApkManifestData ' , ( ) {
2019-03-21 16:11:58 +00:00
testUsingContext ( ' Parses manifest with an Activity that has enabled set to true, action set to android.intent.action.MAIN and category set to android.intent.category.LAUNCHER ' , ( ) {
2019-02-07 21:24:03 +00:00
final ApkManifestData data = ApkManifestData . parseFromXmlDump ( _aaptDataWithExplicitEnabledAndMainLauncherActivity ) ;
2016-08-09 21:38:13 +00:00
expect ( data , isNotNull ) ;
2018-06-25 11:38:08 +00:00
expect ( data . packageName , ' io.flutter.examples.hello_world ' ) ;
expect ( data . launchableActivityName , ' io.flutter.examples.hello_world.MainActivity2 ' ) ;
2019-03-21 16:11:58 +00:00
} , overrides: noColorTerminalOverride ) ;
testUsingContext ( ' Parses manifest with an Activity that has no value for its enabled field, action set to android.intent.action.MAIN and category set to android.intent.category.LAUNCHER ' , ( ) {
2019-02-07 21:24:03 +00:00
final ApkManifestData data = ApkManifestData . parseFromXmlDump ( _aaptDataWithDefaultEnabledAndMainLauncherActivity ) ;
2018-06-25 11:38:08 +00:00
expect ( data , isNotNull ) ;
expect ( data . packageName , ' io.flutter.examples.hello_world ' ) ;
expect ( data . launchableActivityName , ' io.flutter.examples.hello_world.MainActivity2 ' ) ;
2019-03-21 16:11:58 +00:00
} , overrides: noColorTerminalOverride ) ;
2019-02-07 21:24:03 +00:00
testUsingContext ( ' Error when parsing manifest with no Activity that has enabled set to true nor has no value for its enabled field ' , ( ) {
2018-06-25 11:38:08 +00:00
final ApkManifestData data = ApkManifestData . parseFromXmlDump ( _aaptDataWithNoEnabledActivity ) ;
expect ( data , isNull ) ;
2019-04-25 22:51:08 +00:00
final BufferLogger logger = context . get < Logger > ( ) ;
2018-06-25 11:38:08 +00:00
expect (
logger . errorText , ' Error running io.flutter.examples.hello_world. Default activity not found \n ' ) ;
2018-11-05 15:56:30 +00:00
} , overrides: noColorTerminalOverride ) ;
2019-02-07 21:24:03 +00:00
testUsingContext ( ' Error when parsing manifest with no Activity that has action set to android.intent.action.MAIN ' , ( ) {
final ApkManifestData data = ApkManifestData . parseFromXmlDump ( _aaptDataWithNoMainActivity ) ;
expect ( data , isNull ) ;
2019-04-25 22:51:08 +00:00
final BufferLogger logger = context . get < Logger > ( ) ;
2019-02-07 21:24:03 +00:00
expect (
logger . errorText , ' Error running io.flutter.examples.hello_world. Default activity not found \n ' ) ;
2019-03-21 16:11:58 +00:00
} , overrides: noColorTerminalOverride ) ;
2019-02-07 21:24:03 +00:00
testUsingContext ( ' Error when parsing manifest with no Activity that has category set to android.intent.category.LAUNCHER ' , ( ) {
final ApkManifestData data = ApkManifestData . parseFromXmlDump ( _aaptDataWithNoLauncherActivity ) ;
expect ( data , isNull ) ;
2019-04-25 22:51:08 +00:00
final BufferLogger logger = context . get < Logger > ( ) ;
2019-02-07 21:24:03 +00:00
expect (
logger . errorText , ' Error running io.flutter.examples.hello_world. Default activity not found \n ' ) ;
2019-03-21 16:11:58 +00:00
} , overrides: noColorTerminalOverride ) ;
2016-08-09 21:38:13 +00:00
} ) ;
2017-07-13 01:35:08 +00:00
2018-05-31 08:33:15 +00:00
group ( ' PrebuiltIOSApp ' , ( ) {
final Map < Type , Generator > overrides = < Type , Generator > {
2018-09-12 06:29:29 +00:00
FileSystem: ( ) = > MemoryFileSystem ( ) ,
2018-11-05 15:56:30 +00:00
IOSWorkflow: ( ) = > MockIosWorkFlow ( ) ,
Platform: _kNoColorTerminalPlatform ,
2019-05-30 02:04:35 +00:00
OperatingSystemUtils: ( ) = > MockOperatingSystemUtils ( ) ,
2018-05-31 08:33:15 +00:00
} ;
testUsingContext ( ' Error on non-existing file ' , ( ) {
final PrebuiltIOSApp iosApp =
2018-09-12 06:29:29 +00:00
IOSApp . fromPrebuiltApp ( fs . file ( ' not_existing.ipa ' ) ) ;
2018-05-31 08:33:15 +00:00
expect ( iosApp , isNull ) ;
2019-04-25 22:51:08 +00:00
final BufferLogger logger = context . get < Logger > ( ) ;
2018-05-31 08:33:15 +00:00
expect (
logger . errorText ,
' File "not_existing.ipa" does not exist. Use an app bundle or an ipa. \n ' ,
) ;
} , overrides: overrides ) ;
testUsingContext ( ' Error on non-app-bundle folder ' , ( ) {
fs . directory ( ' regular_folder ' ) . createSync ( ) ;
final PrebuiltIOSApp iosApp =
2018-09-12 06:29:29 +00:00
IOSApp . fromPrebuiltApp ( fs . file ( ' regular_folder ' ) ) ;
2018-05-31 08:33:15 +00:00
expect ( iosApp , isNull ) ;
2019-04-25 22:51:08 +00:00
final BufferLogger logger = context . get < Logger > ( ) ;
2018-05-31 08:33:15 +00:00
expect (
logger . errorText , ' Folder "regular_folder" is not an app bundle. \n ' ) ;
} , overrides: overrides ) ;
testUsingContext ( ' Error on no info.plist ' , ( ) {
fs . directory ( ' bundle.app ' ) . createSync ( ) ;
2018-09-12 06:29:29 +00:00
final PrebuiltIOSApp iosApp = IOSApp . fromPrebuiltApp ( fs . file ( ' bundle.app ' ) ) ;
2018-05-31 08:33:15 +00:00
expect ( iosApp , isNull ) ;
2019-04-25 22:51:08 +00:00
final BufferLogger logger = context . get < Logger > ( ) ;
2018-05-31 08:33:15 +00:00
expect (
logger . errorText ,
' Invalid prebuilt iOS app. Does not contain Info.plist. \n ' ,
) ;
} , overrides: overrides ) ;
testUsingContext ( ' Error on bad info.plist ' , ( ) {
fs . directory ( ' bundle.app ' ) . createSync ( ) ;
fs . file ( ' bundle.app/Info.plist ' ) . writeAsStringSync ( badPlistData ) ;
2018-09-12 06:29:29 +00:00
final PrebuiltIOSApp iosApp = IOSApp . fromPrebuiltApp ( fs . file ( ' bundle.app ' ) ) ;
2018-05-31 08:33:15 +00:00
expect ( iosApp , isNull ) ;
2019-04-25 22:51:08 +00:00
final BufferLogger logger = context . get < Logger > ( ) ;
2018-05-31 08:33:15 +00:00
expect (
logger . errorText ,
contains (
' Invalid prebuilt iOS app. Info.plist does not contain bundle identifier \n ' ) ,
) ;
} , overrides: overrides ) ;
testUsingContext ( ' Success with app bundle ' , ( ) {
fs . directory ( ' bundle.app ' ) . createSync ( ) ;
fs . file ( ' bundle.app/Info.plist ' ) . writeAsStringSync ( plistData ) ;
2018-09-12 06:29:29 +00:00
final PrebuiltIOSApp iosApp = IOSApp . fromPrebuiltApp ( fs . file ( ' bundle.app ' ) ) ;
2019-04-25 22:51:08 +00:00
final BufferLogger logger = context . get < Logger > ( ) ;
2018-05-31 08:33:15 +00:00
expect ( logger . errorText , isEmpty ) ;
expect ( iosApp . bundleDir . path , ' bundle.app ' ) ;
expect ( iosApp . id , ' fooBundleId ' ) ;
expect ( iosApp . bundleName , ' bundle.app ' ) ;
} , overrides: overrides ) ;
testUsingContext ( ' Bad ipa zip-file, no payload dir ' , ( ) {
fs . file ( ' app.ipa ' ) . createSync ( ) ;
2019-03-09 08:03:11 +00:00
when ( os . unzip ( fs . file ( ' app.ipa ' ) , any ) ) . thenAnswer ( ( Invocation _ ) { } ) ;
2018-09-12 06:29:29 +00:00
final PrebuiltIOSApp iosApp = IOSApp . fromPrebuiltApp ( fs . file ( ' app.ipa ' ) ) ;
2018-05-31 08:33:15 +00:00
expect ( iosApp , isNull ) ;
2019-04-25 22:51:08 +00:00
final BufferLogger logger = context . get < Logger > ( ) ;
2018-05-31 08:33:15 +00:00
expect (
logger . errorText ,
' Invalid prebuilt iOS ipa. Does not contain a "Payload" directory. \n ' ,
) ;
} , overrides: overrides ) ;
testUsingContext ( ' Bad ipa zip-file, two app bundles ' , ( ) {
fs . file ( ' app.ipa ' ) . createSync ( ) ;
when ( os . unzip ( any , any ) ) . thenAnswer ( ( Invocation invocation ) {
final File zipFile = invocation . positionalArguments [ 0 ] ;
if ( zipFile . path ! = ' app.ipa ' ) {
return null ;
}
final Directory targetDirectory = invocation . positionalArguments [ 1 ] ;
final String bundlePath1 =
fs . path . join ( targetDirectory . path , ' Payload ' , ' bundle1.app ' ) ;
final String bundlePath2 =
fs . path . join ( targetDirectory . path , ' Payload ' , ' bundle2.app ' ) ;
fs . directory ( bundlePath1 ) . createSync ( recursive: true ) ;
fs . directory ( bundlePath2 ) . createSync ( recursive: true ) ;
} ) ;
2018-09-12 06:29:29 +00:00
final PrebuiltIOSApp iosApp = IOSApp . fromPrebuiltApp ( fs . file ( ' app.ipa ' ) ) ;
2018-05-31 08:33:15 +00:00
expect ( iosApp , isNull ) ;
2019-04-25 22:51:08 +00:00
final BufferLogger logger = context . get < Logger > ( ) ;
2018-05-31 08:33:15 +00:00
expect ( logger . errorText ,
' Invalid prebuilt iOS ipa. Does not contain a single app bundle. \n ' ) ;
} , overrides: overrides ) ;
testUsingContext ( ' Success with ipa ' , ( ) {
fs . file ( ' app.ipa ' ) . createSync ( ) ;
when ( os . unzip ( any , any ) ) . thenAnswer ( ( Invocation invocation ) {
final File zipFile = invocation . positionalArguments [ 0 ] ;
if ( zipFile . path ! = ' app.ipa ' ) {
return null ;
}
final Directory targetDirectory = invocation . positionalArguments [ 1 ] ;
final Directory bundleAppDir = fs . directory (
fs . path . join ( targetDirectory . path , ' Payload ' , ' bundle.app ' ) ) ;
bundleAppDir . createSync ( recursive: true ) ;
fs
. file ( fs . path . join ( bundleAppDir . path , ' Info.plist ' ) )
. writeAsStringSync ( plistData ) ;
} ) ;
2018-09-12 06:29:29 +00:00
final PrebuiltIOSApp iosApp = IOSApp . fromPrebuiltApp ( fs . file ( ' app.ipa ' ) ) ;
2019-04-25 22:51:08 +00:00
final BufferLogger logger = context . get < Logger > ( ) ;
2018-05-31 08:33:15 +00:00
expect ( logger . errorText , isEmpty ) ;
expect ( iosApp . bundleDir . path , endsWith ( ' bundle.app ' ) ) ;
expect ( iosApp . id , ' fooBundleId ' ) ;
expect ( iosApp . bundleName , ' bundle.app ' ) ;
} , overrides: overrides ) ;
2019-04-23 16:49:49 +00:00
testUsingContext ( ' returns null when there is no ios or .ios directory ' , ( ) async {
fs . file ( ' pubspec.yaml ' ) . createSync ( ) ;
fs . file ( ' .packages ' ) . createSync ( ) ;
2019-04-29 15:21:32 +00:00
final BuildableIOSApp iosApp = IOSApp . fromIosProject ( FlutterProject . fromDirectory ( fs . currentDirectory ) . ios ) ;
2019-04-23 16:49:49 +00:00
expect ( iosApp , null ) ;
} , overrides: overrides ) ;
2019-04-25 07:12:17 +00:00
testUsingContext ( ' returns null when there is no Runner.xcodeproj ' , ( ) async {
fs . file ( ' pubspec.yaml ' ) . createSync ( ) ;
fs . file ( ' .packages ' ) . createSync ( ) ;
fs . file ( ' ios/FooBar.xcodeproj ' ) . createSync ( recursive: true ) ;
2019-04-29 15:21:32 +00:00
final BuildableIOSApp iosApp = IOSApp . fromIosProject ( FlutterProject . fromDirectory ( fs . currentDirectory ) . ios ) ;
2019-04-25 07:12:17 +00:00
expect ( iosApp , null ) ;
} , overrides: overrides ) ;
2019-04-25 22:51:25 +00:00
testUsingContext ( ' returns null when there is no Runner.xcodeproj/project.pbxproj ' , ( ) async {
fs . file ( ' pubspec.yaml ' ) . createSync ( ) ;
fs . file ( ' .packages ' ) . createSync ( ) ;
fs . file ( ' ios/Runner.xcodeproj ' ) . createSync ( recursive: true ) ;
2019-04-29 15:21:32 +00:00
final BuildableIOSApp iosApp = IOSApp . fromIosProject ( FlutterProject . fromDirectory ( fs . currentDirectory ) . ios ) ;
2019-04-25 22:51:25 +00:00
expect ( iosApp , null ) ;
} , overrides: overrides ) ;
2018-05-31 08:33:15 +00:00
} ) ;
2019-06-03 21:31:56 +00:00
group ( ' FuchsiaApp ' , ( ) {
final Map < Type , Generator > overrides = < Type , Generator > {
FileSystem: ( ) = > MemoryFileSystem ( ) ,
Platform: _kNoColorTerminalPlatform ,
OperatingSystemUtils: ( ) = > MockOperatingSystemUtils ( ) ,
} ;
testUsingContext ( ' Error on non-existing file ' , ( ) {
final PrebuiltFuchsiaApp fuchsiaApp =
FuchsiaApp . fromPrebuiltApp ( fs . file ( ' not_existing.far ' ) ) ;
expect ( fuchsiaApp , isNull ) ;
final BufferLogger logger = context . get < Logger > ( ) ;
expect (
logger . errorText ,
' File "not_existing.far" does not exist or is not a .far file. Use far archive. \n ' ,
) ;
} , overrides: overrides ) ;
testUsingContext ( ' Error on non-far file ' , ( ) {
fs . directory ( ' regular_folder ' ) . createSync ( ) ;
final PrebuiltFuchsiaApp fuchsiaApp =
FuchsiaApp . fromPrebuiltApp ( fs . file ( ' regular_folder ' ) ) ;
expect ( fuchsiaApp , isNull ) ;
final BufferLogger logger = context . get < Logger > ( ) ;
expect (
logger . errorText ,
' File "regular_folder" does not exist or is not a .far file. Use far archive. \n ' ,
) ;
} , overrides: overrides ) ;
testUsingContext ( ' Success with far file ' , ( ) {
fs . file ( ' bundle.far ' ) . createSync ( ) ;
final PrebuiltFuchsiaApp fuchsiaApp = FuchsiaApp . fromPrebuiltApp ( fs . file ( ' bundle.far ' ) ) ;
final BufferLogger logger = context . get < Logger > ( ) ;
expect ( logger . errorText , isEmpty ) ;
expect ( fuchsiaApp . id , ' bundle.far ' ) ;
} , overrides: overrides ) ;
testUsingContext ( ' returns null when there is no fuchsia ' , ( ) async {
fs . file ( ' pubspec.yaml ' ) . createSync ( ) ;
fs . file ( ' .packages ' ) . createSync ( ) ;
final BuildableFuchsiaApp fuchsiaApp = FuchsiaApp . fromFuchsiaProject ( FlutterProject . fromDirectory ( fs . currentDirectory ) . fuchsia ) ;
expect ( fuchsiaApp , null ) ;
} , overrides: overrides ) ;
} ) ;
2016-08-09 21:38:13 +00:00
}
2019-02-07 21:24:03 +00:00
const String _aaptDataWithExplicitEnabledAndMainLauncherActivity =
2018-06-25 11:38:08 +00:00
''' N: android=http://schemas.android.com/apk/res/android
E: manifest ( line = 7 )
A: android: versionCode ( 0x0101021b ) = ( type 0x10 ) 0x1
A: android: versionName ( 0x0101021c ) = " 0.0.1 " ( Raw: " 0.0.1 " )
A: package = " io.flutter.examples.hello_world " ( Raw: " io.flutter.examples.hello_world " )
E: uses - sdk ( line = 12 )
A: android: minSdkVersion ( 0x0101020c ) = ( type 0x10 ) 0x10
A: android: targetSdkVersion ( 0x01010270 ) = ( type 0x10 ) 0x1b
E: uses - permission ( line = 21 )
A: android: name ( 0x01010003 ) = " android.permission.INTERNET " ( Raw: " android.permission.INTERNET " )
E: application ( line = 29 )
A: android: label ( 0x01010001 ) = " hello_world " ( Raw: " hello_world " )
A: android: icon ( 0x01010002 ) = @ 0x7f010000
A: android: name ( 0x01010003 ) = " io.flutter.app.FlutterApplication " ( Raw: " io.flutter.app.FlutterApplication " )
A: android: debuggable ( 0x0101000f ) = ( type 0x12 ) 0xffffffff
E: activity ( line = 34 )
A: android: theme ( 0x01010000 ) = @ 0x1030009
A: android: name ( 0x01010003 ) = " io.flutter.examples.hello_world.MainActivity " ( Raw: " io.flutter.examples.hello_world.MainActivity " )
A: android: enabled ( 0x0101000e ) = ( type 0x12 ) 0x0
A: android: launchMode ( 0x0101001d ) = ( type 0x10 ) 0x1
A: android: configChanges ( 0x0101001f ) = ( type 0x11 ) 0x400035b4
A: android: windowSoftInputMode ( 0x0101022b ) = ( type 0x11 ) 0x10
A: android: hardwareAccelerated ( 0x010102d3 ) = ( type 0x12 ) 0xffffffff
E: intent - filter ( line = 42 )
E: action ( line = 43 )
A: android: name ( 0x01010003 ) = " android.intent.action.MAIN " ( Raw: " android.intent.action.MAIN " )
E: category ( line = 45 )
A: android: name ( 0x01010003 ) = " android.intent.category.LAUNCHER " ( Raw: " android.intent.category.LAUNCHER " )
E: activity ( line = 48 )
A: android: theme ( 0x01010000 ) = @ 0x1030009
A: android: label ( 0x01010001 ) = " app2 " ( Raw: " app2 " )
A: android: name ( 0x01010003 ) = " io.flutter.examples.hello_world.MainActivity2 " ( Raw: " io.flutter.examples.hello_world.MainActivity2 " )
A: android: enabled ( 0x0101000e ) = ( type 0x12 ) 0xffffffff
E: intent - filter ( line = 53 )
E: action ( line = 54 )
A: android: name ( 0x01010003 ) = " android.intent.action.MAIN " ( Raw: " android.intent.action.MAIN " )
E: category ( line = 56 )
A: android: name ( 0x01010003 ) = " android.intent.category.LAUNCHER " ( Raw: " android.intent.category.LAUNCHER " ) ''' ;
2019-02-07 21:24:03 +00:00
const String _aaptDataWithDefaultEnabledAndMainLauncherActivity =
2018-06-25 11:38:08 +00:00
''' N: android=http://schemas.android.com/apk/res/android
E: manifest ( line = 7 )
A: android: versionCode ( 0x0101021b ) = ( type 0x10 ) 0x1
A: android: versionName ( 0x0101021c ) = " 0.0.1 " ( Raw: " 0.0.1 " )
A: package = " io.flutter.examples.hello_world " ( Raw: " io.flutter.examples.hello_world " )
E: uses - sdk ( line = 12 )
A: android: minSdkVersion ( 0x0101020c ) = ( type 0x10 ) 0x10
A: android: targetSdkVersion ( 0x01010270 ) = ( type 0x10 ) 0x1b
E: uses - permission ( line = 21 )
A: android: name ( 0x01010003 ) = " android.permission.INTERNET " ( Raw: " android.permission.INTERNET " )
E: application ( line = 29 )
A: android: label ( 0x01010001 ) = " hello_world " ( Raw: " hello_world " )
A: android: icon ( 0x01010002 ) = @ 0x7f010000
A: android: name ( 0x01010003 ) = " io.flutter.app.FlutterApplication " ( Raw: " io.flutter.app.FlutterApplication " )
A: android: debuggable ( 0x0101000f ) = ( type 0x12 ) 0xffffffff
E: activity ( line = 34 )
A: android: theme ( 0x01010000 ) = @ 0x1030009
A: android: name ( 0x01010003 ) = " io.flutter.examples.hello_world.MainActivity " ( Raw: " io.flutter.examples.hello_world.MainActivity " )
A: android: enabled ( 0x0101000e ) = ( type 0x12 ) 0x0
A: android: launchMode ( 0x0101001d ) = ( type 0x10 ) 0x1
A: android: configChanges ( 0x0101001f ) = ( type 0x11 ) 0x400035b4
A: android: windowSoftInputMode ( 0x0101022b ) = ( type 0x11 ) 0x10
A: android: hardwareAccelerated ( 0x010102d3 ) = ( type 0x12 ) 0xffffffff
E: intent - filter ( line = 42 )
E: action ( line = 43 )
A: android: name ( 0x01010003 ) = " android.intent.action.MAIN " ( Raw: " android.intent.action.MAIN " )
E: category ( line = 45 )
A: android: name ( 0x01010003 ) = " android.intent.category.LAUNCHER " ( Raw: " android.intent.category.LAUNCHER " )
E: activity ( line = 48 )
A: android: theme ( 0x01010000 ) = @ 0x1030009
A: android: label ( 0x01010001 ) = " app2 " ( Raw: " app2 " )
A: android: name ( 0x01010003 ) = " io.flutter.examples.hello_world.MainActivity2 " ( Raw: " io.flutter.examples.hello_world.MainActivity2 " )
E: intent - filter ( line = 53 )
E: action ( line = 54 )
A: android: name ( 0x01010003 ) = " android.intent.action.MAIN " ( Raw: " android.intent.action.MAIN " )
E: category ( line = 56 )
A: android: name ( 0x01010003 ) = " android.intent.category.LAUNCHER " ( Raw: " android.intent.category.LAUNCHER " ) ''' ;
const String _aaptDataWithNoEnabledActivity =
''' N: android=http://schemas.android.com/apk/res/android
E: manifest ( line = 7 )
A: android: versionCode ( 0x0101021b ) = ( type 0x10 ) 0x1
A: android: versionName ( 0x0101021c ) = " 0.0.1 " ( Raw: " 0.0.1 " )
A: package = " io.flutter.examples.hello_world " ( Raw: " io.flutter.examples.hello_world " )
E: uses - sdk ( line = 12 )
A: android: minSdkVersion ( 0x0101020c ) = ( type 0x10 ) 0x10
A: android: targetSdkVersion ( 0x01010270 ) = ( type 0x10 ) 0x1b
E: uses - permission ( line = 21 )
A: android: name ( 0x01010003 ) = " android.permission.INTERNET " ( Raw: " android.permission.INTERNET " )
E: application ( line = 29 )
A: android: label ( 0x01010001 ) = " hello_world " ( Raw: " hello_world " )
A: android: icon ( 0x01010002 ) = @ 0x7f010000
A: android: name ( 0x01010003 ) = " io.flutter.app.FlutterApplication " ( Raw: " io.flutter.app.FlutterApplication " )
A: android: debuggable ( 0x0101000f ) = ( type 0x12 ) 0xffffffff
E: activity ( line = 34 )
A: android: theme ( 0x01010000 ) = @ 0x1030009
A: android: name ( 0x01010003 ) = " io.flutter.examples.hello_world.MainActivity " ( Raw: " io.flutter.examples.hello_world.MainActivity " )
A: android: enabled ( 0x0101000e ) = ( type 0x12 ) 0x0
A: android: launchMode ( 0x0101001d ) = ( type 0x10 ) 0x1
A: android: configChanges ( 0x0101001f ) = ( type 0x11 ) 0x400035b4
A: android: windowSoftInputMode ( 0x0101022b ) = ( type 0x11 ) 0x10
A: android: hardwareAccelerated ( 0x010102d3 ) = ( type 0x12 ) 0xffffffff
E: intent - filter ( line = 42 )
E: action ( line = 43 )
A: android: name ( 0x01010003 ) = " android.intent.action.MAIN " ( Raw: " android.intent.action.MAIN " )
E: category ( line = 45 )
A: android: name ( 0x01010003 ) = " android.intent.category.LAUNCHER " ( Raw: " android.intent.category.LAUNCHER " ) ''' ;
2019-02-07 21:24:03 +00:00
const String _aaptDataWithNoMainActivity =
''' N: android=http://schemas.android.com/apk/res/android
E: manifest ( line = 7 )
A: android: versionCode ( 0x0101021b ) = ( type 0x10 ) 0x1
A: android: versionName ( 0x0101021c ) = " 0.0.1 " ( Raw: " 0.0.1 " )
A: package = " io.flutter.examples.hello_world " ( Raw: " io.flutter.examples.hello_world " )
E: uses - sdk ( line = 12 )
A: android: minSdkVersion ( 0x0101020c ) = ( type 0x10 ) 0x10
A: android: targetSdkVersion ( 0x01010270 ) = ( type 0x10 ) 0x1b
E: uses - permission ( line = 21 )
A: android: name ( 0x01010003 ) = " android.permission.INTERNET " ( Raw: " android.permission.INTERNET " )
E: application ( line = 29 )
A: android: label ( 0x01010001 ) = " hello_world " ( Raw: " hello_world " )
A: android: icon ( 0x01010002 ) = @ 0x7f010000
A: android: name ( 0x01010003 ) = " io.flutter.app.FlutterApplication " ( Raw: " io.flutter.app.FlutterApplication " )
A: android: debuggable ( 0x0101000f ) = ( type 0x12 ) 0xffffffff
E: activity ( line = 34 )
A: android: theme ( 0x01010000 ) = @ 0x1030009
A: android: name ( 0x01010003 ) = " io.flutter.examples.hello_world.MainActivity " ( Raw: " io.flutter.examples.hello_world.MainActivity " )
A: android: enabled ( 0x0101000e ) = ( type 0x12 ) 0xffffffff
A: android: launchMode ( 0x0101001d ) = ( type 0x10 ) 0x1
A: android: configChanges ( 0x0101001f ) = ( type 0x11 ) 0x400035b4
A: android: windowSoftInputMode ( 0x0101022b ) = ( type 0x11 ) 0x10
A: android: hardwareAccelerated ( 0x010102d3 ) = ( type 0x12 ) 0xffffffff
E: intent - filter ( line = 42 )
E: category ( line = 43 )
A: android: name ( 0x01010003 ) = " android.intent.category.LAUNCHER " ( Raw: " android.intent.category.LAUNCHER " ) ''' ;
const String _aaptDataWithNoLauncherActivity =
''' N: android=http://schemas.android.com/apk/res/android
E: manifest ( line = 7 )
A: android: versionCode ( 0x0101021b ) = ( type 0x10 ) 0x1
A: android: versionName ( 0x0101021c ) = " 0.0.1 " ( Raw: " 0.0.1 " )
A: package = " io.flutter.examples.hello_world " ( Raw: " io.flutter.examples.hello_world " )
E: uses - sdk ( line = 12 )
A: android: minSdkVersion ( 0x0101020c ) = ( type 0x10 ) 0x10
A: android: targetSdkVersion ( 0x01010270 ) = ( type 0x10 ) 0x1b
E: uses - permission ( line = 21 )
A: android: name ( 0x01010003 ) = " android.permission.INTERNET " ( Raw: " android.permission.INTERNET " )
E: application ( line = 29 )
A: android: label ( 0x01010001 ) = " hello_world " ( Raw: " hello_world " )
A: android: icon ( 0x01010002 ) = @ 0x7f010000
A: android: name ( 0x01010003 ) = " io.flutter.app.FlutterApplication " ( Raw: " io.flutter.app.FlutterApplication " )
A: android: debuggable ( 0x0101000f ) = ( type 0x12 ) 0xffffffff
E: activity ( line = 34 )
A: android: theme ( 0x01010000 ) = @ 0x1030009
A: android: name ( 0x01010003 ) = " io.flutter.examples.hello_world.MainActivity " ( Raw: " io.flutter.examples.hello_world.MainActivity " )
A: android: enabled ( 0x0101000e ) = ( type 0x12 ) 0xffffffff
A: android: launchMode ( 0x0101001d ) = ( type 0x10 ) 0x1
A: android: configChanges ( 0x0101001f ) = ( type 0x11 ) 0x400035b4
A: android: windowSoftInputMode ( 0x0101022b ) = ( type 0x11 ) 0x10
A: android: hardwareAccelerated ( 0x010102d3 ) = ( type 0x12 ) 0xffffffff
E: intent - filter ( line = 42 )
E: action ( line = 43 )
A: android: name ( 0x01010003 ) = " android.intent.action.MAIN " ( Raw: " android.intent.action.MAIN " ) ''' ;
2018-06-25 11:38:08 +00:00
2018-05-31 08:33:15 +00:00
class MockIosWorkFlow extends Mock implements IOSWorkflow {
@ override
String getPlistValueFromFile ( String path , String key ) {
final File file = fs . file ( path ) ;
if ( ! file . existsSync ( ) ) {
return null ;
}
return json . decode ( file . readAsStringSync ( ) ) [ key ] ;
}
}
// Contains no bundle identifier.
const String badPlistData = '''
{ }
''' ;
const String plistData = '''
{ " CFBundleIdentifier " : " fooBundleId " }
''' ;
2019-05-30 02:04:35 +00:00
class MockOperatingSystemUtils extends Mock implements OperatingSystemUtils { }