Merge branch 'studio-suggestions' into 'master'

Studio suggestions



See merge request !324
This commit is contained in:
Daniel Martí 2016-06-08 20:10:38 +00:00
commit 99a488dc18
28 changed files with 47 additions and 99 deletions

View File

@ -68,7 +68,7 @@ import java.util.zip.ZipFile;
* @see <a href="https://stackoverflow.com/a/4761689">a binary XML parser</a> * @see <a href="https://stackoverflow.com/a/4761689">a binary XML parser</a>
*/ */
public class AndroidXMLDecompress { public class AndroidXMLDecompress {
public static final int START_TAG = 0x00100102; private static final int START_TAG = 0x00100102;
/** /**
* Just get the XML attributes from the {@code <manifest>} element. * Just get the XML attributes from the {@code <manifest>} element.
@ -119,7 +119,7 @@ public class AndroidXMLDecompress {
return new HashMap<>(0); return new HashMap<>(0);
} }
public static byte[] getManifestFromFilename(String filename) throws IOException { private static byte[] getManifestFromFilename(String filename) throws IOException {
InputStream is = null; InputStream is = null;
ZipFile zip = null; ZipFile zip = null;
int size = 0; int size = 0;
@ -140,7 +140,7 @@ public class AndroidXMLDecompress {
return buf; return buf;
} }
public static String getString(byte[] bytes, int stringIndexTableOffset, int stringTableOffset, int stringIndex) { private static String getString(byte[] bytes, int stringIndexTableOffset, int stringTableOffset, int stringIndex) {
if (stringIndex < 0) { if (stringIndex < 0) {
return null; return null;
} }
@ -148,7 +148,7 @@ public class AndroidXMLDecompress {
return getStringAt(bytes, stringOffset); return getStringAt(bytes, stringOffset);
} }
public static String getStringAt(byte[] bytes, int stringOffset) { private static String getStringAt(byte[] bytes, int stringOffset) {
int length = bytes[stringOffset + 1] << 8 & 0xff00 | bytes[stringOffset] & 0xff; int length = bytes[stringOffset + 1] << 8 & 0xff00 | bytes[stringOffset] & 0xff;
byte[] chars = new byte[length]; byte[] chars = new byte[length];
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
@ -160,7 +160,7 @@ public class AndroidXMLDecompress {
/** /**
* Return the little endian 32-bit word from the byte array at offset * Return the little endian 32-bit word from the byte array at offset
*/ */
public static int littleEndianWord(byte[] bytes, int offset) { private static int littleEndianWord(byte[] bytes, int offset) {
return bytes[offset + 3] return bytes[offset + 3]
<< 24 & 0xff000000 << 24 & 0xff000000
| bytes[offset + 2] | bytes[offset + 2]

View File

@ -925,7 +925,7 @@ public class AppDetails extends AppCompatActivity {
} }
// Install the version of this app denoted by 'app.curApk'. // Install the version of this app denoted by 'app.curApk'.
public void install(final Apk apk) { private void install(final Apk apk) {
if (isFinishing()) { if (isFinishing()) {
return; return;
} }

View File

@ -129,7 +129,7 @@ public class FDroidApp extends Application {
activity.setTheme(getCurDialogThemeResId()); activity.setTheme(getCurDialogThemeResId());
} }
public static int getCurDialogThemeResId() { private static int getCurDialogThemeResId() {
switch (curTheme) { switch (curTheme) {
case light: case light:
return R.style.MinWithDialogBaseThemeLight; return R.style.MinWithDialogBaseThemeLight;

View File

@ -5,7 +5,7 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.URL; import java.net.URL;
public class ProgressBufferedInputStream extends BufferedInputStream { class ProgressBufferedInputStream extends BufferedInputStream {
private final ProgressListener progressListener; private final ProgressListener progressListener;
private final URL sourceUrl; private final URL sourceUrl;
@ -17,7 +17,7 @@ public class ProgressBufferedInputStream extends BufferedInputStream {
* Reports progress to the specified {@link ProgressListener}, with the * Reports progress to the specified {@link ProgressListener}, with the
* progress based on the {@code totalBytes}. * progress based on the {@code totalBytes}.
*/ */
public ProgressBufferedInputStream(InputStream in, ProgressListener progressListener, URL sourceUrl, int totalBytes) { ProgressBufferedInputStream(InputStream in, ProgressListener progressListener, URL sourceUrl, int totalBytes) {
super(in); super(in);
this.progressListener = progressListener; this.progressListener = progressListener;
this.sourceUrl = sourceUrl; this.sourceUrl = sourceUrl;

View File

@ -50,7 +50,7 @@ public class RepoUpdater {
private static final String TAG = "RepoUpdater"; private static final String TAG = "RepoUpdater";
public final String indexUrl; private final String indexUrl;
@NonNull @NonNull
private final Context context; private final Context context;

View File

@ -473,11 +473,6 @@ public final class Utils {
return out; return out;
} }
public String[] toArray() {
ArrayList<String> list = toArrayList();
return list.toArray(new String[list.size()]);
}
public boolean contains(String v) { public boolean contains(String v) {
for (final String s : this) { for (final String s : this) {
if (s.equals(v)) { if (s.equals(v)) {

View File

@ -271,8 +271,7 @@ public class App extends ValueObject implements Comparable<App> {
initApkFromApkFile(context, this.installedApk, packageInfo, apkFile); initApkFromApkFile(context, this.installedApk, packageInfo, apkFile);
} }
private void setFromPackageInfo(PackageManager pm, PackageInfo packageInfo) private void setFromPackageInfo(PackageManager pm, PackageInfo packageInfo) {
throws CertificateEncodingException, IOException, PackageManager.NameNotFoundException {
this.packageName = packageInfo.packageName; this.packageName = packageInfo.packageName;
final String installerPackageName = pm.getInstallerPackageName(packageName); final String installerPackageName = pm.getInstallerPackageName(packageName);

View File

@ -20,12 +20,12 @@ import java.util.Map;
* means only types used in {@link App#toContentValues()} and * means only types used in {@link App#toContentValues()} and
* {@link Apk#toContentValues()} are implemented. * {@link Apk#toContentValues()} are implemented.
*/ */
public class ContentValuesCursor extends AbstractCursor { class ContentValuesCursor extends AbstractCursor {
private final String[] keys; private final String[] keys;
private final Object[] values; private final Object[] values;
public ContentValuesCursor(ContentValues contentValues) { ContentValuesCursor(ContentValues contentValues) {
super(); super();
keys = new String[contentValues.size()]; keys = new String[contentValues.size()];
values = new Object[contentValues.size()]; values = new Object[contentValues.size()];

View File

@ -24,10 +24,10 @@ public abstract class FDroidProvider extends ContentProvider {
private static final String TAG = "FDroidProvider"; private static final String TAG = "FDroidProvider";
public static final String AUTHORITY = "org.fdroid.fdroid.data"; static final String AUTHORITY = "org.fdroid.fdroid.data";
protected static final int CODE_LIST = 1; static final int CODE_LIST = 1;
protected static final int CODE_SINGLE = 2; static final int CODE_SINGLE = 2;
private static DBHelper dbHelper; private static DBHelper dbHelper;

View File

@ -38,7 +38,7 @@ import java.util.Arrays;
* Thus, we are comparing certificates (including the public key) used to sign an APK, * Thus, we are comparing certificates (including the public key) used to sign an APK,
* not the actual APK signature. * not the actual APK signature.
*/ */
public class ApkSignatureVerifier { class ApkSignatureVerifier {
private static final String TAG = "ApkSignatureVerifier"; private static final String TAG = "ApkSignatureVerifier";

View File

@ -36,7 +36,7 @@ import org.fdroid.fdroid.R;
* A transparent activity as a wrapper around Android's PackageInstaller Intents * A transparent activity as a wrapper around Android's PackageInstaller Intents
*/ */
public class DefaultInstallerActivity extends FragmentActivity { public class DefaultInstallerActivity extends FragmentActivity {
public static final String TAG = "AndroidInstallerAct"; private static final String TAG = "AndroidInstallerAct";
static final String ACTION_INSTALL_PACKAGE = "org.fdroid.fdroid.installer.DefaultInstaller.action.INSTALL_PACKAGE"; static final String ACTION_INSTALL_PACKAGE = "org.fdroid.fdroid.installer.DefaultInstaller.action.INSTALL_PACKAGE";
static final String ACTION_UNINSTALL_PACKAGE = "org.fdroid.fdroid.installer.DefaultInstaller.action.UNINSTALL_PACKAGE"; static final String ACTION_UNINSTALL_PACKAGE = "org.fdroid.fdroid.installer.DefaultInstaller.action.UNINSTALL_PACKAGE";
@ -124,7 +124,7 @@ public class DefaultInstallerActivity extends FragmentActivity {
installer.sendBroadcastInstall(downloadUri, Installer.ACTION_INSTALL_STARTED); installer.sendBroadcastInstall(downloadUri, Installer.ACTION_INSTALL_STARTED);
} }
protected void uninstallPackage(String packageName) { private void uninstallPackage(String packageName) {
// check that the package is installed // check that the package is installed
try { try {
getPackageManager().getPackageInfo(packageName, 0); getPackageManager().getPackageInfo(packageName, 0);

View File

@ -61,7 +61,7 @@ import java.util.Set;
* include caching of the generated {@code String}, so it should be plenty fast. * include caching of the generated {@code String}, so it should be plenty fast.
*/ */
public class InstallManagerService extends Service { public class InstallManagerService extends Service {
public static final String TAG = "InstallManagerService"; private static final String TAG = "InstallManagerService";
private static final String ACTION_INSTALL = "org.fdroid.fdroid.installer.action.INSTALL"; private static final String ACTION_INSTALL = "org.fdroid.fdroid.installer.action.INSTALL";

View File

@ -23,7 +23,6 @@ import android.app.PendingIntent;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.net.Uri; import android.net.Uri;
import android.os.PatternMatcher; import android.os.PatternMatcher;
import android.support.v4.content.LocalBroadcastManager; import android.support.v4.content.LocalBroadcastManager;
@ -50,8 +49,7 @@ import java.util.Map;
*/ */
public abstract class Installer { public abstract class Installer {
final Context context; final Context context;
final PackageManager pm; private final LocalBroadcastManager localBroadcastManager;
final LocalBroadcastManager localBroadcastManager;
public static final String ACTION_INSTALL_STARTED = "org.fdroid.fdroid.installer.Installer.action.INSTALL_STARTED"; public static final String ACTION_INSTALL_STARTED = "org.fdroid.fdroid.installer.Installer.action.INSTALL_STARTED";
public static final String ACTION_INSTALL_COMPLETE = "org.fdroid.fdroid.installer.Installer.action.INSTALL_COMPLETE"; public static final String ACTION_INSTALL_COMPLETE = "org.fdroid.fdroid.installer.Installer.action.INSTALL_COMPLETE";
@ -91,7 +89,6 @@ public abstract class Installer {
Installer(Context context) { Installer(Context context) {
this.context = context; this.context = context;
this.pm = context.getPackageManager();
localBroadcastManager = LocalBroadcastManager.getInstance(context); localBroadcastManager = LocalBroadcastManager.getInstance(context);
} }

View File

@ -25,7 +25,7 @@ import java.security.cert.CertificateEncodingException;
* {@link org.fdroid.fdroid.data.Apk} instances. * {@link org.fdroid.fdroid.data.Apk} instances.
*/ */
public class CacheSwapAppsService extends IntentService { public class CacheSwapAppsService extends IntentService {
public static final String TAG = "CacheSwapAppsService"; private static final String TAG = "CacheSwapAppsService";
private static final String ACTION_PARSE_APP = "org.fdroid.fdroid.localrepo.action.PARSE_APP"; private static final String ACTION_PARSE_APP = "org.fdroid.fdroid.localrepo.action.PARSE_APP";

View File

@ -16,7 +16,7 @@ import rx.Subscriber;
import rx.functions.Action0; import rx.functions.Action0;
import rx.subscriptions.Subscriptions; import rx.subscriptions.Subscriptions;
class BluetoothFinder extends PeerFinder { final class BluetoothFinder extends PeerFinder {
public static Observable<Peer> createBluetoothObservable(final Context context) { public static Observable<Peer> createBluetoothObservable(final Context context) {
return Observable.create(new Observable.OnSubscribe<Peer>() { return Observable.create(new Observable.OnSubscribe<Peer>() {
@ -40,7 +40,7 @@ class BluetoothFinder extends PeerFinder {
private final BluetoothAdapter adapter; private final BluetoothAdapter adapter;
BluetoothFinder(Context context, Subscriber<? super Peer> subscriber) { private BluetoothFinder(Context context, Subscriber<? super Peer> subscriber) {
super(context, subscriber); super(context, subscriber);
adapter = BluetoothAdapter.getDefaultAdapter(); adapter = BluetoothAdapter.getDefaultAdapter();
} }

View File

@ -71,7 +71,7 @@ public class BluetoothPeer implements Peer {
dest.writeParcelable(this.device, 0); dest.writeParcelable(this.device, 0);
} }
protected BluetoothPeer(Parcel in) { private BluetoothPeer(Parcel in) {
this.device = in.readParcelable(BluetoothDevice.class.getClassLoader()); this.device = in.readParcelable(BluetoothDevice.class.getClassLoader());
} }

View File

@ -19,7 +19,7 @@ import rx.Subscriber;
import rx.functions.Action0; import rx.functions.Action0;
import rx.subscriptions.Subscriptions; import rx.subscriptions.Subscriptions;
class BonjourFinder extends PeerFinder implements ServiceListener { final class BonjourFinder extends PeerFinder implements ServiceListener {
public static Observable<Peer> createBonjourObservable(final Context context) { public static Observable<Peer> createBonjourObservable(final Context context) {
return Observable.create(new Observable.OnSubscribe<Peer>() { return Observable.create(new Observable.OnSubscribe<Peer>() {
@ -41,14 +41,14 @@ class BonjourFinder extends PeerFinder implements ServiceListener {
private static final String TAG = "BonjourFinder"; private static final String TAG = "BonjourFinder";
public static final String HTTP_SERVICE_TYPE = "_http._tcp.local."; private static final String HTTP_SERVICE_TYPE = "_http._tcp.local.";
public static final String HTTPS_SERVICE_TYPE = "_https._tcp.local."; private static final String HTTPS_SERVICE_TYPE = "_https._tcp.local.";
private JmDNS jmdns; private JmDNS jmdns;
private WifiManager wifiManager; private WifiManager wifiManager;
private WifiManager.MulticastLock mMulticastLock; private WifiManager.MulticastLock mMulticastLock;
BonjourFinder(Context context, Subscriber<? super Peer> subscriber) { private BonjourFinder(Context context, Subscriber<? super Peer> subscriber) {
super(context, subscriber); super(context, subscriber);
} }

View File

@ -20,7 +20,7 @@ public class WifiPeer implements Peer {
this(config.getRepoUri(), config.getHost(), !config.preventFurtherSwaps()); this(config.getRepoUri(), config.getHost(), !config.preventFurtherSwaps());
} }
protected WifiPeer(Uri uri, String name, boolean shouldPromptForSwapBack) { private WifiPeer(Uri uri, String name, boolean shouldPromptForSwapBack) {
this.name = name; this.name = name;
this.uri = uri; this.uri = uri;
this.shouldPromptForSwapBack = shouldPromptForSwapBack; this.shouldPromptForSwapBack = shouldPromptForSwapBack;
@ -63,7 +63,7 @@ public class WifiPeer implements Peer {
dest.writeByte(shouldPromptForSwapBack ? (byte) 1 : (byte) 0); dest.writeByte(shouldPromptForSwapBack ? (byte) 1 : (byte) 0);
} }
protected WifiPeer(Parcel in) { private WifiPeer(Parcel in) {
this(Uri.parse(in.readString()), in.readString(), in.readByte() == 1); this(Uri.parse(in.readString()), in.readString(), in.readByte() == 1);
} }

View File

@ -54,7 +54,7 @@ public class BluetoothDownloader extends Downloader {
* May return null if an error occurred while getting file details. * May return null if an error occurred while getting file details.
*/ */
@Nullable @Nullable
public FileDetails getFileDetails() { private FileDetails getFileDetails() {
if (fileDetails == null) { if (fileDetails == null) {
Utils.debugLog(TAG, "Going to Bluetooth \"server\" to get file details."); Utils.debugLog(TAG, "Going to Bluetooth \"server\" to get file details.");
try { try {

View File

@ -4,12 +4,10 @@ import org.fdroid.fdroid.ProgressListener;
import org.fdroid.fdroid.Utils; import org.fdroid.fdroid.Utils;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.util.Timer; import java.util.Timer;
import java.util.TimerTask; import java.util.TimerTask;
@ -46,8 +44,7 @@ public abstract class Downloader {
protected abstract void close(); protected abstract void close();
Downloader(URL url, File destFile) Downloader(URL url, File destFile) {
throws FileNotFoundException, MalformedURLException {
this.sourceUrl = url; this.sourceUrl = url;
outputFile = destFile; outputFile = destFile;
} }

View File

@ -23,12 +23,12 @@ import info.guardianproject.netcipher.NetCipher;
public class HttpDownloader extends Downloader { public class HttpDownloader extends Downloader {
private static final String TAG = "HttpDownloader"; private static final String TAG = "HttpDownloader";
protected static final String HEADER_IF_NONE_MATCH = "If-None-Match"; private static final String HEADER_IF_NONE_MATCH = "If-None-Match";
protected static final String HEADER_FIELD_ETAG = "ETag"; private static final String HEADER_FIELD_ETAG = "ETag";
private final String username; private final String username;
private final String password; private final String password;
protected HttpURLConnection connection; private HttpURLConnection connection;
private int statusCode = -1; private int statusCode = -1;
HttpDownloader(URL url, File destFile) HttpDownloader(URL url, File destFile)
@ -135,7 +135,7 @@ public class HttpDownloader extends Downloader {
/** /**
* @return Whether the connection is resumable or not * @return Whether the connection is resumable or not
*/ */
protected void setupConnection(boolean resumable) throws IOException { private void setupConnection(boolean resumable) throws IOException {
if (connection != null) { if (connection != null) {
return; return;
} }
@ -147,7 +147,7 @@ public class HttpDownloader extends Downloader {
} }
} }
protected void doDownload(boolean resumable) throws IOException, InterruptedException { private void doDownload(boolean resumable) throws IOException, InterruptedException {
if (wantToCheckCache()) { if (wantToCheckCache()) {
setupCacheCheck(); setupCacheCheck();
Utils.debugLog(TAG, "Checking cached status of " + sourceUrl); Utils.debugLog(TAG, "Checking cached status of " + sourceUrl);

View File

@ -20,7 +20,7 @@ public class BluetoothConnection {
private OutputStream output; private OutputStream output;
private final BluetoothSocket socket; private final BluetoothSocket socket;
public BluetoothConnection(BluetoothSocket socket) throws IOException { public BluetoothConnection(BluetoothSocket socket) {
this.socket = socket; this.socket = socket;
} }

View File

@ -5,7 +5,7 @@ import java.util.UUID;
/** /**
* We need some shared information between the client and the server app. * We need some shared information between the client and the server app.
*/ */
public class BluetoothConstants { class BluetoothConstants {
public static UUID fdroidUuid() { public static UUID fdroidUuid() {
// TODO: Generate a UUID deterministically from, e.g. "org.fdroid.fdroid.net.Bluetooth"; // TODO: Generate a UUID deterministically from, e.g. "org.fdroid.fdroid.net.Bluetooth";

View File

@ -144,7 +144,7 @@ public class BluetoothServer extends Thread {
} }
private Response handleRequest(Request request) throws IOException { private Response handleRequest(Request request) {
Utils.debugLog(TAG, "Received Bluetooth request from client, will process it now."); Utils.debugLog(TAG, "Received Bluetooth request from client, will process it now.");

View File

@ -8,7 +8,6 @@ import org.fdroid.fdroid.net.bluetooth.FileDetails;
import org.fdroid.fdroid.net.bluetooth.httpish.headers.Header; import org.fdroid.fdroid.net.bluetooth.httpish.headers.Header;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;
@ -130,23 +129,6 @@ public class Response {
} }
public String readContents() throws IOException {
int size = getFileSize();
if (contentStream == null || size <= 0) {
return null;
}
int pos = 0;
byte[] buffer = new byte[4096];
ByteArrayOutputStream contents = new ByteArrayOutputStream(size);
while (pos < size) {
int read = contentStream.read(buffer);
pos += read;
contents.write(buffer, 0, read);
}
return contents.toString();
}
public static class Builder { public static class Builder {
private InputStream contentStream; private InputStream contentStream;

View File

@ -22,7 +22,6 @@ import android.annotation.TargetApi;
import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo; import android.content.pm.PackageInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build; import android.os.Build;
import org.fdroid.fdroid.data.Apk; import org.fdroid.fdroid.data.Apk;
@ -61,27 +60,6 @@ public class AppDiff {
init(); init();
} }
public AppDiff(PackageManager mPm, Uri mPackageURI) {
this.mPm = mPm;
final String pkgPath = mPackageURI.getPath();
mPkgInfo = mPm.getPackageArchiveInfo(pkgPath, PackageManager.GET_PERMISSIONS);
// We could not get the package info from the file. This means that we
// could not parse the file, which can happen if the file cannot be
// read or the minSdk is not satisfied.
// Since we can't return an error from a constructor, we refuse to
// continue. The caller must check if mPkgInfo is null to see if the
// AppDiff was initialised correctly.
if (mPkgInfo == null) {
return;
}
mPkgInfo.applicationInfo.sourceDir = pkgPath;
mPkgInfo.applicationInfo.publicSourceDir = pkgPath;
init();
}
private void init() { private void init() {
String pkgName = mPkgInfo.packageName; String pkgName = mPkgInfo.packageName;
// Check if there is already a package on the device with this name // Check if there is already a package on the device with this name

View File

@ -37,7 +37,7 @@ public abstract class AppListFragment extends ListFragment implements
private static final int REQUEST_APPDETAILS = 0; private static final int REQUEST_APPDETAILS = 0;
public static final String[] APP_PROJECTION = { private static final String[] APP_PROJECTION = {
AppProvider.DataColumns._ID, // Required for cursor loader to work. AppProvider.DataColumns._ID, // Required for cursor loader to work.
AppProvider.DataColumns.PACKAGE_NAME, AppProvider.DataColumns.PACKAGE_NAME,
AppProvider.DataColumns.NAME, AppProvider.DataColumns.NAME,
@ -55,9 +55,9 @@ public abstract class AppListFragment extends ListFragment implements
AppProvider.DataColumns.REQUIREMENTS, // Needed for filtering apps that require root. AppProvider.DataColumns.REQUIREMENTS, // Needed for filtering apps that require root.
}; };
public static final String APP_SORT = AppProvider.DataColumns.NAME; private static final String APP_SORT = AppProvider.DataColumns.NAME;
protected AppListAdapter appAdapter; private AppListAdapter appAdapter;
@Nullable private String searchQuery; @Nullable private String searchQuery;
@ -80,7 +80,7 @@ public abstract class AppListFragment extends ListFragment implements
* NOTE: This will get called <em>multiple</em> times, every time the user changes the * NOTE: This will get called <em>multiple</em> times, every time the user changes the
* search query. * search query.
*/ */
protected void onSearch() { void onSearch() {
// Do nothing by default. // Do nothing by default.
} }
@ -176,7 +176,7 @@ public abstract class AppListFragment extends ListFragment implements
} }
} }
protected Intent getAppDetailsIntent() { private Intent getAppDetailsIntent() {
return new Intent(getActivity(), AppDetails.class); return new Intent(getActivity(), AppDetails.class);
} }

View File

@ -3,7 +3,7 @@ buildscript {
jcenter() jcenter()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:2.1.0' classpath 'com.android.tools.build:gradle:2.1.2'
classpath files('libs/gradle-witness.jar') classpath files('libs/gradle-witness.jar')
} }
} }