mirror of
https://github.com/Genymobile/scrcpy.git
synced 2025-08-03 14:49:29 +00:00
fixpatch
This commit is contained in:
parent
0be766e71a
commit
44a8bcb152
29 changed files with 1645 additions and 0 deletions
22
debian/.gitignore
vendored
Normal file
22
debian/.gitignore
vendored
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
# Ignore generated files
|
||||||
|
*.deb
|
||||||
|
*.dsc
|
||||||
|
*.changes
|
||||||
|
*.build
|
||||||
|
*.buildinfo
|
||||||
|
*.tar.gz
|
||||||
|
|
||||||
|
# Ignore files generated during build
|
||||||
|
files
|
||||||
|
autoreconf.*
|
||||||
|
*.substvars
|
||||||
|
*.log
|
||||||
|
*.debhelper
|
||||||
|
*-stamp
|
||||||
|
/*/
|
||||||
|
!missing-sources/
|
||||||
|
!patches/
|
||||||
|
!patches/*.patch
|
||||||
|
!source/
|
||||||
|
!tests/
|
||||||
|
!upstream/
|
28
debian/changelog
vendored
Normal file
28
debian/changelog
vendored
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
scrcpy (1.16-1) unstable; urgency=medium
|
||||||
|
|
||||||
|
* build 1.16.
|
||||||
|
*
|
||||||
|
|
||||||
|
-- zhaozhen <zhaozhen@uniontech.com> Wed, 02 Sep 2020 18:23:17 +0800
|
||||||
|
|
||||||
|
scrcpy (1.14-1) unstable; urgency=medium
|
||||||
|
|
||||||
|
* New upstream release
|
||||||
|
* Bump Standards-Version to 4.5.0
|
||||||
|
* Bump debhelper compat to 13
|
||||||
|
|
||||||
|
-- Yangfl <mmyangfl@gmail.com> Wed, 01 Jul 2020 14:59:53 +0800
|
||||||
|
|
||||||
|
scrcpy (1.12.1+ds-1) unstable; urgency=medium
|
||||||
|
|
||||||
|
* New upstream release (Closes: #947465)
|
||||||
|
* Recommend but not depend on adb
|
||||||
|
* Add upstream metadata
|
||||||
|
|
||||||
|
-- Yangfl <mmyangfl@gmail.com> Tue, 14 Jan 2020 13:14:59 +0800
|
||||||
|
|
||||||
|
scrcpy (1.11+ds-1) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Initial release (Closes: #893279)
|
||||||
|
|
||||||
|
-- Yangfl <mmyangfl@gmail.com> Wed, 20 Nov 2019 23:40:21 +0800
|
44
debian/control
vendored
Normal file
44
debian/control
vendored
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
Source: scrcpy
|
||||||
|
Section: net
|
||||||
|
Priority: optional
|
||||||
|
Maintainer: Yangfl <mmyangfl@gmail.com>
|
||||||
|
Build-Depends:
|
||||||
|
debhelper-compat (= 13),
|
||||||
|
Build-Depends-Arch:
|
||||||
|
meson,
|
||||||
|
libavcodec-dev,
|
||||||
|
libavformat-dev,
|
||||||
|
libavutil-dev,
|
||||||
|
libsdl2-dev,
|
||||||
|
Build-Depends-Indep:
|
||||||
|
android-sdk,
|
||||||
|
android-sdk-platform-23,
|
||||||
|
default-jdk,
|
||||||
|
unzip,
|
||||||
|
zip,
|
||||||
|
Rules-Requires-Root: no
|
||||||
|
Standards-Version: 4.5.0
|
||||||
|
Homepage: https://github.com/Genymobile/scrcpy
|
||||||
|
Vcs-Git: https://salsa.debian.org/yangfl-guest/scrcpy.git
|
||||||
|
Vcs-Browser: https://salsa.debian.org/yangfl-guest/scrcpy
|
||||||
|
|
||||||
|
Package: scrcpy
|
||||||
|
Architecture: any
|
||||||
|
Depends: ${misc:Depends}, ${shlibs:Depends}, scrcpy-server,
|
||||||
|
Recommends: adb,
|
||||||
|
Description: Display and control your Android device
|
||||||
|
This application provides display and control of Android devices connected on
|
||||||
|
USB (or over TCP/IP). It does not require any root access.
|
||||||
|
.
|
||||||
|
This package contains the client (desktop) binary.
|
||||||
|
|
||||||
|
Package: scrcpy-server
|
||||||
|
Architecture: all
|
||||||
|
Multi-Arch: foreign
|
||||||
|
Depends: ${misc:Depends},
|
||||||
|
Description: Display and control your Android device - server binary
|
||||||
|
This application provides display and control of Android devices connected on
|
||||||
|
USB (or over TCP/IP). It does not require any root access.
|
||||||
|
.
|
||||||
|
This package contains the server (mobile) binary, which will be pushed to the
|
||||||
|
Android device.
|
38
debian/copyright
vendored
Normal file
38
debian/copyright
vendored
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||||
|
Upstream-Name: scrcpy
|
||||||
|
Upstream-Contact: Romain Vimont <rom@rom1v.com>
|
||||||
|
Source: https://github.com/Genymobile/scrcpy
|
||||||
|
|
||||||
|
Files: *
|
||||||
|
Copyright: 2018 Genymobile
|
||||||
|
2018-2019 Romain Vimont <rom@rom1v.com>
|
||||||
|
License: Apache-2
|
||||||
|
|
||||||
|
Files: app/src/android/input.h
|
||||||
|
app/src/android/keycodes.h
|
||||||
|
Copyright: 2010 The Android Open Source Project
|
||||||
|
License: Apache-2
|
||||||
|
|
||||||
|
Files: debian/missing-sources/gradle/wrapper/gradle-wrapper/*
|
||||||
|
Copyright: 2007-2017 Gradle authors
|
||||||
|
License: Apache-2
|
||||||
|
|
||||||
|
Files: debian/*
|
||||||
|
Copyright: 2019 Yangfl <mmyangfl@gmail.com>
|
||||||
|
License: Apache-2
|
||||||
|
|
||||||
|
License: Apache-2
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
.
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
.
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
.
|
||||||
|
On Debian systems, the full text of the Apache License, Version 2.0
|
||||||
|
can be found in the file '/usr/share/common-licenses/Apache-2.0'.
|
4
debian/gbp.conf
vendored
Normal file
4
debian/gbp.conf
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
[DEFAULT]
|
||||||
|
upstream-branch = upstream
|
||||||
|
debian-branch = master
|
||||||
|
pristine-tar = True
|
3
debian/gitlab-ci.yml
vendored
Normal file
3
debian/gitlab-ci.yml
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
include:
|
||||||
|
- https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/salsa-ci.yml
|
||||||
|
- https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/pipeline-jobs.yml
|
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2010 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.gradle.wrapper;
|
||||||
|
|
||||||
|
import java.io.Closeable;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FilenameFilter;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLClassLoader;
|
||||||
|
|
||||||
|
public class BootstrapMainStarter {
|
||||||
|
public void start(String[] args, File gradleHome) throws Exception {
|
||||||
|
File gradleJar = findLauncherJar(gradleHome);
|
||||||
|
if (gradleJar == null) {
|
||||||
|
throw new RuntimeException(String.format("Could not locate the Gradle launcher JAR in Gradle distribution '%s'.", gradleHome));
|
||||||
|
}
|
||||||
|
URLClassLoader contextClassLoader = new URLClassLoader(new URL[]{gradleJar.toURI().toURL()}, ClassLoader.getSystemClassLoader().getParent());
|
||||||
|
Thread.currentThread().setContextClassLoader(contextClassLoader);
|
||||||
|
Class<?> mainClass = contextClassLoader.loadClass("org.gradle.launcher.GradleMain");
|
||||||
|
Method mainMethod = mainClass.getMethod("main", String[].class);
|
||||||
|
mainMethod.invoke(null, new Object[]{args});
|
||||||
|
if (contextClassLoader instanceof Closeable) {
|
||||||
|
((Closeable) contextClassLoader).close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static File findLauncherJar(File gradleHome) {
|
||||||
|
File libDirectory = new File(gradleHome, "lib");
|
||||||
|
if (libDirectory.exists() && libDirectory.isDirectory()) {
|
||||||
|
File[] launcherJars = libDirectory.listFiles(new FilenameFilter() {
|
||||||
|
@Override
|
||||||
|
public boolean accept(File dir, String name) {
|
||||||
|
return name.matches("gradle-launcher-.*\\.jar");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (launcherJars!=null && launcherJars.length==1) {
|
||||||
|
return launcherJars[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
235
debian/missing-sources/gradle/wrapper/gradle-wrapper/java/org/gradle/wrapper/Download.java
vendored
Normal file
235
debian/missing-sources/gradle/wrapper/gradle-wrapper/java/org/gradle/wrapper/Download.java
vendored
Normal file
|
@ -0,0 +1,235 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2007-2009 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.gradle.wrapper;
|
||||||
|
|
||||||
|
import java.io.BufferedOutputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.net.Authenticator;
|
||||||
|
import java.net.PasswordAuthentication;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLConnection;
|
||||||
|
|
||||||
|
public class Download implements IDownload {
|
||||||
|
public static final String UNKNOWN_VERSION = "0";
|
||||||
|
|
||||||
|
private static final int BUFFER_SIZE = 10 * 1024;
|
||||||
|
private static final int PROGRESS_CHUNK = 1024 * 1024;
|
||||||
|
private final Logger logger;
|
||||||
|
private final String appName;
|
||||||
|
private final String appVersion;
|
||||||
|
private final DownloadProgressListener progressListener;
|
||||||
|
|
||||||
|
public Download(Logger logger, String appName, String appVersion) {
|
||||||
|
this(logger, null, appName, appVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Download(Logger logger, DownloadProgressListener progressListener, String appName, String appVersion) {
|
||||||
|
this.logger = logger;
|
||||||
|
this.appName = appName;
|
||||||
|
this.appVersion = appVersion;
|
||||||
|
this.progressListener = new DefaultDownloadProgressListener(logger, progressListener);
|
||||||
|
configureProxyAuthentication();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void configureProxyAuthentication() {
|
||||||
|
if (System.getProperty("http.proxyUser") != null) {
|
||||||
|
Authenticator.setDefault(new ProxyAuthenticator());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void download(URI address, File destination) throws Exception {
|
||||||
|
destination.getParentFile().mkdirs();
|
||||||
|
downloadInternal(address, destination);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void downloadInternal(URI address, File destination)
|
||||||
|
throws Exception {
|
||||||
|
OutputStream out = null;
|
||||||
|
URLConnection conn;
|
||||||
|
InputStream in = null;
|
||||||
|
try {
|
||||||
|
URL url = safeUri(address).toURL();
|
||||||
|
out = new BufferedOutputStream(new FileOutputStream(destination));
|
||||||
|
conn = url.openConnection();
|
||||||
|
addBasicAuthentication(address, conn);
|
||||||
|
final String userAgentValue = calculateUserAgent();
|
||||||
|
conn.setRequestProperty("User-Agent", userAgentValue);
|
||||||
|
in = conn.getInputStream();
|
||||||
|
byte[] buffer = new byte[BUFFER_SIZE];
|
||||||
|
int numRead;
|
||||||
|
int totalLength = conn.getContentLength();
|
||||||
|
long downloadedLength = 0;
|
||||||
|
long progressCounter = 0;
|
||||||
|
while ((numRead = in.read(buffer)) != -1) {
|
||||||
|
if (Thread.currentThread().isInterrupted()) {
|
||||||
|
System.out.print("interrupted");
|
||||||
|
throw new IOException("Download was interrupted.");
|
||||||
|
}
|
||||||
|
|
||||||
|
downloadedLength += numRead;
|
||||||
|
progressCounter += numRead;
|
||||||
|
|
||||||
|
if (progressCounter / PROGRESS_CHUNK > 0 || downloadedLength == totalLength) {
|
||||||
|
progressCounter = progressCounter - PROGRESS_CHUNK;
|
||||||
|
progressListener.downloadStatusChanged(address, totalLength, downloadedLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
out.write(buffer, 0, numRead);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
logger.log("");
|
||||||
|
if (in != null) {
|
||||||
|
in.close();
|
||||||
|
}
|
||||||
|
if (out != null) {
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a safe URI from the given one by stripping out user info.
|
||||||
|
*
|
||||||
|
* @param uri Original URI
|
||||||
|
* @return a new URI with no user info
|
||||||
|
*/
|
||||||
|
static URI safeUri(URI uri) {
|
||||||
|
try {
|
||||||
|
return new URI(uri.getScheme(), null, uri.getHost(), uri.getPort(), uri.getPath(), uri.getQuery(), uri.getFragment());
|
||||||
|
} catch (URISyntaxException e) {
|
||||||
|
throw new RuntimeException("Failed to parse URI", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addBasicAuthentication(URI address, URLConnection connection) throws IOException {
|
||||||
|
String userInfo = calculateUserInfo(address);
|
||||||
|
if (userInfo == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!"https".equals(address.getScheme())) {
|
||||||
|
logger.log("WARNING Using HTTP Basic Authentication over an insecure connection to download the Gradle distribution. Please consider using HTTPS.");
|
||||||
|
}
|
||||||
|
connection.setRequestProperty("Authorization", "Basic " + base64Encode(userInfo));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base64 encode user info for HTTP Basic Authentication.
|
||||||
|
*
|
||||||
|
* Try to use {@literal java.util.Base64} encoder which is available starting with Java 8.
|
||||||
|
* Fallback to {@literal javax.xml.bind.DatatypeConverter} from JAXB which is available starting with Java 6 but is not anymore in Java 9.
|
||||||
|
* Fortunately, both of these two Base64 encoders implement the right Base64 flavor, the one that does not split the output in multiple lines.
|
||||||
|
*
|
||||||
|
* @param userInfo user info
|
||||||
|
* @return Base64 encoded user info
|
||||||
|
* @throws RuntimeException if no public Base64 encoder is available on this JVM
|
||||||
|
*/
|
||||||
|
private String base64Encode(String userInfo) {
|
||||||
|
ClassLoader loader = getClass().getClassLoader();
|
||||||
|
try {
|
||||||
|
Method getEncoderMethod = loader.loadClass("java.util.Base64").getMethod("getEncoder");
|
||||||
|
Method encodeMethod = loader.loadClass("java.util.Base64$Encoder").getMethod("encodeToString", byte[].class);
|
||||||
|
Object encoder = getEncoderMethod.invoke(null);
|
||||||
|
return (String) encodeMethod.invoke(encoder, new Object[]{userInfo.getBytes("UTF-8")});
|
||||||
|
} catch (Exception java7OrEarlier) {
|
||||||
|
try {
|
||||||
|
Method encodeMethod = loader.loadClass("javax.xml.bind.DatatypeConverter").getMethod("printBase64Binary", byte[].class);
|
||||||
|
return (String) encodeMethod.invoke(null, new Object[]{userInfo.getBytes("UTF-8")});
|
||||||
|
} catch (Exception java5OrEarlier) {
|
||||||
|
throw new RuntimeException("Downloading Gradle distributions with HTTP Basic Authentication is not supported on your JVM.", java5OrEarlier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String calculateUserInfo(URI uri) {
|
||||||
|
String username = System.getProperty("gradle.wrapperUser");
|
||||||
|
String password = System.getProperty("gradle.wrapperPassword");
|
||||||
|
if (username != null && password != null) {
|
||||||
|
return username + ':' + password;
|
||||||
|
}
|
||||||
|
return uri.getUserInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String calculateUserAgent() {
|
||||||
|
String javaVendor = System.getProperty("java.vendor");
|
||||||
|
String javaVersion = System.getProperty("java.version");
|
||||||
|
String javaVendorVersion = System.getProperty("java.vm.version");
|
||||||
|
String osName = System.getProperty("os.name");
|
||||||
|
String osVersion = System.getProperty("os.version");
|
||||||
|
String osArch = System.getProperty("os.arch");
|
||||||
|
return String.format("%s/%s (%s;%s;%s) (%s;%s;%s)", appName, appVersion, osName, osVersion, osArch, javaVendor, javaVersion, javaVendorVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ProxyAuthenticator extends Authenticator {
|
||||||
|
@Override
|
||||||
|
protected PasswordAuthentication getPasswordAuthentication() {
|
||||||
|
return new PasswordAuthentication(
|
||||||
|
System.getProperty("http.proxyUser"), System.getProperty(
|
||||||
|
"http.proxyPassword", "").toCharArray());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class DefaultDownloadProgressListener implements DownloadProgressListener {
|
||||||
|
private final Logger logger;
|
||||||
|
private final DownloadProgressListener delegate;
|
||||||
|
private int previousDownloadPercent;
|
||||||
|
|
||||||
|
public DefaultDownloadProgressListener(Logger logger, DownloadProgressListener delegate) {
|
||||||
|
this.logger = logger;
|
||||||
|
this.delegate = delegate;
|
||||||
|
this.previousDownloadPercent = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void downloadStatusChanged(URI address, long contentLength, long downloaded) {
|
||||||
|
// If the total size of distribution is known, but there's no advanced progress listener, provide extra progress information
|
||||||
|
if (contentLength > 0 && delegate == null) {
|
||||||
|
appendPercentageSoFar(contentLength, downloaded);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (contentLength != downloaded) {
|
||||||
|
logger.append(".");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (delegate != null) {
|
||||||
|
delegate.downloadStatusChanged(address, contentLength, downloaded);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appendPercentageSoFar(long contentLength, long downloaded) {
|
||||||
|
try {
|
||||||
|
int currentDownloadPercent = 10 * (calculateDownloadPercent(contentLength, downloaded) / 10);
|
||||||
|
if (currentDownloadPercent != 0 && previousDownloadPercent != currentDownloadPercent) {
|
||||||
|
logger.append(String.valueOf(currentDownloadPercent)).append('%');
|
||||||
|
previousDownloadPercent = currentDownloadPercent;
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int calculateDownloadPercent(long totalLength, long downloadedLength) {
|
||||||
|
return Math.min(100, Math.max(0, (int) ((downloadedLength / (double) totalLength) * 100)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2017 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.gradle.wrapper;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
public interface DownloadProgressListener {
|
||||||
|
/**
|
||||||
|
* Reports the current progress of the download
|
||||||
|
*
|
||||||
|
* @param address distribution url
|
||||||
|
* @param contentLength the content length of the distribution, or -1 if the content length is not known.
|
||||||
|
* @param downloaded the total amount of currently downloaded bytes
|
||||||
|
*/
|
||||||
|
void downloadStatusChanged(URI address, long contentLength, long downloaded);
|
||||||
|
}
|
|
@ -0,0 +1,97 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.gradle.wrapper;
|
||||||
|
|
||||||
|
import java.io.Closeable;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.RandomAccessFile;
|
||||||
|
import java.nio.channels.FileChannel;
|
||||||
|
import java.nio.channels.FileLock;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
public class ExclusiveFileAccessManager {
|
||||||
|
|
||||||
|
public static final String LOCK_FILE_SUFFIX = ".lck";
|
||||||
|
|
||||||
|
private final int timeoutMs;
|
||||||
|
private final int pollIntervalMs;
|
||||||
|
|
||||||
|
public ExclusiveFileAccessManager(int timeoutMs, int pollIntervalMs) {
|
||||||
|
this.timeoutMs = timeoutMs;
|
||||||
|
this.pollIntervalMs = pollIntervalMs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> T access(File exclusiveFile, Callable<T> task) throws Exception {
|
||||||
|
final File lockFile = new File(exclusiveFile.getParentFile(), exclusiveFile.getName() + LOCK_FILE_SUFFIX);
|
||||||
|
File lockFileDirectory = lockFile.getParentFile();
|
||||||
|
if (!lockFileDirectory.mkdirs()
|
||||||
|
&& (!lockFileDirectory.exists() || !lockFileDirectory.isDirectory())) {
|
||||||
|
throw new RuntimeException("Could not create parent directory for lock file " + lockFile.getAbsolutePath());
|
||||||
|
}
|
||||||
|
RandomAccessFile randomAccessFile = null;
|
||||||
|
FileChannel channel = null;
|
||||||
|
try {
|
||||||
|
|
||||||
|
long expiry = getTimeMillis() + timeoutMs;
|
||||||
|
FileLock lock = null;
|
||||||
|
|
||||||
|
while (lock == null && getTimeMillis() < expiry) {
|
||||||
|
randomAccessFile = new RandomAccessFile(lockFile, "rw");
|
||||||
|
channel = randomAccessFile.getChannel();
|
||||||
|
lock = channel.tryLock();
|
||||||
|
|
||||||
|
if (lock == null) {
|
||||||
|
maybeCloseQuietly(channel);
|
||||||
|
maybeCloseQuietly(randomAccessFile);
|
||||||
|
Thread.sleep(pollIntervalMs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lock == null) {
|
||||||
|
throw new RuntimeException("Timeout of " + timeoutMs + " reached waiting for exclusive access to file: " + exclusiveFile.getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return task.call();
|
||||||
|
} finally {
|
||||||
|
lock.release();
|
||||||
|
|
||||||
|
maybeCloseQuietly(channel);
|
||||||
|
channel = null;
|
||||||
|
maybeCloseQuietly(randomAccessFile);
|
||||||
|
randomAccessFile = null;
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
maybeCloseQuietly(channel);
|
||||||
|
maybeCloseQuietly(randomAccessFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private long getTimeMillis() {
|
||||||
|
return System.nanoTime() / (1000L * 1000L);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void maybeCloseQuietly(Closeable closeable) {
|
||||||
|
if (closeable != null) {
|
||||||
|
try {
|
||||||
|
closeable.close();
|
||||||
|
} catch (Exception ignore) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2014 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.gradle.wrapper;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
public class GradleUserHomeLookup {
|
||||||
|
public static final String DEFAULT_GRADLE_USER_HOME = System.getProperty("user.home") + "/.gradle";
|
||||||
|
public static final String GRADLE_USER_HOME_PROPERTY_KEY = "gradle.user.home";
|
||||||
|
public static final String GRADLE_USER_HOME_ENV_KEY = "GRADLE_USER_HOME";
|
||||||
|
|
||||||
|
public static File gradleUserHome() {
|
||||||
|
String gradleUserHome;
|
||||||
|
if ((gradleUserHome = System.getProperty(GRADLE_USER_HOME_PROPERTY_KEY)) != null) {
|
||||||
|
return new File(gradleUserHome);
|
||||||
|
}
|
||||||
|
if ((gradleUserHome = System.getenv(GRADLE_USER_HOME_ENV_KEY)) != null) {
|
||||||
|
return new File(gradleUserHome);
|
||||||
|
}
|
||||||
|
return new File(DEFAULT_GRADLE_USER_HOME);
|
||||||
|
}
|
||||||
|
}
|
109
debian/missing-sources/gradle/wrapper/gradle-wrapper/java/org/gradle/wrapper/GradleWrapperMain.java
vendored
Normal file
109
debian/missing-sources/gradle/wrapper/gradle-wrapper/java/org/gradle/wrapper/GradleWrapperMain.java
vendored
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2007 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.gradle.wrapper;
|
||||||
|
|
||||||
|
import org.gradle.cli.CommandLineParser;
|
||||||
|
import org.gradle.cli.ParsedCommandLine;
|
||||||
|
import org.gradle.cli.SystemPropertiesCommandLineConverter;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import static org.gradle.wrapper.Download.UNKNOWN_VERSION;
|
||||||
|
|
||||||
|
public class GradleWrapperMain {
|
||||||
|
public static final String GRADLE_USER_HOME_OPTION = "g";
|
||||||
|
public static final String GRADLE_USER_HOME_DETAILED_OPTION = "gradle-user-home";
|
||||||
|
public static final String GRADLE_QUIET_OPTION = "q";
|
||||||
|
public static final String GRADLE_QUIET_DETAILED_OPTION = "quiet";
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
File wrapperJar = wrapperJar();
|
||||||
|
File propertiesFile = wrapperProperties(wrapperJar);
|
||||||
|
File rootDir = rootDir(wrapperJar);
|
||||||
|
|
||||||
|
CommandLineParser parser = new CommandLineParser();
|
||||||
|
parser.allowUnknownOptions();
|
||||||
|
parser.option(GRADLE_USER_HOME_OPTION, GRADLE_USER_HOME_DETAILED_OPTION).hasArgument();
|
||||||
|
parser.option(GRADLE_QUIET_OPTION, GRADLE_QUIET_DETAILED_OPTION);
|
||||||
|
|
||||||
|
SystemPropertiesCommandLineConverter converter = new SystemPropertiesCommandLineConverter();
|
||||||
|
converter.configure(parser);
|
||||||
|
|
||||||
|
ParsedCommandLine options = parser.parse(args);
|
||||||
|
|
||||||
|
Properties systemProperties = System.getProperties();
|
||||||
|
systemProperties.putAll(converter.convert(options, new HashMap<String, String>()));
|
||||||
|
|
||||||
|
File gradleUserHome = gradleUserHome(options);
|
||||||
|
|
||||||
|
addSystemProperties(gradleUserHome, rootDir);
|
||||||
|
|
||||||
|
Logger logger = logger(options);
|
||||||
|
|
||||||
|
WrapperExecutor wrapperExecutor = WrapperExecutor.forWrapperPropertiesFile(propertiesFile);
|
||||||
|
wrapperExecutor.execute(
|
||||||
|
args,
|
||||||
|
new Install(logger, new Download(logger, "gradlew", UNKNOWN_VERSION), new PathAssembler(gradleUserHome)),
|
||||||
|
new BootstrapMainStarter());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void addSystemProperties(File gradleHome, File rootDir) {
|
||||||
|
System.getProperties().putAll(SystemPropertiesHandler.getSystemProperties(new File(gradleHome, "gradle.properties")));
|
||||||
|
System.getProperties().putAll(SystemPropertiesHandler.getSystemProperties(new File(rootDir, "gradle.properties")));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static File rootDir(File wrapperJar) {
|
||||||
|
return wrapperJar.getParentFile().getParentFile().getParentFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static File wrapperProperties(File wrapperJar) {
|
||||||
|
return new File(wrapperJar.getParent(), wrapperJar.getName().replaceFirst("\\.jar$", ".properties"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static File wrapperJar() {
|
||||||
|
URI location;
|
||||||
|
try {
|
||||||
|
location = GradleWrapperMain.class.getProtectionDomain().getCodeSource().getLocation().toURI();
|
||||||
|
} catch (URISyntaxException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
if (!location.getScheme().equals("file")) {
|
||||||
|
throw new RuntimeException(String.format("Cannot determine classpath for wrapper Jar from codebase '%s'.", location));
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return Paths.get(location).toFile();
|
||||||
|
} catch (NoClassDefFoundError e) {
|
||||||
|
return new File(location.getPath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static File gradleUserHome(ParsedCommandLine options) {
|
||||||
|
if (options.hasOption(GRADLE_USER_HOME_OPTION)) {
|
||||||
|
return new File(options.option(GRADLE_USER_HOME_OPTION).getValue());
|
||||||
|
}
|
||||||
|
return GradleUserHomeLookup.gradleUserHome();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Logger logger(ParsedCommandLine options) {
|
||||||
|
return new Logger(options.hasOption(GRADLE_QUIET_OPTION));
|
||||||
|
}
|
||||||
|
}
|
23
debian/missing-sources/gradle/wrapper/gradle-wrapper/java/org/gradle/wrapper/IDownload.java
vendored
Normal file
23
debian/missing-sources/gradle/wrapper/gradle-wrapper/java/org/gradle/wrapper/IDownload.java
vendored
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2007-2009 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.gradle.wrapper;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
public interface IDownload {
|
||||||
|
void download(URI address, File destination) throws Exception;
|
||||||
|
}
|
297
debian/missing-sources/gradle/wrapper/gradle-wrapper/java/org/gradle/wrapper/Install.java
vendored
Normal file
297
debian/missing-sources/gradle/wrapper/gradle-wrapper/java/org/gradle/wrapper/Install.java
vendored
Normal file
|
@ -0,0 +1,297 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2010 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.gradle.wrapper;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipFile;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
|
||||||
|
public class Install {
|
||||||
|
public static final String DEFAULT_DISTRIBUTION_PATH = "wrapper/dists";
|
||||||
|
private final Logger logger;
|
||||||
|
private final IDownload download;
|
||||||
|
private final PathAssembler pathAssembler;
|
||||||
|
private final ExclusiveFileAccessManager exclusiveFileAccessManager = new ExclusiveFileAccessManager(120000, 200);
|
||||||
|
|
||||||
|
public Install(Logger logger, IDownload download, PathAssembler pathAssembler) {
|
||||||
|
this.logger = logger;
|
||||||
|
this.download = download;
|
||||||
|
this.pathAssembler = pathAssembler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public File createDist(final WrapperConfiguration configuration) throws Exception {
|
||||||
|
final URI distributionUrl = configuration.getDistribution();
|
||||||
|
final String distributionSha256Sum = configuration.getDistributionSha256Sum();
|
||||||
|
|
||||||
|
final PathAssembler.LocalDistribution localDistribution = pathAssembler.getDistribution(configuration);
|
||||||
|
final File distDir = localDistribution.getDistributionDir();
|
||||||
|
final File localZipFile = localDistribution.getZipFile();
|
||||||
|
|
||||||
|
return exclusiveFileAccessManager.access(localZipFile, new Callable<File>() {
|
||||||
|
public File call() throws Exception {
|
||||||
|
final File markerFile = new File(localZipFile.getParentFile(), localZipFile.getName() + ".ok");
|
||||||
|
if (distDir.isDirectory() && markerFile.isFile()) {
|
||||||
|
InstallCheck installCheck = verifyDistributionRoot(distDir, distDir.getAbsolutePath());
|
||||||
|
if (installCheck.isVerified()) {
|
||||||
|
return installCheck.gradleHome;
|
||||||
|
}
|
||||||
|
// Distribution is invalid. Try to reinstall.
|
||||||
|
System.err.println(installCheck.failureMessage);
|
||||||
|
markerFile.delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean needsDownload = !localZipFile.isFile();
|
||||||
|
URI safeDistributionUrl = Download.safeUri(distributionUrl);
|
||||||
|
|
||||||
|
if (needsDownload) {
|
||||||
|
File tmpZipFile = new File(localZipFile.getParentFile(), localZipFile.getName() + ".part");
|
||||||
|
tmpZipFile.delete();
|
||||||
|
logger.log("Downloading " + safeDistributionUrl);
|
||||||
|
download.download(distributionUrl, tmpZipFile);
|
||||||
|
tmpZipFile.renameTo(localZipFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<File> topLevelDirs = listDirs(distDir);
|
||||||
|
for (File dir : topLevelDirs) {
|
||||||
|
logger.log("Deleting directory " + dir.getAbsolutePath());
|
||||||
|
deleteDir(dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
verifyDownloadChecksum(configuration.getDistribution().toString(), localZipFile, distributionSha256Sum);
|
||||||
|
|
||||||
|
try {
|
||||||
|
unzip(localZipFile, distDir);
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.log("Could not unzip " + localZipFile.getAbsolutePath() + " to " + distDir.getAbsolutePath() + ".");
|
||||||
|
logger.log("Reason: " + e.getMessage());
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
|
InstallCheck installCheck = verifyDistributionRoot(distDir, safeDistributionUrl.toString());
|
||||||
|
if (installCheck.isVerified()) {
|
||||||
|
setExecutablePermissions(installCheck.gradleHome);
|
||||||
|
markerFile.createNewFile();
|
||||||
|
return installCheck.gradleHome;
|
||||||
|
}
|
||||||
|
// Distribution couldn't be installed.
|
||||||
|
throw new RuntimeException(installCheck.failureMessage);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private String calculateSha256Sum(File file)
|
||||||
|
throws Exception {
|
||||||
|
MessageDigest md = MessageDigest.getInstance("SHA-256");
|
||||||
|
InputStream fis = new FileInputStream(file);
|
||||||
|
try {
|
||||||
|
int n = 0;
|
||||||
|
byte[] buffer = new byte[4096];
|
||||||
|
while (n != -1) {
|
||||||
|
n = fis.read(buffer);
|
||||||
|
if (n > 0) {
|
||||||
|
md.update(buffer, 0, n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
fis.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
byte byteData[] = md.digest();
|
||||||
|
|
||||||
|
StringBuffer hexString = new StringBuffer();
|
||||||
|
for (int i = 0; i < byteData.length; i++) {
|
||||||
|
String hex = Integer.toHexString(0xff & byteData[i]);
|
||||||
|
if (hex.length() == 1) {
|
||||||
|
hexString.append('0');
|
||||||
|
}
|
||||||
|
hexString.append(hex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hexString.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private InstallCheck verifyDistributionRoot(File distDir, String distributionDescription)
|
||||||
|
throws Exception {
|
||||||
|
List<File> dirs = listDirs(distDir);
|
||||||
|
if (dirs.isEmpty()) {
|
||||||
|
return InstallCheck.failure(String.format("Gradle distribution '%s' does not contain any directories. Expected to find exactly 1 directory.", distributionDescription));
|
||||||
|
}
|
||||||
|
if (dirs.size() != 1) {
|
||||||
|
return InstallCheck.failure(String.format("Gradle distribution '%s' contains too many directories. Expected to find exactly 1 directory.", distributionDescription));
|
||||||
|
}
|
||||||
|
|
||||||
|
File gradleHome = dirs.get(0);
|
||||||
|
if (BootstrapMainStarter.findLauncherJar(gradleHome) == null) {
|
||||||
|
return InstallCheck.failure(String.format("Gradle distribution '%s' does not appear to contain a Gradle distribution.", distributionDescription));
|
||||||
|
}
|
||||||
|
return InstallCheck.success(gradleHome);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifyDownloadChecksum(String sourceUrl, File localZipFile, String expectedSum) throws Exception {
|
||||||
|
if (expectedSum != null) {
|
||||||
|
// if a SHA-256 hash sum has been defined in gradle-wrapper.properties, verify it here
|
||||||
|
String actualSum = calculateSha256Sum(localZipFile);
|
||||||
|
if (!expectedSum.equals(actualSum)) {
|
||||||
|
localZipFile.delete();
|
||||||
|
String message = String.format("Verification of Gradle distribution failed!%n"
|
||||||
|
+ "%n"
|
||||||
|
+ "Your Gradle distribution may have been tampered with.%n"
|
||||||
|
+ "Confirm that the 'distributionSha256Sum' property in your gradle-wrapper.properties file is correct and you are downloading the wrapper from a trusted source.%n"
|
||||||
|
+ "%n"
|
||||||
|
+ " Distribution Url: %s%n"
|
||||||
|
+ "Download Location: %s%n"
|
||||||
|
+ "Expected checksum: '%s'%n"
|
||||||
|
+ " Actual checksum: '%s'%n",
|
||||||
|
sourceUrl, localZipFile.getAbsolutePath(), expectedSum, actualSum
|
||||||
|
);
|
||||||
|
throw new RuntimeException(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<File> listDirs(File distDir) {
|
||||||
|
List<File> dirs = new ArrayList<File>();
|
||||||
|
if (distDir.exists()) {
|
||||||
|
File[] files = distDir.listFiles();
|
||||||
|
if (files != null) {
|
||||||
|
for (File file : files) {
|
||||||
|
if (file.isDirectory()) {
|
||||||
|
dirs.add(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dirs;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setExecutablePermissions(File gradleHome) {
|
||||||
|
if (isWindows()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
File gradleCommand = new File(gradleHome, "bin/gradle");
|
||||||
|
String errorMessage = null;
|
||||||
|
try {
|
||||||
|
ProcessBuilder pb = new ProcessBuilder("chmod", "755", gradleCommand.getCanonicalPath());
|
||||||
|
Process p = pb.start();
|
||||||
|
if (p.waitFor() != 0) {
|
||||||
|
BufferedReader is = new BufferedReader(new InputStreamReader(p.getInputStream()));
|
||||||
|
Formatter stdout = new Formatter();
|
||||||
|
String line;
|
||||||
|
while ((line = is.readLine()) != null) {
|
||||||
|
stdout.format("%s%n", line);
|
||||||
|
}
|
||||||
|
errorMessage = stdout.toString();
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
errorMessage = e.getMessage();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
errorMessage = e.getMessage();
|
||||||
|
}
|
||||||
|
if (errorMessage != null) {
|
||||||
|
logger.log("Could not set executable permissions for: " + gradleCommand.getAbsolutePath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isWindows() {
|
||||||
|
String osName = System.getProperty("os.name").toLowerCase(Locale.US);
|
||||||
|
if (osName.indexOf("windows") > -1) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean deleteDir(File dir) {
|
||||||
|
if (dir.isDirectory()) {
|
||||||
|
String[] children = dir.list();
|
||||||
|
for (int i = 0; i < children.length; i++) {
|
||||||
|
boolean success = deleteDir(new File(dir, children[i]));
|
||||||
|
if (!success) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The directory is now empty so delete it
|
||||||
|
return dir.delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void unzip(File zip, File dest) throws IOException {
|
||||||
|
Enumeration entries;
|
||||||
|
ZipFile zipFile = new ZipFile(zip);
|
||||||
|
try {
|
||||||
|
entries = zipFile.entries();
|
||||||
|
|
||||||
|
while (entries.hasMoreElements()) {
|
||||||
|
ZipEntry entry = (ZipEntry) entries.nextElement();
|
||||||
|
|
||||||
|
if (entry.isDirectory()) {
|
||||||
|
(new File(dest, entry.getName())).mkdirs();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(new File(dest, entry.getName())));
|
||||||
|
try {
|
||||||
|
copyInputStream(zipFile.getInputStream(entry), outputStream);
|
||||||
|
} finally {
|
||||||
|
outputStream.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
zipFile.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void copyInputStream(InputStream in, OutputStream out) throws IOException {
|
||||||
|
byte[] buffer = new byte[1024];
|
||||||
|
int len;
|
||||||
|
|
||||||
|
while ((len = in.read(buffer)) >= 0) {
|
||||||
|
out.write(buffer, 0, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
in.close();
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class InstallCheck {
|
||||||
|
private final File gradleHome;
|
||||||
|
private final String failureMessage;
|
||||||
|
|
||||||
|
private static InstallCheck failure(String message) {
|
||||||
|
return new InstallCheck(null, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static InstallCheck success(File gradleHome) {
|
||||||
|
return new InstallCheck(gradleHome, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private InstallCheck(File gradleHome, String failureMessage) {
|
||||||
|
this.gradleHome = gradleHome;
|
||||||
|
this.failureMessage = failureMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isVerified() {
|
||||||
|
return gradleHome != null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
52
debian/missing-sources/gradle/wrapper/gradle-wrapper/java/org/gradle/wrapper/Logger.java
vendored
Normal file
52
debian/missing-sources/gradle/wrapper/gradle-wrapper/java/org/gradle/wrapper/Logger.java
vendored
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2007-2014 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.gradle.wrapper;
|
||||||
|
|
||||||
|
public class Logger implements Appendable {
|
||||||
|
|
||||||
|
private final boolean quiet;
|
||||||
|
|
||||||
|
public Logger(boolean quiet) {
|
||||||
|
this.quiet = quiet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void log(String message) {
|
||||||
|
if (!quiet) {
|
||||||
|
System.out.println(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Appendable append(CharSequence csq) {
|
||||||
|
if (!quiet) {
|
||||||
|
System.out.append(csq);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Appendable append(CharSequence csq, int start, int end) {
|
||||||
|
if (!quiet) {
|
||||||
|
System.out.append(csq, start, end);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Appendable append(char c) {
|
||||||
|
if(!quiet) {
|
||||||
|
System.out.append(c);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
124
debian/missing-sources/gradle/wrapper/gradle-wrapper/java/org/gradle/wrapper/PathAssembler.java
vendored
Normal file
124
debian/missing-sources/gradle/wrapper/gradle-wrapper/java/org/gradle/wrapper/PathAssembler.java
vendored
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2007-2008 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.gradle.wrapper;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
|
||||||
|
public class PathAssembler {
|
||||||
|
public static final String GRADLE_USER_HOME_STRING = "GRADLE_USER_HOME";
|
||||||
|
public static final String PROJECT_STRING = "PROJECT";
|
||||||
|
|
||||||
|
private File gradleUserHome;
|
||||||
|
|
||||||
|
public PathAssembler() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public PathAssembler(File gradleUserHome) {
|
||||||
|
this.gradleUserHome = gradleUserHome;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines the local locations for the distribution to use given the supplied configuration.
|
||||||
|
*/
|
||||||
|
public LocalDistribution getDistribution(WrapperConfiguration configuration) {
|
||||||
|
String baseName = getDistName(configuration.getDistribution());
|
||||||
|
String distName = removeExtension(baseName);
|
||||||
|
String rootDirName = rootDirName(distName, configuration);
|
||||||
|
File distDir = new File(getBaseDir(configuration.getDistributionBase()), configuration.getDistributionPath() + "/" + rootDirName);
|
||||||
|
File distZip = new File(getBaseDir(configuration.getZipBase()), configuration.getZipPath() + "/" + rootDirName + "/" + baseName);
|
||||||
|
return new LocalDistribution(distDir, distZip);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String rootDirName(String distName, WrapperConfiguration configuration) {
|
||||||
|
String urlHash = getHash(Download.safeUri(configuration.getDistribution()).toString());
|
||||||
|
return distName + "/" + urlHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method computes a hash of the provided {@code string}.
|
||||||
|
* <p>
|
||||||
|
* The algorithm in use by this method is as follows:
|
||||||
|
* <ol>
|
||||||
|
* <li>Compute the MD5 value of {@code string}.</li>
|
||||||
|
* <li>Truncate leading zeros (i.e., treat the MD5 value as a number).</li>
|
||||||
|
* <li>Convert to base 36 (the characters {@code 0-9a-z}).</li>
|
||||||
|
* </ol>
|
||||||
|
*/
|
||||||
|
private String getHash(String string) {
|
||||||
|
try {
|
||||||
|
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
|
||||||
|
byte[] bytes = string.getBytes();
|
||||||
|
messageDigest.update(bytes);
|
||||||
|
return new BigInteger(1, messageDigest.digest()).toString(36);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("Could not hash input string.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String removeExtension(String name) {
|
||||||
|
int p = name.lastIndexOf(".");
|
||||||
|
if (p < 0) {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
return name.substring(0, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getDistName(URI distUrl) {
|
||||||
|
String path = distUrl.getPath();
|
||||||
|
int p = path.lastIndexOf("/");
|
||||||
|
if (p < 0) {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
return path.substring(p + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private File getBaseDir(String base) {
|
||||||
|
if (base.equals(GRADLE_USER_HOME_STRING)) {
|
||||||
|
return gradleUserHome;
|
||||||
|
} else if (base.equals(PROJECT_STRING)) {
|
||||||
|
return new File(System.getProperty("user.dir"));
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("Base: " + base + " is unknown");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class LocalDistribution {
|
||||||
|
private final File distZip;
|
||||||
|
private final File distDir;
|
||||||
|
|
||||||
|
public LocalDistribution(File distDir, File distZip) {
|
||||||
|
this.distDir = distDir;
|
||||||
|
this.distZip = distZip;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the location to install the distribution into.
|
||||||
|
*/
|
||||||
|
public File getDistributionDir() {
|
||||||
|
return distDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the location to install the distribution ZIP file to.
|
||||||
|
*/
|
||||||
|
public File getZipFile() {
|
||||||
|
return distZip;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2010 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.gradle.wrapper;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
public class SystemPropertiesHandler {
|
||||||
|
static final String SYSTEM_PROP_PREFIX = "systemProp.";
|
||||||
|
|
||||||
|
public static Map<String, String> getSystemProperties(File propertiesFile) {
|
||||||
|
Map<String, String> propertyMap = new HashMap<String, String>();
|
||||||
|
if (!propertiesFile.isFile()) {
|
||||||
|
return propertyMap;
|
||||||
|
}
|
||||||
|
Properties properties = new Properties();
|
||||||
|
try {
|
||||||
|
FileInputStream inStream = new FileInputStream(propertiesFile);
|
||||||
|
try {
|
||||||
|
properties.load(inStream);
|
||||||
|
} finally {
|
||||||
|
inStream.close();
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("Error when loading properties file=" + propertiesFile, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Object argument : properties.keySet()) {
|
||||||
|
if (argument.toString().startsWith(SYSTEM_PROP_PREFIX)) {
|
||||||
|
String key = argument.toString().substring(SYSTEM_PROP_PREFIX.length());
|
||||||
|
if (key.length() > 0) {
|
||||||
|
propertyMap.put(key, properties.get(argument).toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return propertyMap;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.gradle.wrapper;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
public class WrapperConfiguration {
|
||||||
|
private URI distribution;
|
||||||
|
private String distributionBase = PathAssembler.GRADLE_USER_HOME_STRING;
|
||||||
|
private String distributionPath = Install.DEFAULT_DISTRIBUTION_PATH;
|
||||||
|
private String distributionSha256Sum;
|
||||||
|
private String zipBase = PathAssembler.GRADLE_USER_HOME_STRING;
|
||||||
|
private String zipPath = Install.DEFAULT_DISTRIBUTION_PATH;
|
||||||
|
|
||||||
|
public URI getDistribution() {
|
||||||
|
return distribution;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDistribution(URI distribution) {
|
||||||
|
this.distribution = distribution;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDistributionBase() {
|
||||||
|
return distributionBase;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDistributionBase(String distributionBase) {
|
||||||
|
this.distributionBase = distributionBase;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDistributionPath() {
|
||||||
|
return distributionPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDistributionPath(String distributionPath) {
|
||||||
|
this.distributionPath = distributionPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDistributionSha256Sum() {
|
||||||
|
return distributionSha256Sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDistributionSha256Sum(String distributionSha256Sum) {
|
||||||
|
this.distributionSha256Sum = distributionSha256Sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getZipBase() {
|
||||||
|
return zipBase;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setZipBase(String zipBase) {
|
||||||
|
this.zipBase = zipBase;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getZipPath() {
|
||||||
|
return zipPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setZipPath(String zipPath) {
|
||||||
|
this.zipPath = zipPath;
|
||||||
|
}
|
||||||
|
}
|
138
debian/missing-sources/gradle/wrapper/gradle-wrapper/java/org/gradle/wrapper/WrapperExecutor.java
vendored
Normal file
138
debian/missing-sources/gradle/wrapper/gradle-wrapper/java/org/gradle/wrapper/WrapperExecutor.java
vendored
Normal file
|
@ -0,0 +1,138 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2007-2008 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.gradle.wrapper;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
public class WrapperExecutor {
|
||||||
|
public static final String DISTRIBUTION_URL_PROPERTY = "distributionUrl";
|
||||||
|
public static final String DISTRIBUTION_BASE_PROPERTY = "distributionBase";
|
||||||
|
public static final String DISTRIBUTION_PATH_PROPERTY = "distributionPath";
|
||||||
|
public static final String DISTRIBUTION_SHA_256_SUM = "distributionSha256Sum";
|
||||||
|
public static final String ZIP_STORE_BASE_PROPERTY = "zipStoreBase";
|
||||||
|
public static final String ZIP_STORE_PATH_PROPERTY = "zipStorePath";
|
||||||
|
private final Properties properties;
|
||||||
|
private final File propertiesFile;
|
||||||
|
private final WrapperConfiguration config = new WrapperConfiguration();
|
||||||
|
|
||||||
|
public static WrapperExecutor forProjectDirectory(File projectDir) {
|
||||||
|
return new WrapperExecutor(new File(projectDir, "gradle/wrapper/gradle-wrapper.properties"), new Properties());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static WrapperExecutor forWrapperPropertiesFile(File propertiesFile) {
|
||||||
|
if (!propertiesFile.exists()) {
|
||||||
|
throw new RuntimeException(String.format("Wrapper properties file '%s' does not exist.", propertiesFile));
|
||||||
|
}
|
||||||
|
return new WrapperExecutor(propertiesFile, new Properties());
|
||||||
|
}
|
||||||
|
|
||||||
|
WrapperExecutor(File propertiesFile, Properties properties) {
|
||||||
|
this.properties = properties;
|
||||||
|
this.propertiesFile = propertiesFile;
|
||||||
|
if (propertiesFile.exists()) {
|
||||||
|
try {
|
||||||
|
loadProperties(propertiesFile, properties);
|
||||||
|
config.setDistribution(prepareDistributionUri());
|
||||||
|
config.setDistributionBase(getProperty(DISTRIBUTION_BASE_PROPERTY, config.getDistributionBase()));
|
||||||
|
config.setDistributionPath(getProperty(DISTRIBUTION_PATH_PROPERTY, config.getDistributionPath()));
|
||||||
|
config.setDistributionSha256Sum(getProperty(DISTRIBUTION_SHA_256_SUM, config.getDistributionSha256Sum(), false));
|
||||||
|
config.setZipBase(getProperty(ZIP_STORE_BASE_PROPERTY, config.getZipBase()));
|
||||||
|
config.setZipPath(getProperty(ZIP_STORE_PATH_PROPERTY, config.getZipPath()));
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(String.format("Could not load wrapper properties from '%s'.", propertiesFile), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private URI prepareDistributionUri() throws URISyntaxException {
|
||||||
|
URI source = readDistroUrl();
|
||||||
|
if (source.getScheme() == null) {
|
||||||
|
//no scheme means someone passed a relative url. In our context only file relative urls make sense.
|
||||||
|
return new File(propertiesFile.getParentFile(), source.getSchemeSpecificPart()).toURI();
|
||||||
|
} else {
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private URI readDistroUrl() throws URISyntaxException {
|
||||||
|
if (properties.getProperty(DISTRIBUTION_URL_PROPERTY) == null) {
|
||||||
|
reportMissingProperty(DISTRIBUTION_URL_PROPERTY);
|
||||||
|
}
|
||||||
|
return new URI(getProperty(DISTRIBUTION_URL_PROPERTY));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void loadProperties(File propertiesFile, Properties properties) throws IOException {
|
||||||
|
InputStream inStream = new FileInputStream(propertiesFile);
|
||||||
|
try {
|
||||||
|
properties.load(inStream);
|
||||||
|
} finally {
|
||||||
|
inStream.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the distribution which this wrapper will use. Returns null if no wrapper meta-data was found in the specified project directory.
|
||||||
|
*/
|
||||||
|
public URI getDistribution() {
|
||||||
|
return config.getDistribution();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the configuration for this wrapper.
|
||||||
|
*/
|
||||||
|
public WrapperConfiguration getConfiguration() {
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void execute(String[] args, Install install, BootstrapMainStarter bootstrapMainStarter) throws Exception {
|
||||||
|
File gradleHome = install.createDist(config);
|
||||||
|
bootstrapMainStarter.start(args, gradleHome);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getProperty(String propertyName) {
|
||||||
|
return getProperty(propertyName, null, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getProperty(String propertyName, String defaultValue) {
|
||||||
|
return getProperty(propertyName, defaultValue, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getProperty(String propertyName, String defaultValue, boolean required) {
|
||||||
|
String value = properties.getProperty(propertyName);
|
||||||
|
if (value != null) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
if (defaultValue != null) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
if (required) {
|
||||||
|
return reportMissingProperty(propertyName);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String reportMissingProperty(String propertyName) {
|
||||||
|
throw new RuntimeException(String.format(
|
||||||
|
"No value with key '%s' specified in wrapper properties file '%s'.", propertyName, propertiesFile));
|
||||||
|
}
|
||||||
|
}
|
108
debian/patches/0001-No-Android-Q.patch
vendored
Normal file
108
debian/patches/0001-No-Android-Q.patch
vendored
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
diff --git a/server/src/main/java/com/genymobile/scrcpy/Controller.java b/server/src/main/java/com/genymobile/scrcpy/Controller.java
|
||||||
|
index 9100a9d..572a1b2 100644
|
||||||
|
--- a/server/src/main/java/com/genymobile/scrcpy/Controller.java
|
||||||
|
+++ b/server/src/main/java/com/genymobile/scrcpy/Controller.java
|
||||||
|
@@ -262,8 +262,8 @@ public class Controller {
|
||||||
|
}
|
||||||
|
|
||||||
|
// On Android >= 7, also press the PASTE key if requested
|
||||||
|
- if (paste && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && device.supportsInputEvents()) {
|
||||||
|
- device.injectKeycode(KeyEvent.KEYCODE_PASTE);
|
||||||
|
+ if (paste && Build.VERSION.SDK_INT >= 24 && device.supportsInputEvents()) {
|
||||||
|
+ device.injectKeycode(279);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ok;
|
||||||
|
diff --git a/server/src/main/java/com/genymobile/scrcpy/Device.java b/server/src/main/java/com/genymobile/scrcpy/Device.java
|
||||||
|
index f23dd05..6be0652 100644
|
||||||
|
--- a/server/src/main/java/com/genymobile/scrcpy/Device.java
|
||||||
|
+++ b/server/src/main/java/com/genymobile/scrcpy/Device.java
|
||||||
|
@@ -110,7 +110,7 @@ public final class Device {
|
||||||
|
}
|
||||||
|
|
||||||
|
// main display or any display on Android >= Q
|
||||||
|
- supportsInputEvents = displayId == 0 || Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q;
|
||||||
|
+ supportsInputEvents = displayId == 0 || Build.VERSION.SDK_INT >= 29;
|
||||||
|
if (!supportsInputEvents) {
|
||||||
|
Ln.w("Input events are not supported for secondary displays before Android 10");
|
||||||
|
}
|
||||||
|
diff --git a/server/src/main/java/com/genymobile/scrcpy/wrappers/ClipboardManager.java b/server/src/main/java/com/genymobile/scrcpy/wrappers/ClipboardManager.java
|
||||||
|
index e25b6e9..9566de6 100644
|
||||||
|
--- a/server/src/main/java/com/genymobile/scrcpy/wrappers/ClipboardManager.java
|
||||||
|
+++ b/server/src/main/java/com/genymobile/scrcpy/wrappers/ClipboardManager.java
|
||||||
|
@@ -22,7 +22,7 @@ public class ClipboardManager {
|
||||||
|
|
||||||
|
private Method getGetPrimaryClipMethod() throws NoSuchMethodException {
|
||||||
|
if (getPrimaryClipMethod == null) {
|
||||||
|
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
|
||||||
|
+ if (Build.VERSION.SDK_INT < 29) {
|
||||||
|
getPrimaryClipMethod = manager.getClass().getMethod("getPrimaryClip", String.class);
|
||||||
|
} else {
|
||||||
|
getPrimaryClipMethod = manager.getClass().getMethod("getPrimaryClip", String.class, int.class);
|
||||||
|
@@ -33,7 +33,7 @@ public class ClipboardManager {
|
||||||
|
|
||||||
|
private Method getSetPrimaryClipMethod() throws NoSuchMethodException {
|
||||||
|
if (setPrimaryClipMethod == null) {
|
||||||
|
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
|
||||||
|
+ if (Build.VERSION.SDK_INT < 29) {
|
||||||
|
setPrimaryClipMethod = manager.getClass().getMethod("setPrimaryClip", ClipData.class, String.class);
|
||||||
|
} else {
|
||||||
|
setPrimaryClipMethod = manager.getClass().getMethod("setPrimaryClip", ClipData.class, String.class, int.class);
|
||||||
|
@@ -43,7 +43,7 @@ public class ClipboardManager {
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ClipData getPrimaryClip(Method method, IInterface manager) throws InvocationTargetException, IllegalAccessException {
|
||||||
|
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
|
||||||
|
+ if (Build.VERSION.SDK_INT < 29) {
|
||||||
|
return (ClipData) method.invoke(manager, ServiceManager.PACKAGE_NAME);
|
||||||
|
}
|
||||||
|
return (ClipData) method.invoke(manager, ServiceManager.PACKAGE_NAME, ServiceManager.USER_ID);
|
||||||
|
@@ -51,7 +51,7 @@ public class ClipboardManager {
|
||||||
|
|
||||||
|
private static void setPrimaryClip(Method method, IInterface manager, ClipData clipData)
|
||||||
|
throws InvocationTargetException, IllegalAccessException {
|
||||||
|
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
|
||||||
|
+ if (Build.VERSION.SDK_INT < 29) {
|
||||||
|
method.invoke(manager, clipData, ServiceManager.PACKAGE_NAME);
|
||||||
|
} else {
|
||||||
|
method.invoke(manager, clipData, ServiceManager.PACKAGE_NAME, ServiceManager.USER_ID);
|
||||||
|
@@ -86,7 +86,7 @@ public class ClipboardManager {
|
||||||
|
|
||||||
|
private static void addPrimaryClipChangedListener(Method method, IInterface manager, IOnPrimaryClipChangedListener listener)
|
||||||
|
throws InvocationTargetException, IllegalAccessException {
|
||||||
|
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
|
||||||
|
+ if (Build.VERSION.SDK_INT < 29) {
|
||||||
|
method.invoke(manager, listener, ServiceManager.PACKAGE_NAME);
|
||||||
|
} else {
|
||||||
|
method.invoke(manager, listener, ServiceManager.PACKAGE_NAME, ServiceManager.USER_ID);
|
||||||
|
@@ -95,7 +95,7 @@ public class ClipboardManager {
|
||||||
|
|
||||||
|
private Method getAddPrimaryClipChangedListener() throws NoSuchMethodException {
|
||||||
|
if (addPrimaryClipChangedListener == null) {
|
||||||
|
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
|
||||||
|
+ if (Build.VERSION.SDK_INT < 29) {
|
||||||
|
addPrimaryClipChangedListener = manager.getClass()
|
||||||
|
.getMethod("addPrimaryClipChangedListener", IOnPrimaryClipChangedListener.class, String.class);
|
||||||
|
} else {
|
||||||
|
diff --git a/server/src/main/java/com/genymobile/scrcpy/wrappers/SurfaceControl.java b/server/src/main/java/com/genymobile/scrcpy/wrappers/SurfaceControl.java
|
||||||
|
index 8fbb860..de09834 100644
|
||||||
|
--- a/server/src/main/java/com/genymobile/scrcpy/wrappers/SurfaceControl.java
|
||||||
|
+++ b/server/src/main/java/com/genymobile/scrcpy/wrappers/SurfaceControl.java
|
||||||
|
@@ -88,7 +88,7 @@ public final class SurfaceControl {
|
||||||
|
if (getBuiltInDisplayMethod == null) {
|
||||||
|
// the method signature has changed in Android Q
|
||||||
|
// <https://github.com/Genymobile/scrcpy/issues/586>
|
||||||
|
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
|
||||||
|
+ if (Build.VERSION.SDK_INT < 29) {
|
||||||
|
getBuiltInDisplayMethod = CLASS.getMethod("getBuiltInDisplay", int.class);
|
||||||
|
} else {
|
||||||
|
getBuiltInDisplayMethod = CLASS.getMethod("getInternalDisplayToken");
|
||||||
|
@@ -101,7 +101,7 @@ public final class SurfaceControl {
|
||||||
|
|
||||||
|
try {
|
||||||
|
Method method = getGetBuiltInDisplayMethod();
|
||||||
|
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
|
||||||
|
+ if (Build.VERSION.SDK_INT < 29) {
|
||||||
|
// call getBuiltInDisplay(0)
|
||||||
|
return (IBinder) method.invoke(null, 0);
|
||||||
|
}
|
1
debian/patches/series
vendored
Normal file
1
debian/patches/series
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
0001-No-Android-Q.patch
|
49
debian/rules
vendored
Executable file
49
debian/rules
vendored
Executable file
|
@ -0,0 +1,49 @@
|
||||||
|
#!/usr/bin/make -f
|
||||||
|
#export DH_VERBOSE = 1
|
||||||
|
|
||||||
|
|
||||||
|
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
|
||||||
|
|
||||||
|
export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic
|
||||||
|
export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed
|
||||||
|
|
||||||
|
export ANDROID_HOME=/usr/lib/android-sdk
|
||||||
|
export JAVA_HOME=/usr/lib/jvm/default-java
|
||||||
|
export JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF8
|
||||||
|
|
||||||
|
include /usr/share/dpkg/pkg-info.mk
|
||||||
|
|
||||||
|
|
||||||
|
%:
|
||||||
|
dh $@
|
||||||
|
|
||||||
|
build:
|
||||||
|
dh build-arch
|
||||||
|
dh build-indep --buildsystem=makefile
|
||||||
|
|
||||||
|
build-arch:
|
||||||
|
dh build-arch
|
||||||
|
|
||||||
|
build-indep:
|
||||||
|
dh build-indep --buildsystem=makefile
|
||||||
|
|
||||||
|
clean:
|
||||||
|
dh clean
|
||||||
|
|
||||||
|
override_dh_auto_clean:
|
||||||
|
dh_auto_clean
|
||||||
|
rm -rf build_manual
|
||||||
|
|
||||||
|
override_dh_auto_configure-arch:
|
||||||
|
dh_auto_configure -a -- -Dcompile_server=false
|
||||||
|
|
||||||
|
override_dh_auto_build-indep:
|
||||||
|
ANDROID_PLATFORM=23 ANDROID_BUILD_TOOLS=debian server/build_without_gradle.sh
|
||||||
|
# dirty hack for reproducible jar build
|
||||||
|
cd build_manual; \
|
||||||
|
unzip scrcpy-server; \
|
||||||
|
touch -t $$(date --date="@${SOURCE_DATE_EPOCH}" +%Y%m%d%H%M.%S) META-INF META-INF/MANIFEST.MF classes.dex; \
|
||||||
|
chmod 755 META-INF; \
|
||||||
|
chmod 644 META-INF/MANIFEST.MF classes.dex; \
|
||||||
|
TZ=UTC zip -X scrcpy-server.zip META-INF/MANIFEST.MF classes.dex; \
|
||||||
|
mv scrcpy-server.zip scrcpy-server
|
1
debian/scrcpy-server.install
vendored
Normal file
1
debian/scrcpy-server.install
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
build_manual/scrcpy-server usr/share/scrcpy
|
2
debian/scrcpy.install
vendored
Normal file
2
debian/scrcpy.install
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
usr/bin/scrcpy
|
||||||
|
usr/share/man/
|
1
debian/source/format
vendored
Normal file
1
debian/source/format
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
3.0 (quilt)
|
2
debian/tests/control
vendored
Normal file
2
debian/tests/control
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Tests: unittest.sh
|
||||||
|
Depends: @builddeps@
|
8
debian/tests/unittest.sh
vendored
Executable file
8
debian/tests/unittest.sh
vendored
Executable file
|
@ -0,0 +1,8 @@
|
||||||
|
#!/bin/sh
|
||||||
|
set -e
|
||||||
|
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
meson .. --wrap-mode=nodownload -Dcompile_server=false
|
||||||
|
ninja test
|
||||||
|
rm -rf build
|
4
debian/upstream/metadata
vendored
Normal file
4
debian/upstream/metadata
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
Bug-Submit: https://github.com/Genymobile/scrcpy/issues
|
||||||
|
Repository: https://github.com/Genymobile/scrcpy.git
|
||||||
|
Repository-Browse: https://github.com/Genymobile/scrcpy
|
||||||
|
Screenshots: https://raw.githubusercontent.com/Genymobile/scrcpy/master/assets/screenshot-debian-600.jpg
|
4
debian/watch
vendored
Normal file
4
debian/watch
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
version=4
|
||||||
|
opts="filenamemangle=s%(?:.*?)?v?(\d[\d.]*)\.tar\.gz%scrcpy-$1.tar.gz%" \
|
||||||
|
https://github.com/Genymobile/scrcpy/tags \
|
||||||
|
(?:.*?/)?v?(\d[\d.]*)\.tar\.gz debian uupdate
|
Loading…
Add table
Add a link
Reference in a new issue