Merge pull request #10051 from nextcloud/fdroid-no-scan

Don't include document scanner in FDroid version
This commit is contained in:
Álvaro Brey 2022-04-07 12:46:08 +02:00 committed by GitHub
commit d97edf023d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 391 additions and 61 deletions

View file

@ -261,7 +261,11 @@ dependencies {
implementation "com.github.cotechde.hwsecurity:hwsecurity-fido:$fidoVersion" implementation "com.github.cotechde.hwsecurity:hwsecurity-fido:$fidoVersion"
implementation "com.github.cotechde.hwsecurity:hwsecurity-fido2:$fidoVersion" implementation "com.github.cotechde.hwsecurity:hwsecurity-fido2:$fidoVersion"
implementation 'com.github.zynkware:Document-Scanning-Android-SDK:1.0.1' // document scanner not available on FDroid (generic) due to OpenCV binaries
gplayImplementation "com.github.zynkware:Document-Scanning-Android-SDK:$documentScannerVersion"
huaweiImplementation "com.github.zynkware:Document-Scanning-Android-SDK:$documentScannerVersion"
qaImplementation "com.github.zynkware:Document-Scanning-Android-SDK:$documentScannerVersion"
versionDevImplementation "com.github.zynkware:Document-Scanning-Android-SDK:$documentScannerVersion"
spotbugsPlugins 'com.h3xstream.findsecbugs:findsecbugs-plugin:1.12.0' spotbugsPlugins 'com.h3xstream.findsecbugs:findsecbugs-plugin:1.12.0'
spotbugsPlugins 'com.mebigfatguy.fb-contrib:fb-contrib:7.4.7' spotbugsPlugins 'com.mebigfatguy.fb-contrib:fb-contrib:7.4.7'

View file

@ -0,0 +1,30 @@
<!--
~ Nextcloud Android client application
~
~ @author Álvaro Brey Vilas
~ Copyright (C) 2022 Álvaro Brey Vilas
~ Copyright (C) 2022 Nextcloud GmbH
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <https://www.gnu.org/licenses/>.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application>
<activity
android:name=".ui.activity.AppScanActivity"
tools:node="remove" />
</application>
</manifest>

View file

@ -0,0 +1,42 @@
/*
*
* Nextcloud Android client application
*
* @author Tobias Kaminsky
* Copyright (C) 2022 Tobias Kaminsky
* Copyright (C) 2022 Nextcloud GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.owncloud.android.ui.activity
import android.app.Activity
import com.owncloud.android.lib.common.utils.Log_OC
class AppScanActivity {
// stub
companion object {
private val TAG = AppScanActivity::class.simpleName
@JvmStatic
val enabled: Boolean = false
@JvmStatic
fun scanFromCamera(activity: Activity, requestcode: Int) {
// stub
Log_OC.w(TAG, "scanFromCamera called in stub implementation")
}
}
}

View file

@ -0,0 +1,81 @@
/*
* Nextcloud Android client application
*
* @author Álvaro Brey Vilas
* Copyright (C) 2022 Álvaro Brey Vilas
* Copyright (C) 2022 Nextcloud GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.owncloud.android.ui.activity
import android.Manifest
import android.app.Activity
import android.content.Intent
import android.graphics.Bitmap
import android.os.Bundle
import com.owncloud.android.R
import com.owncloud.android.utils.DisplayUtils
import com.owncloud.android.utils.PermissionUtil
import com.zynksoftware.documentscanner.ScanActivity
import com.zynksoftware.documentscanner.model.DocumentScannerErrorModel
import com.zynksoftware.documentscanner.model.ScannerResults
import com.zynksoftware.documentscanner.ui.DocumentScanner
@Suppress("unused")
class AppScanActivity : ScanActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
addFragmentContentLayout()
}
override fun onError(error: DocumentScannerErrorModel) {
DisplayUtils.showSnackMessage(this, R.string.error_starting_scan_doc)
}
override fun onSuccess(scannerResults: ScannerResults) {
val intent = Intent()
intent.putExtra(
"file",
scannerResults.transformedImageFile?.absolutePath ?: scannerResults.croppedImageFile?.absolutePath
)
setResult(Activity.RESULT_OK, intent)
finish()
}
override fun onClose() {
finish()
}
companion object {
@JvmStatic
val enabled: Boolean = true
@JvmStatic
fun scanFromCamera(activity: Activity, requestCode: Int) {
val configuration = DocumentScanner.Configuration()
configuration.imageType = Bitmap.CompressFormat.PNG
DocumentScanner.init(activity, configuration)
val scanIntent = Intent(activity, AppScanActivity::class.java)
if (PermissionUtil.checkSelfPermission(activity, Manifest.permission.CAMERA)) {
activity.startActivityForResult(scanIntent, requestCode)
} else {
PermissionUtil.requestCameraPermission(activity, PermissionUtil.PERMISSIONS_SCAN_DOCUMENT)
}
}
}
}

View file

@ -1,32 +0,0 @@
/*
* Nextcloud Android client application
*
* @author Tobias Kaminsky
* Copyright (C) 2021 Nextcloud
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
* License as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
*
* You should have received a copy of the GNU Affero General Public
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.owncloud.android.ui.activity
import android.view.View
/**
* Activity providing information about ways to participate in the app's development.
*/
class HuaweiCommunityActivity : CommunityActivity() {
override fun setupContent() {
super.setupContent()
binding.communityReleaseCandidatePlaystore.visibility = View.GONE
}
}

View file

@ -1,35 +1,38 @@
/* /*
*
* Nextcloud Android client application * Nextcloud Android client application
* *
* @author Tobias Kaminsky * @author Álvaro Brey Vilas
* Copyright (C) 2022 Tobias Kaminsky * Copyright (C) 2022 Álvaro Brey Vilas
* Copyright (C) 2022 Nextcloud GmbH * Copyright (C) 2022 Nextcloud GmbH
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU Affero General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.owncloud.android.ui.activity package com.owncloud.android.ui.activity
import android.Manifest
import android.app.Activity import android.app.Activity
import android.content.Intent import android.content.Intent
import android.graphics.Bitmap
import android.os.Bundle import android.os.Bundle
import com.owncloud.android.R import com.owncloud.android.R
import com.owncloud.android.utils.DisplayUtils import com.owncloud.android.utils.DisplayUtils
import com.owncloud.android.utils.PermissionUtil
import com.zynksoftware.documentscanner.ScanActivity import com.zynksoftware.documentscanner.ScanActivity
import com.zynksoftware.documentscanner.model.DocumentScannerErrorModel import com.zynksoftware.documentscanner.model.DocumentScannerErrorModel
import com.zynksoftware.documentscanner.model.ScannerResults import com.zynksoftware.documentscanner.model.ScannerResults
import com.zynksoftware.documentscanner.ui.DocumentScanner
class AppScanActivity : ScanActivity() { class AppScanActivity : ScanActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
@ -56,4 +59,22 @@ class AppScanActivity : ScanActivity() {
override fun onClose() { override fun onClose() {
finish() finish()
} }
companion object {
@JvmStatic
val enabled: Boolean = true
@JvmStatic
fun scanFromCamera(activity: Activity, requestCode: Int) {
val configuration = DocumentScanner.Configuration()
configuration.imageType = Bitmap.CompressFormat.PNG
DocumentScanner.init(activity, configuration)
val scanIntent = Intent(activity, AppScanActivity::class.java)
if (PermissionUtil.checkSelfPermission(activity, Manifest.permission.CAMERA)) {
activity.startActivityForResult(scanIntent, requestCode)
} else {
PermissionUtil.requestCameraPermission(activity, PermissionUtil.PERMISSIONS_SCAN_DOCUMENT)
}
}
}
} }

View file

@ -0,0 +1,33 @@
/*
* Nextcloud Android client application
*
* @author Álvaro Brey Vilas
* Copyright (C) 2022 Álvaro Brey Vilas
* Copyright (C) 2022 Nextcloud GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.owncloud.android.ui.activity
import android.view.View
/**
* Activity providing information about ways to participate in the app's development.
*/
class HuaweiCommunityActivity : CommunityActivity() {
override fun setupContent() {
super.setupContent()
binding.communityReleaseCandidatePlaystore.visibility = View.GONE
}
}

View file

@ -399,7 +399,7 @@ public class FileDisplayActivity extends FileActivity
// If request is cancelled, result arrays are empty. // If request is cancelled, result arrays are empty.
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted // permission was granted
getFileOperationsHelper().scanFromCamera( AppScanActivity.scanFromCamera(
this, this,
FileDisplayActivity.REQUEST_CODE__UPLOAD_SCAN_DOC_FROM_CAMERA); FileDisplayActivity.REQUEST_CODE__UPLOAD_SCAN_DOC_FROM_CAMERA);
} }

View file

@ -38,6 +38,7 @@ import com.owncloud.android.files.FileMenuFilter;
import com.owncloud.android.lib.common.Creator; import com.owncloud.android.lib.common.Creator;
import com.owncloud.android.lib.common.DirectEditing; import com.owncloud.android.lib.common.DirectEditing;
import com.owncloud.android.lib.resources.status.OCCapability; import com.owncloud.android.lib.resources.status.OCCapability;
import com.owncloud.android.ui.activity.AppScanActivity;
import com.owncloud.android.ui.activity.FileActivity; import com.owncloud.android.ui.activity.FileActivity;
import com.owncloud.android.utils.MimeTypeUtil; import com.owncloud.android.utils.MimeTypeUtil;
import com.owncloud.android.utils.theme.ThemeColorUtils; import com.owncloud.android.utils.theme.ThemeColorUtils;
@ -183,10 +184,14 @@ public class OCFileListBottomSheetDialog extends BottomSheetDialog {
dismiss(); dismiss();
}); });
binding.menuScanDocUpload.setOnClickListener(v -> { if(AppScanActivity.getEnabled()) {
actions.scanDocUpload(); binding.menuScanDocUpload.setOnClickListener(v -> {
dismiss(); actions.scanDocUpload();
}); dismiss();
});
}else {
binding.menuScanDocUpload.setVisibility(View.GONE);
}
binding.menuUploadFiles.setOnClickListener(v -> { binding.menuUploadFiles.setOnClickListener(v -> {
actions.uploadFiles(); actions.uploadFiles();

View file

@ -72,6 +72,7 @@ import com.owncloud.android.lib.resources.e2ee.ToggleEncryptionRemoteOperation;
import com.owncloud.android.lib.resources.files.SearchRemoteOperation; import com.owncloud.android.lib.resources.files.SearchRemoteOperation;
import com.owncloud.android.lib.resources.files.ToggleFavoriteRemoteOperation; import com.owncloud.android.lib.resources.files.ToggleFavoriteRemoteOperation;
import com.owncloud.android.lib.resources.status.OCCapability; import com.owncloud.android.lib.resources.status.OCCapability;
import com.owncloud.android.ui.activity.AppScanActivity;
import com.owncloud.android.ui.activity.FileActivity; import com.owncloud.android.ui.activity.FileActivity;
import com.owncloud.android.ui.activity.FileDisplayActivity; import com.owncloud.android.ui.activity.FileDisplayActivity;
import com.owncloud.android.ui.activity.FolderPickerActivity; import com.owncloud.android.ui.activity.FolderPickerActivity;
@ -486,7 +487,7 @@ public class OCFileListFragment extends ExtendedListFragment implements
FileDisplayActivity fileDisplayActivity = (FileDisplayActivity) getActivity(); FileDisplayActivity fileDisplayActivity = (FileDisplayActivity) getActivity();
if (fileDisplayActivity != null) { if (fileDisplayActivity != null) {
fileDisplayActivity.getFileOperationsHelper() AppScanActivity
.scanFromCamera(fileDisplayActivity, FileDisplayActivity.REQUEST_CODE__UPLOAD_SCAN_DOC_FROM_CAMERA); .scanFromCamera(fileDisplayActivity, FileDisplayActivity.REQUEST_CODE__UPLOAD_SCAN_DOC_FROM_CAMERA);
} else { } else {
Toast.makeText(getContext(), Toast.makeText(getContext(),

View file

@ -37,7 +37,6 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo; import android.content.pm.ResolveInfo;
import android.graphics.Bitmap;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.os.Environment; import android.os.Environment;
@ -69,7 +68,6 @@ import com.owncloud.android.lib.resources.shares.ShareType;
import com.owncloud.android.lib.resources.status.OCCapability; import com.owncloud.android.lib.resources.status.OCCapability;
import com.owncloud.android.operations.SynchronizeFileOperation; import com.owncloud.android.operations.SynchronizeFileOperation;
import com.owncloud.android.services.OperationsService; import com.owncloud.android.services.OperationsService;
import com.owncloud.android.ui.activity.AppScanActivity;
import com.owncloud.android.ui.activity.ConflictsResolveActivity; import com.owncloud.android.ui.activity.ConflictsResolveActivity;
import com.owncloud.android.ui.activity.ExternalSiteWebView; import com.owncloud.android.ui.activity.ExternalSiteWebView;
import com.owncloud.android.ui.activity.FileActivity; import com.owncloud.android.ui.activity.FileActivity;
@ -86,7 +84,6 @@ import com.owncloud.android.utils.DisplayUtils;
import com.owncloud.android.utils.FileStorageUtils; import com.owncloud.android.utils.FileStorageUtils;
import com.owncloud.android.utils.PermissionUtil; import com.owncloud.android.utils.PermissionUtil;
import com.owncloud.android.utils.UriUtils; import com.owncloud.android.utils.UriUtils;
import com.zynksoftware.documentscanner.ui.DocumentScanner;
import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.EventBus;
@ -1075,19 +1072,6 @@ public class FileOperationsHelper {
} }
} }
public void scanFromCamera(Activity activity, int requestCode) {
DocumentScanner.Configuration configuration = new DocumentScanner.Configuration();
configuration.setImageType(Bitmap.CompressFormat.PNG);
DocumentScanner.INSTANCE.init(activity, configuration);
Intent scanIntent = new Intent(activity, AppScanActivity.class);
if (PermissionUtil.checkSelfPermission(activity, Manifest.permission.CAMERA)) {
activity.startActivityForResult(scanIntent, requestCode);
} else {
PermissionUtil.requestCameraPermission(activity, PermissionUtil.PERMISSIONS_SCAN_DOCUMENT);
}
}
public static File createImageFile(Activity activity) { public static File createImageFile(Activity activity) {
File storageDir = activity.getExternalFilesDir(Environment.DIRECTORY_PICTURES); File storageDir = activity.getExternalFilesDir(Environment.DIRECTORY_PICTURES);

View file

@ -0,0 +1,80 @@
/*
* Nextcloud Android client application
*
* @author Álvaro Brey Vilas
* Copyright (C) 2022 Álvaro Brey Vilas
* Copyright (C) 2022 Nextcloud GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.owncloud.android.ui.activity
import android.Manifest
import android.app.Activity
import android.content.Intent
import android.graphics.Bitmap
import android.os.Bundle
import com.owncloud.android.R
import com.owncloud.android.utils.DisplayUtils
import com.owncloud.android.utils.PermissionUtil
import com.zynksoftware.documentscanner.ScanActivity
import com.zynksoftware.documentscanner.model.DocumentScannerErrorModel
import com.zynksoftware.documentscanner.model.ScannerResults
import com.zynksoftware.documentscanner.ui.DocumentScanner
class AppScanActivity : ScanActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
addFragmentContentLayout()
}
override fun onError(error: DocumentScannerErrorModel) {
DisplayUtils.showSnackMessage(this, R.string.error_starting_scan_doc)
}
override fun onSuccess(scannerResults: ScannerResults) {
val intent = Intent()
intent.putExtra(
"file",
scannerResults.transformedImageFile?.absolutePath ?: scannerResults.croppedImageFile?.absolutePath
)
setResult(Activity.RESULT_OK, intent)
finish()
}
override fun onClose() {
finish()
}
companion object {
@JvmStatic
val enabled: Boolean = true
@JvmStatic
fun scanFromCamera(activity: Activity, requestCode: Int) {
val configuration = DocumentScanner.Configuration()
configuration.imageType = Bitmap.CompressFormat.PNG
DocumentScanner.init(activity, configuration)
val scanIntent = Intent(activity, AppScanActivity::class.java)
if (PermissionUtil.checkSelfPermission(activity, Manifest.permission.CAMERA)) {
activity.startActivityForResult(scanIntent, requestCode)
} else {
PermissionUtil.requestCameraPermission(activity, PermissionUtil.PERMISSIONS_SCAN_DOCUMENT)
}
}
}
}

View file

@ -0,0 +1,80 @@
/*
* Nextcloud Android client application
*
* @author Álvaro Brey Vilas
* Copyright (C) 2022 Álvaro Brey Vilas
* Copyright (C) 2022 Nextcloud GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.owncloud.android.ui.activity
import android.Manifest
import android.app.Activity
import android.content.Intent
import android.graphics.Bitmap
import android.os.Bundle
import com.owncloud.android.R
import com.owncloud.android.utils.DisplayUtils
import com.owncloud.android.utils.PermissionUtil
import com.zynksoftware.documentscanner.ScanActivity
import com.zynksoftware.documentscanner.model.DocumentScannerErrorModel
import com.zynksoftware.documentscanner.model.ScannerResults
import com.zynksoftware.documentscanner.ui.DocumentScanner
class AppScanActivity : ScanActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
addFragmentContentLayout()
}
override fun onError(error: DocumentScannerErrorModel) {
DisplayUtils.showSnackMessage(this, R.string.error_starting_scan_doc)
}
override fun onSuccess(scannerResults: ScannerResults) {
val intent = Intent()
intent.putExtra(
"file",
scannerResults.transformedImageFile?.absolutePath ?: scannerResults.croppedImageFile?.absolutePath
)
setResult(Activity.RESULT_OK, intent)
finish()
}
override fun onClose() {
finish()
}
companion object {
@JvmStatic
val enabled: Boolean = true
@JvmStatic
fun scanFromCamera(activity: Activity, requestCode: Int) {
val configuration = DocumentScanner.Configuration()
configuration.imageType = Bitmap.CompressFormat.PNG
DocumentScanner.init(activity, configuration)
val scanIntent = Intent(activity, AppScanActivity::class.java)
if (PermissionUtil.checkSelfPermission(activity, Manifest.permission.CAMERA)) {
activity.startActivityForResult(scanIntent, requestCode)
} else {
PermissionUtil.requestCameraPermission(activity, PermissionUtil.PERMISSIONS_SCAN_DOCUMENT)
}
}
}
}

View file

@ -17,6 +17,7 @@ buildscript {
fidoVersion = "4.1.0" fidoVersion = "4.1.0"
checkerVersion = "3.21.2" checkerVersion = "3.21.2"
exoplayerVersion = "2.17.1" exoplayerVersion = "2.17.1"
documentScannerVersion = "1.0.1"
ciBuild = System.getenv("CI") == "true" ciBuild = System.getenv("CI") == "true"
} }