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
ba4177f6
Unverified
Commit
ba4177f6
authored
Apr 29, 2021
by
Jenn Magder
Committed by
GitHub
Apr 29, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Find Android Studio installations with Spotlight query on macOS (#80475)
parent
0021a08c
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
127 additions
and
19 deletions
+127
-19
android_studio.dart
packages/flutter_tools/lib/src/android/android_studio.dart
+22
-2
build_apk_test.dart
...r_tools/test/commands.shard/permeable/build_apk_test.dart
+5
-0
android_studio_test.dart
...tools/test/general.shard/android/android_studio_test.dart
+88
-0
gradle_test.dart
...flutter_tools/test/general.shard/android/gradle_test.dart
+11
-17
cache_test.dart
packages/flutter_tools/test/general.shard/cache_test.dart
+1
-0
No files found.
packages/flutter_tools/lib/src/android/android_studio.dart
View file @
ba4177f6
...
...
@@ -7,6 +7,7 @@ import '../base/io.dart';
import
'../base/process.dart'
;
import
'../base/utils.dart'
;
import
'../base/version.dart'
;
import
'../convert.dart'
;
import
'../globals_null_migrated.dart'
as
globals
;
import
'../ios/plist_parser.dart'
;
...
...
@@ -44,7 +45,7 @@ class AndroidStudio implements Comparable<AndroidStudio> {
Map
<
String
,
dynamic
>
plistValues
=
globals
.
plistParser
.
parseFile
(
plistFile
);
// As AndroidStudio managed by JetBrainsToolbox could have a wrapper pointing to the real Android Studio.
// Check if we've found a JetBrainsToolbox wrapper and deal with it properly.
final
String
jetBrainsToolboxAppBundlePath
=
plistValues
[
'JetBrainsToolboxApp'
]
as
String
;
final
String
?
jetBrainsToolboxAppBundlePath
=
plistValues
[
'JetBrainsToolboxApp'
]
as
String
?
;
if
(
jetBrainsToolboxAppBundlePath
!=
null
)
{
studioPath
=
globals
.
fs
.
path
.
join
(
jetBrainsToolboxAppBundlePath
,
'Contents'
);
plistFile
=
globals
.
fs
.
path
.
join
(
studioPath
,
'Info.plist'
);
...
...
@@ -295,9 +296,28 @@ class AndroidStudio implements Comparable<AndroidStudio> {
}
}
// Query Spotlight for unexpected installation locations.
String
spotlightQueryResult
=
''
;
try
{
final
ProcessResult
spotlightResult
=
globals
.
processManager
.
runSync
(<
String
>[
'mdfind'
,
// com.google.android.studio, com.google.android.studio-EAP
'kMDItemCFBundleIdentifier="com.google.android.studio*"'
,
]);
spotlightQueryResult
=
spotlightResult
.
stdout
as
String
;
}
on
ProcessException
{
// The Spotlight query is a nice-to-have, continue checking known installation locations.
}
for
(
final
String
studioPath
in
LineSplitter
.
split
(
spotlightQueryResult
))
{
final
Directory
appBundle
=
globals
.
fs
.
directory
(
studioPath
);
if
(!
candidatePaths
.
any
((
FileSystemEntity
e
)
=>
e
.
path
==
studioPath
))
{
candidatePaths
.
add
(
appBundle
);
}
}
return
candidatePaths
.
map
<
AndroidStudio
>((
FileSystemEntity
e
)
=>
AndroidStudio
.
fromMacOSBundle
(
e
.
path
))
.
where
((
AndroidStudio
s
)
=>
s
!=
null
)
.
where
Type
<
AndroidStudio
>(
)
.
toList
();
}
...
...
packages/flutter_tools/test/commands.shard/permeable/build_apk_test.dart
View file @
ba4177f6
...
...
@@ -143,6 +143,11 @@ void main() {
workingDirectory:
anyNamed
(
'workingDirectory'
),
environment:
anyNamed
(
'environment'
)))
.
thenAnswer
((
_
)
=>
Future
<
ProcessResult
>.
value
(
ProcessResult
(
0
,
0
,
'assembleRelease'
,
''
)));
when
(
mockProcessManager
.
runSync
(<
String
>[
'mdfind'
,
'kMDItemCFBundleIdentifier="com.google.android.studio*"'
],
workingDirectory:
anyNamed
(
'workingDirectory'
),
environment:
anyNamed
(
'environment'
)))
.
thenReturn
(
ProcessResult
(
0
,
0
,
''
,
''
));
// Fallback with error.
final
Process
process
=
createMockProcess
(
exitCode:
1
);
when
(
mockProcessManager
.
start
(
any
,
...
...
packages/flutter_tools/test/general.shard/android/android_studio_test.dart
View file @
ba4177f6
...
...
@@ -15,6 +15,7 @@ import 'package:test/fake.dart';
import
'../../src/common.dart'
;
import
'../../src/context.dart'
;
import
'../../src/fake_process_manager.dart'
;
const
String
homeLinux
=
'/home/me'
;
const
String
homeMac
=
'/Users/me'
;
...
...
@@ -99,6 +100,7 @@ void main() {
FileSystemUtils
fsUtils
;
Platform
platform
;
FakePlistUtils
plistUtils
;
FakeProcessManager
processManager
;
setUp
(()
{
plistUtils
=
FakePlistUtils
();
...
...
@@ -107,6 +109,7 @@ void main() {
fileSystem:
fileSystem
,
platform:
platform
,
);
processManager
=
FakeProcessManager
.
empty
();
});
testUsingContext
(
'Can discover Android Studio >=4.1 location on Mac'
,
()
{
...
...
@@ -174,6 +177,91 @@ void main() {
PlistParser:
()
=>
plistUtils
,
});
testUsingContext
(
'Can discover installation from Spotlight query'
,
()
{
// One in expected location.
final
String
studioInApplication
=
fileSystem
.
path
.
join
(
'/'
,
'Application'
,
'Android Studio.app'
,
);
final
String
studioInApplicationPlistFolder
=
fileSystem
.
path
.
join
(
studioInApplication
,
'Contents'
,
);
fileSystem
.
directory
(
studioInApplicationPlistFolder
).
createSync
(
recursive:
true
);
final
String
plistFilePath
=
fileSystem
.
path
.
join
(
studioInApplicationPlistFolder
,
'Info.plist'
);
plistUtils
.
fileContents
[
plistFilePath
]
=
macStudioInfoPlist4_1
;
// Two in random location only Spotlight knows about.
final
String
randomLocation1
=
fileSystem
.
path
.
join
(
'/'
,
'random'
,
'Android Studio Preview.app'
,
);
final
String
randomLocation1PlistFolder
=
fileSystem
.
path
.
join
(
randomLocation1
,
'Contents'
,
);
fileSystem
.
directory
(
randomLocation1PlistFolder
).
createSync
(
recursive:
true
);
final
String
randomLocation1PlistPath
=
fileSystem
.
path
.
join
(
randomLocation1PlistFolder
,
'Info.plist'
);
plistUtils
.
fileContents
[
randomLocation1PlistPath
]
=
macStudioInfoPlist4_1
;
final
String
randomLocation2
=
fileSystem
.
path
.
join
(
'/'
,
'random'
,
'Android Studio with Blaze.app'
,
);
final
String
randomLocation2PlistFolder
=
fileSystem
.
path
.
join
(
randomLocation2
,
'Contents'
,
);
fileSystem
.
directory
(
randomLocation2PlistFolder
).
createSync
(
recursive:
true
);
final
String
randomLocation2PlistPath
=
fileSystem
.
path
.
join
(
randomLocation2PlistFolder
,
'Info.plist'
);
plistUtils
.
fileContents
[
randomLocation2PlistPath
]
=
macStudioInfoPlist4_1
;
final
String
javaBin
=
fileSystem
.
path
.
join
(
'jre'
,
'jdk'
,
'Contents'
,
'Home'
,
'bin'
,
'java'
);
// Spotlight finds the one known and two random installations.
processManager
.
addCommands
(<
FakeCommand
>[
FakeCommand
(
command:
const
<
String
>[
'mdfind'
,
'kMDItemCFBundleIdentifier="com.google.android.studio*"'
,
],
stdout:
'
$randomLocation1
\n
$randomLocation2
\n
$studioInApplication
'
,
),
FakeCommand
(
command:
<
String
>[
fileSystem
.
path
.
join
(
randomLocation1
,
'Contents'
,
javaBin
),
'-version'
,
],
),
FakeCommand
(
command:
<
String
>[
fileSystem
.
path
.
join
(
randomLocation2
,
'Contents'
,
javaBin
),
'-version'
,
],
),
FakeCommand
(
command:
<
String
>[
fileSystem
.
path
.
join
(
studioInApplicationPlistFolder
,
javaBin
),
'-version'
,
],
),
]);
// Results are de-duplicated, only 3 installed.
expect
(
AndroidStudio
.
allInstalled
().
length
,
3
);
expect
(
processManager
,
hasNoRemainingExpectations
);
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
fileSystem
,
FileSystemUtils:
()
=>
fsUtils
,
ProcessManager:
()
=>
processManager
,
// Custom home paths are not supported on macOS nor Windows yet,
// so we force the platform to fake Linux here.
Platform:
()
=>
platform
,
PlistParser:
()
=>
plistUtils
,
});
testUsingContext
(
'finds latest valid install'
,
()
{
final
String
applicationPlistFolder
=
globals
.
fs
.
path
.
join
(
'/'
,
...
...
packages/flutter_tools/test/general.shard/android/gradle_test.dart
View file @
ba4177f6
...
...
@@ -309,19 +309,17 @@ include ':app'
group
(
'Gradle local.properties'
,
()
{
Artifacts
localEngineArtifacts
;
FakePlatform
android
;
FileSystem
fs
;
setUp
(()
{
fs
=
MemoryFileSystem
.
test
();
localEngineArtifacts
=
Artifacts
.
test
(
localEngine:
'out/android_arm'
);
android
=
fakePlatform
(
'android'
);
});
void
testUsingAndroidContext
(
String
description
,
dynamic
Function
()
testMethod
)
{
testUsingContext
(
description
,
testMethod
,
overrides:
<
Type
,
Generator
>{
Artifacts:
()
=>
localEngineArtifacts
,
Platform:
()
=>
android
,
Platform:
()
=>
FakePlatform
(
operatingSystem:
'linux'
)
,
FileSystem:
()
=>
fs
,
ProcessManager:
()
=>
FakeProcessManager
.
any
(),
});
...
...
@@ -626,12 +624,15 @@ flutter:
FakeAndroidSdk
androidSdk
;
AndroidGradleBuilder
builder
;
BufferLogger
logger
;
Platform
platform
;
setUp
(()
{
logger
=
BufferLogger
.
test
();
fs
=
MemoryFileSystem
.
test
();
fakeProcessManager
=
FakeProcessManager
.
empty
();
androidSdk
=
FakeAndroidSdk
();
platform
=
FakePlatform
(
operatingSystem:
'linux'
);
builder
=
AndroidGradleBuilder
(
logger:
logger
,
processManager:
fakeProcessManager
,
...
...
@@ -639,7 +640,7 @@ flutter:
artifacts:
Artifacts
.
test
(),
usage:
TestUsage
(),
gradleUtils:
FakeGradleUtils
(),
platform:
FakePlatform
()
,
platform:
platform
,
);
});
...
...
@@ -704,8 +705,8 @@ plugin2=${plugin2.path}
'aar_init_script.gradle'
,
);
fakeProcessManager
..
addCommand
(
FakeCommand
(
fakeProcessManager
.
addCommands
(<
FakeCommand
>[
FakeCommand
(
command:
<
String
>[
'gradlew'
,
'-I=
$initScript
'
,
...
...
@@ -721,8 +722,8 @@ plugin2=${plugin2.path}
'assembleAarRelease'
,
],
workingDirectory:
plugin1
.
childDirectory
(
'android'
).
path
,
)
)
..
addCommand
(
FakeCommand
(
)
,
FakeCommand
(
command:
<
String
>[
'gradlew'
,
'-I=
$initScript
'
,
...
...
@@ -738,7 +739,7 @@ plugin2=${plugin2.path}
'assembleAarRelease'
,
],
workingDirectory:
plugin2
.
childDirectory
(
'android'
).
path
,
));
)
]
);
await
builder
.
buildPluginsAsAar
(
FlutterProject
.
fromDirectoryTest
(
androidDirectory
),
...
...
@@ -755,6 +756,7 @@ plugin2=${plugin2.path}
},
overrides:
<
Type
,
Generator
>{
AndroidSdk:
()
=>
androidSdk
,
FileSystem:
()
=>
fs
,
Platform:
()
=>
platform
,
ProcessManager:
()
=>
fakeProcessManager
,
GradleUtils:
()
=>
FakeGradleUtils
(),
});
...
...
@@ -1008,14 +1010,6 @@ plugin1=${plugin1.path}
},
skip:
true
);
// TODO(jonahwilliams): This is an integration test and should be moved to the integration shard.
}
FakePlatform
fakePlatform
(
String
name
)
{
return
FakePlatform
(
environment:
<
String
,
String
>{
'HOME'
:
'/path/to/home'
},
operatingSystem:
name
,
stdoutSupportsAnsi:
false
,
);
}
class
FakeGradleUtils
extends
GradleUtils
{
@override
String
getExecutable
(
FlutterProject
project
)
{
...
...
packages/flutter_tools/test/general.shard/cache_test.dart
View file @
ba4177f6
...
...
@@ -884,6 +884,7 @@ void main() {
},
overrides:
<
Type
,
Generator
>{
Cache:
()
=>
cache
,
FileSystem:
()
=>
memoryFileSystem
,
Platform:
()
=>
FakePlatform
(
operatingSystem:
'linux'
),
ProcessManager:
()
=>
FakeProcessManager
.
list
(<
FakeCommand
>[
const
FakeCommand
(
command:
<
String
>[
'/cache/bin/cache/flutter_gradle_wrapper.rand0/gradlew'
,
...
...
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