Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
8ab4de02
Unverified
Commit
8ab4de02
authored
Oct 19, 2021
by
Jenn Magder
Committed by
GitHub
Oct 19, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Migrate desktop_device to null safety (#92055)
parent
502edd48
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
91 additions
and
102 deletions
+91
-102
bundle_builder.dart
packages/flutter_tools/lib/src/bundle_builder.dart
+18
-20
desktop_device.dart
packages/flutter_tools/lib/src/desktop_device.dart
+28
-31
preview_device.dart
packages/flutter_tools/lib/src/preview_device.dart
+27
-30
desktop_device_test.dart
...flutter_tools/test/general.shard/desktop_device_test.dart
+18
-21
No files found.
packages/flutter_tools/lib/src/bundle_builder.dart
View file @
8ab4de02
...
...
@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import
'package:meta/meta.dart'
;
import
'package:pool/pool.dart'
;
...
...
@@ -29,15 +27,15 @@ class BundleBuilder {
/// The default `mainPath` is `lib/main.dart`.
/// The default `manifestPath` is `pubspec.yaml`
Future
<
void
>
build
({
@
required
TargetPlatform
platform
,
@
required
BuildInfo
buildInfo
,
FlutterProject
project
,
String
mainPath
,
required
TargetPlatform
platform
,
required
BuildInfo
buildInfo
,
FlutterProject
?
project
,
String
?
mainPath
,
String
manifestPath
=
defaultManifestPath
,
String
applicationKernelFilePath
,
String
depfilePath
,
String
assetDirPath
,
@visibleForTesting
BuildSystem
buildSystem
String
?
applicationKernelFilePath
,
String
?
depfilePath
,
String
?
assetDirPath
,
@visibleForTesting
BuildSystem
?
buildSystem
,
})
async
{
project
??=
FlutterProject
.
current
();
mainPath
??=
defaultMainPath
;
...
...
@@ -52,7 +50,7 @@ class BundleBuilder {
buildDir:
project
.
dartTool
.
childDirectory
(
'flutter_build'
),
cacheDir:
globals
.
cache
.
getRoot
(),
flutterRootDir:
globals
.
fs
.
directory
(
Cache
.
flutterRoot
),
engineVersion:
globals
.
artifacts
.
isLocalEngine
engineVersion:
globals
.
artifacts
!
.
isLocalEngine
?
null
:
globals
.
flutterVersion
.
engineRevision
,
defines:
<
String
,
String
>{
...
...
@@ -62,7 +60,7 @@ class BundleBuilder {
kDeferredComponents:
'false'
,
...
buildInfo
.
toBuildSystemEnvironment
(),
},
artifacts:
globals
.
artifacts
,
artifacts:
globals
.
artifacts
!
,
fileSystem:
globals
.
fs
,
logger:
globals
.
logger
,
processManager:
globals
.
processManager
,
...
...
@@ -72,7 +70,7 @@ class BundleBuilder {
final
Target
target
=
buildInfo
.
mode
==
BuildMode
.
debug
?
const
CopyFlutterBundle
()
:
const
ReleaseCopyFlutterBundle
();
final
BuildResult
result
=
await
buildSystem
.
build
(
target
,
environment
);
final
BuildResult
result
=
await
buildSystem
!
.
build
(
target
,
environment
);
if
(!
result
.
success
)
{
for
(
final
ExceptionMeasurement
measurement
in
result
.
exceptions
.
values
)
{
...
...
@@ -108,14 +106,14 @@ class BundleBuilder {
}
}
Future
<
AssetBundle
>
buildAssets
({
String
manifestPath
,
String
assetDirPath
,
@required
String
packagesPath
,
TargetPlatform
targetPlatform
,
Future
<
AssetBundle
?
>
buildAssets
({
required
String
manifestPath
,
String
?
assetDirPath
,
String
?
packagesPath
,
TargetPlatform
?
targetPlatform
,
})
async
{
assetDirPath
??=
getAssetBuildDirectory
();
packagesPath
??=
globals
.
fs
.
path
.
absolute
(
packagesPath
);
packagesPath
??=
globals
.
fs
.
path
.
absolute
(
'.packages'
);
// Build the asset bundle.
final
AssetBundle
assetBundle
=
AssetBundleFactory
.
instance
.
createBundle
();
...
...
@@ -135,7 +133,7 @@ Future<AssetBundle> buildAssets({
Future
<
void
>
writeBundle
(
Directory
bundleDir
,
Map
<
String
,
DevFSContent
>
assetEntries
,
{
Logger
loggerOverride
}
{
Logger
?
loggerOverride
}
)
async
{
loggerOverride
??=
globals
.
logger
;
if
(
bundleDir
.
existsSync
())
{
...
...
packages/flutter_tools/lib/src/desktop_device.dart
View file @
8ab4de02
...
...
@@ -2,11 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import
'dart:async'
;
import
'package:meta/meta.dart'
;
import
'package:process/process.dart'
;
import
'application_package.dart'
;
...
...
@@ -26,12 +23,12 @@ import 'protocol_discovery.dart';
/// from, containing implementations that are common to all desktop devices.
abstract
class
DesktopDevice
extends
Device
{
DesktopDevice
(
String
identifier
,
{
@
required
PlatformType
platformType
,
@
required
bool
ephemeral
,
@
required
Logger
logger
,
@
required
ProcessManager
processManager
,
@
required
FileSystem
fileSystem
,
@
required
OperatingSystemUtils
operatingSystemUtils
,
required
PlatformType
platformType
,
required
bool
ephemeral
,
required
Logger
logger
,
required
ProcessManager
processManager
,
required
FileSystem
fileSystem
,
required
OperatingSystemUtils
operatingSystemUtils
,
})
:
_logger
=
logger
,
_processManager
=
processManager
,
_fileSystem
=
fileSystem
,
...
...
@@ -60,7 +57,7 @@ abstract class DesktopDevice extends Device {
@override
Future
<
bool
>
isAppInstalled
(
ApplicationPackage
app
,
{
String
userIdentifier
,
String
?
userIdentifier
,
})
async
=>
true
;
// Since the host and target devices are the same, no work needs to be done
...
...
@@ -73,7 +70,7 @@ abstract class DesktopDevice extends Device {
@override
Future
<
bool
>
installApp
(
ApplicationPackage
app
,
{
String
userIdentifier
,
String
?
userIdentifier
,
})
async
=>
true
;
// Since the host and target devices are the same, no work needs to be done
...
...
@@ -81,14 +78,14 @@ abstract class DesktopDevice extends Device {
@override
Future
<
bool
>
uninstallApp
(
ApplicationPackage
app
,
{
String
userIdentifier
,
String
?
userIdentifier
,
})
async
=>
true
;
@override
Future
<
bool
>
get
isLocalEmulator
async
=>
false
;
@override
Future
<
String
>
get
emulatorId
async
=>
null
;
Future
<
String
?
>
get
emulatorId
async
=>
null
;
@override
DevicePortForwarder
get
portForwarder
=>
const
NoOpDevicePortForwarder
();
...
...
@@ -101,7 +98,7 @@ abstract class DesktopDevice extends Device {
@override
DeviceLogReader
getLogReader
({
ApplicationPackage
app
,
ApplicationPackage
?
app
,
bool
includePastLogs
=
false
,
})
{
assert
(!
includePastLogs
,
'Past log reading not supported on desktop.'
);
...
...
@@ -114,13 +111,13 @@ abstract class DesktopDevice extends Device {
@override
Future
<
LaunchResult
>
startApp
(
ApplicationPackage
package
,
{
String
mainPath
,
String
route
,
@
required
DebuggingOptions
debuggingOptions
,
String
?
mainPath
,
String
?
route
,
required
DebuggingOptions
debuggingOptions
,
Map
<
String
,
dynamic
>
platformArgs
=
const
<
String
,
dynamic
>{},
bool
prebuiltApplication
=
false
,
bool
ipv6
=
false
,
String
userIdentifier
,
String
?
userIdentifier
,
})
async
{
if
(!
prebuiltApplication
)
{
await
buildForDevice
(
...
...
@@ -131,9 +128,9 @@ abstract class DesktopDevice extends Device {
}
// Ensure that the executable is locatable.
final
BuildMode
buildMode
=
debuggingOptions
?.
buildInfo
?
.
mode
;
final
bool
traceStartup
=
platformArgs
[
'trace-startup'
]
as
bool
??
false
;
final
String
executable
=
executablePathForDevice
(
package
,
buildMode
);
final
BuildMode
buildMode
=
debuggingOptions
.
buildInfo
.
mode
;
final
bool
traceStartup
=
platformArgs
[
'trace-startup'
]
as
bool
?
??
false
;
final
String
?
executable
=
executablePathForDevice
(
package
,
buildMode
);
if
(
executable
==
null
)
{
_logger
.
printError
(
'Unable to find executable to run'
);
return
LaunchResult
.
failed
();
...
...
@@ -142,7 +139,7 @@ abstract class DesktopDevice extends Device {
Process
process
;
final
List
<
String
>
command
=
<
String
>[
executable
,
...
?
debuggingOptions
?
.
dartEntrypointArgs
,
...
debuggingOptions
.
dartEntrypointArgs
,
];
try
{
process
=
await
_processManager
.
start
(
...
...
@@ -157,17 +154,17 @@ abstract class DesktopDevice extends Device {
unawaited
(
process
.
exitCode
.
then
((
_
)
=>
_runningProcesses
.
remove
(
process
)));
_deviceLogReader
.
initializeProcess
(
process
);
if
(
debuggingOptions
?.
buildInfo
?
.
isRelease
==
true
)
{
if
(
debuggingOptions
.
buildInfo
.
isRelease
==
true
)
{
return
LaunchResult
.
succeeded
();
}
final
ProtocolDiscovery
observatoryDiscovery
=
ProtocolDiscovery
.
observatory
(
_deviceLogReader
,
devicePort:
debuggingOptions
?
.
deviceVmServicePort
,
hostPort:
debuggingOptions
?
.
hostVmServicePort
,
devicePort:
debuggingOptions
.
deviceVmServicePort
,
hostPort:
debuggingOptions
.
hostVmServicePort
,
ipv6:
ipv6
,
logger:
_logger
,
);
try
{
final
Uri
observatoryUri
=
await
observatoryDiscovery
.
uri
;
final
Uri
?
observatoryUri
=
await
observatoryDiscovery
.
uri
;
if
(
observatoryUri
!=
null
)
{
onAttached
(
package
,
buildMode
,
process
);
return
LaunchResult
.
succeeded
(
observatoryUri:
observatoryUri
);
...
...
@@ -187,7 +184,7 @@ abstract class DesktopDevice extends Device {
@override
Future
<
bool
>
stopApp
(
ApplicationPackage
app
,
{
String
userIdentifier
,
String
?
userIdentifier
,
})
async
{
bool
succeeded
=
true
;
// Walk a copy of _runningProcesses, since the exit handler removes from the
...
...
@@ -200,19 +197,19 @@ abstract class DesktopDevice extends Device {
@override
Future
<
void
>
dispose
()
async
{
await
portForwarder
?
.
dispose
();
await
portForwarder
.
dispose
();
}
/// Builds the current project for this device, with the given options.
Future
<
void
>
buildForDevice
(
ApplicationPackage
package
,
{
String
mainPath
,
String
?
mainPath
,
BuildInfo
buildInfo
,
});
/// Returns the path to the executable to run for [package] on this device for
/// the given [buildMode].
String
executablePathForDevice
(
ApplicationPackage
package
,
BuildMode
buildMode
);
String
?
executablePathForDevice
(
ApplicationPackage
package
,
BuildMode
buildMode
);
/// Called after a process is attached, allowing any device-specific extra
/// steps to be run.
...
...
@@ -225,7 +222,7 @@ abstract class DesktopDevice extends Device {
/// The format of the environment variables is:
/// * FLUTTER_ENGINE_SWITCHES to the number of switches.
/// * FLUTTER_ENGINE_SWITCH_<N> (indexing from 1) to the individual switches.
Map
<
String
,
String
>
_computeEnvironment
(
DebuggingOptions
debuggingOptions
,
bool
traceStartup
,
String
route
)
{
Map
<
String
,
String
>
_computeEnvironment
(
DebuggingOptions
debuggingOptions
,
bool
traceStartup
,
String
?
route
)
{
int
flags
=
0
;
final
Map
<
String
,
String
>
environment
=
<
String
,
String
>{};
...
...
packages/flutter_tools/lib/src/preview_device.dart
View file @
8ab4de02
...
...
@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import
'dart:async'
;
import
'package:meta/meta.dart'
;
...
...
@@ -37,10 +35,10 @@ BundleBuilder _defaultBundleBuilder() {
/// device is not currently discoverable.
class
PreviewDevice
extends
Device
{
PreviewDevice
({
@
required
Platform
platform
,
@
required
ProcessManager
processManager
,
@
required
Logger
logger
,
@
required
FileSystem
fileSystem
,
required
Platform
platform
,
required
ProcessManager
processManager
,
required
Logger
logger
,
required
FileSystem
fileSystem
,
@visibleForTesting
BundleBuilderFactory
builderFactory
=
_defaultBundleBuilder
,
})
:
_platform
=
platform
,
_processManager
=
processManager
,
...
...
@@ -62,18 +60,18 @@ class PreviewDevice extends Device {
Future
<
void
>
dispose
()
async
{
}
@override
Future
<
String
>
get
emulatorId
async
=>
null
;
Future
<
String
?
>
get
emulatorId
async
=>
null
;
final
DesktopLogReader
_logReader
=
DesktopLogReader
();
@override
FutureOr
<
DeviceLogReader
>
getLogReader
({
covariant
ApplicationPackage
app
,
bool
includePastLogs
=
false
})
=>
_logReader
;
FutureOr
<
DeviceLogReader
>
getLogReader
({
covariant
ApplicationPackage
?
app
,
bool
includePastLogs
=
false
})
=>
_logReader
;
@override
Future
<
bool
>
installApp
(
covariant
ApplicationPackage
app
,
{
String
userIdentifier
})
async
=>
true
;
Future
<
bool
>
installApp
(
covariant
ApplicationPackage
?
app
,
{
String
?
userIdentifier
})
async
=>
true
;
@override
Future
<
bool
>
isAppInstalled
(
covariant
ApplicationPackage
app
,
{
String
userIdentifier
})
async
=>
false
;
Future
<
bool
>
isAppInstalled
(
covariant
ApplicationPackage
app
,
{
String
?
userIdentifier
})
async
=>
false
;
@override
Future
<
bool
>
isLatestBuildInstalled
(
covariant
ApplicationPackage
app
)
async
=>
false
;
...
...
@@ -96,24 +94,23 @@ class PreviewDevice extends Device {
@override
Future
<
String
>
get
sdkNameAndVersion
async
=>
'preview'
;
Process
_process
;
Directory
_assetDirectory
;
Process
?
_process
;
@override
Future
<
LaunchResult
>
startApp
(
covariant
ApplicationPackage
package
,
{
String
mainPath
,
String
route
,
@
required
DebuggingOptions
debuggingOptions
,
Map
<
String
,
dynamic
>
platformArgs
,
String
?
mainPath
,
String
?
route
,
required
DebuggingOptions
debuggingOptions
,
Map
<
String
,
dynamic
>
platformArgs
=
const
<
String
,
dynamic
>{}
,
bool
prebuiltApplication
=
false
,
bool
ipv6
=
false
,
String
userIdentifier
,
String
?
userIdentifier
,
})
async
{
_
assetDirectory
=
_fileSystem
.
systemTempDirectory
final
Directory
assetDirectory
=
_fileSystem
.
systemTempDirectory
.
createTempSync
(
'flutter_preview.'
);
// Build assets and perform initial compilation.
Status
status
;
Status
?
status
;
try
{
status
=
_logger
.
startProgress
(
'Compiling application for preview...'
);
await
_bundleBuilderFactory
().
build
(
...
...
@@ -124,32 +121,32 @@ class PreviewDevice extends Device {
);
copyDirectory
(
_fileSystem
.
directory
(
getAssetBuildDirectory
()),
_
assetDirectory
.
childDirectory
(
'data'
).
childDirectory
(
'flutter_assets'
),
assetDirectory
.
childDirectory
(
'data'
).
childDirectory
(
'flutter_assets'
),
);
}
finally
{
status
.
stop
();
status
?
.
stop
();
}
// Merge with precompiled executable.
final
Directory
precompiledDirectory
=
_fileSystem
.
directory
(
_fileSystem
.
path
.
join
(
Cache
.
flutterRoot
,
'artifacts_temp'
,
'Debug'
));
copyDirectory
(
precompiledDirectory
,
_
assetDirectory
);
final
Directory
precompiledDirectory
=
_fileSystem
.
directory
(
_fileSystem
.
path
.
join
(
Cache
.
flutterRoot
!
,
'artifacts_temp'
,
'Debug'
));
copyDirectory
(
precompiledDirectory
,
assetDirectory
);
final
Process
process
=
await
_processManager
.
start
(
<
String
>[
_
assetDirectory
.
childFile
(
'splash'
).
path
,
assetDirectory
.
childFile
(
'splash'
).
path
,
],
);
_process
=
process
;
_logReader
.
initializeProcess
(
process
);
final
ProtocolDiscovery
observatoryDiscovery
=
ProtocolDiscovery
.
observatory
(
_logReader
,
devicePort:
debuggingOptions
?
.
deviceVmServicePort
,
hostPort:
debuggingOptions
?
.
hostVmServicePort
,
devicePort:
debuggingOptions
.
deviceVmServicePort
,
hostPort:
debuggingOptions
.
hostVmServicePort
,
ipv6:
ipv6
,
logger:
_logger
,
);
try
{
final
Uri
observatoryUri
=
await
observatoryDiscovery
.
uri
;
final
Uri
?
observatoryUri
=
await
observatoryDiscovery
.
uri
;
if
(
observatoryUri
!=
null
)
{
return
LaunchResult
.
succeeded
(
observatoryUri:
observatoryUri
);
}
...
...
@@ -166,8 +163,8 @@ class PreviewDevice extends Device {
}
@override
Future
<
bool
>
stopApp
(
covariant
ApplicationPackage
app
,
{
String
userIdentifier
})
async
{
return
_process
?.
kill
();
Future
<
bool
>
stopApp
(
covariant
ApplicationPackage
app
,
{
String
?
userIdentifier
})
async
{
return
_process
?.
kill
()
==
true
;
}
@override
...
...
@@ -179,7 +176,7 @@ class PreviewDevice extends Device {
}
@override
Future
<
bool
>
uninstallApp
(
covariant
ApplicationPackage
app
,
{
String
userIdentifier
})
async
{
Future
<
bool
>
uninstallApp
(
covariant
ApplicationPackage
app
,
{
String
?
userIdentifier
})
async
{
return
true
;
}
...
...
packages/flutter_tools/test/general.shard/desktop_device_test.dart
View file @
8ab4de02
...
...
@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import
'dart:async'
;
import
'package:file/memory.dart'
;
...
...
@@ -18,7 +16,6 @@ import 'package:flutter_tools/src/device.dart';
import
'package:flutter_tools/src/device_port_forwarder.dart'
;
import
'package:flutter_tools/src/project.dart'
;
import
'package:meta/meta.dart'
;
import
'package:test/fake.dart'
;
import
'../src/common.dart'
;
...
...
@@ -50,8 +47,8 @@ void main() {
testWithoutContext
(
'Install checks always return true'
,
()
async
{
final
FakeDesktopDevice
device
=
setUpDesktopDevice
();
expect
(
await
device
.
isAppInstalled
(
null
),
true
);
expect
(
await
device
.
isLatestBuildInstalled
(
null
),
true
);
expect
(
await
device
.
isAppInstalled
(
FakeApplicationPackage
()
),
true
);
expect
(
await
device
.
isLatestBuildInstalled
(
FakeApplicationPackage
()
),
true
);
expect
(
device
.
category
,
Category
.
desktop
);
});
...
...
@@ -89,7 +86,7 @@ void main() {
),
]);
final
FakeDesktopDevice
device
=
setUpDesktopDevice
(
processManager:
processManager
,
fileSystem:
fileSystem
);
final
String
executableName
=
device
.
executablePathForDevice
(
null
,
BuildMode
.
debug
);
final
String
?
executableName
=
device
.
executablePathForDevice
(
FakeApplicationPackage
()
,
BuildMode
.
debug
);
fileSystem
.
file
(
executableName
).
writeAsStringSync
(
'
\n
'
);
final
FakeApplicationPackage
package
=
FakeApplicationPackage
();
final
LaunchResult
result
=
await
device
.
startApp
(
...
...
@@ -248,7 +245,7 @@ void main() {
testWithoutContext
(
'createDevFSWriter returns a LocalDevFSWriter'
,
()
{
final
FakeDesktopDevice
device
=
setUpDesktopDevice
();
expect
(
device
.
createDevFSWriter
(
null
,
''
),
isA
<
LocalDevFSWriter
>());
expect
(
device
.
createDevFSWriter
(
FakeApplicationPackage
()
,
''
),
isA
<
LocalDevFSWriter
>());
});
testWithoutContext
(
'startApp supports dartEntrypointArgs'
,
()
async
{
...
...
@@ -308,10 +305,10 @@ void main() {
}
FakeDesktopDevice
setUpDesktopDevice
(
{
FileSystem
fileSystem
,
Logger
logger
,
ProcessManager
processManager
,
OperatingSystemUtils
operatingSystemUtils
,
FileSystem
?
fileSystem
,
Logger
?
logger
,
ProcessManager
?
processManager
,
OperatingSystemUtils
?
operatingSystemUtils
,
bool
nullExecutablePathForDevice
=
false
,
})
{
return
FakeDesktopDevice
(
...
...
@@ -326,11 +323,11 @@ FakeDesktopDevice setUpDesktopDevice({
/// A trivial subclass of DesktopDevice for testing the shared functionality.
class
FakeDesktopDevice
extends
DesktopDevice
{
FakeDesktopDevice
({
@
required
ProcessManager
processManager
,
@
required
Logger
logger
,
@
required
FileSystem
fileSystem
,
@
required
OperatingSystemUtils
operatingSystemUtils
,
this
.
nullExecutablePathForDevice
,
required
ProcessManager
processManager
,
required
Logger
logger
,
required
FileSystem
fileSystem
,
required
OperatingSystemUtils
operatingSystemUtils
,
this
.
nullExecutablePathForDevice
=
false
,
})
:
super
(
'dummy'
,
platformType:
PlatformType
.
linux
,
...
...
@@ -342,10 +339,10 @@ class FakeDesktopDevice extends DesktopDevice {
);
/// The [mainPath] last passed to [buildForDevice].
String
lastBuiltMainPath
;
String
?
lastBuiltMainPath
;
/// The [buildInfo] last passed to [buildForDevice].
BuildInfo
lastBuildInfo
;
BuildInfo
?
lastBuildInfo
;
final
bool
nullExecutablePathForDevice
;
...
...
@@ -364,8 +361,8 @@ class FakeDesktopDevice extends DesktopDevice {
@override
Future
<
void
>
buildForDevice
(
ApplicationPackage
package
,
{
String
mainPath
,
BuildInfo
buildInfo
,
String
?
mainPath
,
BuildInfo
?
buildInfo
,
})
async
{
lastBuiltMainPath
=
mainPath
;
lastBuildInfo
=
buildInfo
;
...
...
@@ -373,7 +370,7 @@ class FakeDesktopDevice extends DesktopDevice {
// Dummy implementation that just returns the build mode name.
@override
String
executablePathForDevice
(
ApplicationPackage
package
,
BuildMode
buildMode
)
{
String
?
executablePathForDevice
(
ApplicationPackage
package
,
BuildMode
buildMode
)
{
if
(
nullExecutablePathForDevice
)
{
return
null
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment