// Copyright (C) 2017 The Android Open Source Project
//
// 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.

cc_defaults {
    name: "adb_defaults",

    cflags: [
        "-Wall",
        "-Wextra",
        "-Werror",
        "-Wexit-time-destructors",
        "-Wno-unused-parameter",
        "-Wno-missing-field-initializers",
        "-Wthread-safety",
        "-Wvla",
        "-DADB_HOST=1",         // overridden by adbd_defaults
        "-DALLOW_ADBD_ROOT=0",  // overridden by adbd_defaults
    ],
    cpp_std: "experimental",

    use_version_lib: true,
    compile_multilib: "first",

    target: {
        darwin: {
            host_ldlibs: [
                "-lpthread",
                "-framework CoreFoundation",
                "-framework IOKit",
                "-lobjc",
            ],
        },

        windows: {
            cflags: [
                // Define windows.h and tchar.h Unicode preprocessor symbols so that
                // CreateFile(), _tfopen(), etc. map to versions that take wchar_t*, breaking the
                // build if you accidentally pass char*. Fix by calling like:
                //   std::wstring path_wide;
                //   if (!android::base::UTF8ToWide(path_utf8, &path_wide)) { /* error handling */ }
                //   CreateFileW(path_wide.c_str());
                "-DUNICODE=1",
                "-D_UNICODE=1",

                // Unlike on Linux, -std=gnu++ doesn't set _GNU_SOURCE on Windows.
                "-D_GNU_SOURCE",

                // MinGW hides some things behind _POSIX_SOURCE.
                "-D_POSIX_SOURCE",

                // Not supported yet.
                "-Wno-thread-safety",
            ],

            host_ldlibs: [
                "-lws2_32",
                "-lgdi32",
                "-luserenv",
            ],
        },
    },
}

cc_defaults {
    name: "adbd_defaults",
    defaults: ["adb_defaults"],

    cflags: ["-UADB_HOST", "-DADB_HOST=0"],
    product_variables: {
        debuggable: {
            cflags: [
                "-UALLOW_ADBD_ROOT",
                "-DALLOW_ADBD_ROOT=1",
                "-DALLOW_ADBD_DISABLE_VERITY",
                "-DALLOW_ADBD_NO_AUTH",
            ],
        },
    },
}

cc_defaults {
    name: "host_adbd_supported",

    host_supported: true,
    target: {
        linux: {
            enabled: true,
            host_ldlibs: [
                "-lresolv", // b64_pton
                "-lutil", // forkpty
            ],
        },
        darwin: {
            enabled: false,
        },
        windows: {
            enabled: false,
        },
    },
}

// libadb
// =========================================================
// These files are compiled for both the host and the device.
libadb_srcs = [
    "adb.cpp",
    "adb_io.cpp",
    "adb_listeners.cpp",
    "adb_trace.cpp",
    "adb_unique_fd.cpp",
    "adb_utils.cpp",
    "fdevent.cpp",
    "services.cpp",
    "sockets.cpp",
    "socket_spec.cpp",
    "sysdeps/errno.cpp",
    "transport.cpp",
    "transport_fd.cpp",
    "transport_local.cpp",
    "transport_usb.cpp",
]

libadb_posix_srcs = [
    "sysdeps_unix.cpp",
    "sysdeps/posix/network.cpp",
]

libadb_test_srcs = [
    "adb_io_test.cpp",
    "adb_listeners_test.cpp",
    "adb_utils_test.cpp",
    "fdevent_test.cpp",
    "socket_spec_test.cpp",
    "socket_test.cpp",
    "sysdeps_test.cpp",
    "sysdeps/stat_test.cpp",
    "transport_test.cpp",
    "types_test.cpp",
]

cc_library_host_static {
    name: "libadb_host",
    defaults: ["adb_defaults"],

    srcs: libadb_srcs + [
        "client/auth.cpp",
        "client/usb_libusb.cpp",
        "client/usb_dispatch.cpp",
        "client/transport_mdns.cpp",
    ],

    generated_headers: ["platform_tools_version"],

    target: {
        linux: {
            srcs: ["client/usb_linux.cpp"],
        },
        darwin: {
            srcs: ["client/usb_osx.cpp"],
        },

        not_windows: {
            srcs: libadb_posix_srcs,
        },
        windows: {
            enabled: true,
            srcs: [
                "client/usb_windows.cpp",
                "sysdeps_win32.cpp",
                "sysdeps/win32/errno.cpp",
                "sysdeps/win32/stat.cpp",
            ],
            shared_libs: ["AdbWinApi"],
        },
    },

    static_libs: [
        "libbase",
        "libcrypto_utils",
        "libcrypto",
        "libdiagnose_usb",
        "libmdnssd",
        "libusb",
        "libutils",
        "liblog",
        "libcutils",
    ],
}

cc_test_host {
    name: "adb_test",
    defaults: ["adb_defaults"],
    srcs: libadb_test_srcs,
    static_libs: [
        "libadb_host",
        "libbase",
        "libcutils",
        "libcrypto_utils",
        "libcrypto",
        "libmdnssd",
        "libdiagnose_usb",
        "libusb",
    ],

    target: {
        windows: {
            enabled: true,
            shared_libs: ["AdbWinApi"],
        },
    },
}

cc_benchmark {
    name: "adb_benchmark",
    defaults: ["adb_defaults"],

    srcs: ["transport_benchmark.cpp"],
    target: {
        android: {
            static_libs: [
                "libadbd",
            ],
        },
        host: {
            static_libs: [
                "libadb_host",
            ],
        },
    },

    static_libs: [
        "libbase",
        "libcutils",
        "libcrypto_utils",
        "libcrypto",
        "libdiagnose_usb",
        "liblog",
        "libusb",
    ],
}

cc_binary_host {
    name: "adb",

    defaults: ["adb_defaults"],

    srcs: [
        "client/adb_client.cpp",
        "client/bugreport.cpp",
        "client/commandline.cpp",
        "client/file_sync_client.cpp",
        "client/main.cpp",
        "client/console.cpp",
        "client/adb_install.cpp",
        "client/line_printer.cpp",
        "shell_service_protocol.cpp",
    ],

    static_libs: [
        "libadb_host",
        "libbase",
        "libcutils",
        "libcrypto_utils",
        "libcrypto",
        "libdiagnose_usb",
        "liblog",
        "libmdnssd",
        "libusb",
        "libutils",
        "liblog",
        "libcutils",
    ],

    stl: "libc++_static",

    // Don't add anything here, we don't want additional shared dependencies
    // on the host adb tool, and shared libraries that link against libc++
    // will violate ODR
    shared_libs: [],

    required: [
        "deploypatchgenerator",
    ],

    // Archive adb, adb.exe.
    dist: {
        targets: [
            "dist_files",
            "sdk",
            "win_sdk",
        ],
    },

    target: {
        darwin: {
            cflags: [
                "-Wno-sizeof-pointer-memaccess",
            ],
        },
        windows: {
            enabled: true,
            ldflags: ["-municode"],
            shared_libs: ["AdbWinApi"],
            required: [
                "AdbWinUsbApi",
            ],
        },
    },
}

// libadbd_core contains the common sources to build libadbd and libadbd_services.
cc_library_static {
    name: "libadbd_core",
    defaults: ["adbd_defaults", "host_adbd_supported"],
    recovery_available: true,

    // libminadbd wants both, as it's used to build native tests.
    compile_multilib: "both",

    srcs: libadb_srcs + libadb_posix_srcs + [
        "daemon/auth.cpp",
        "daemon/jdwp_service.cpp",
    ],

    local_include_dirs: [
        "daemon/include",
    ],

    generated_headers: ["platform_tools_version"],

    static_libs: [
        "libdiagnose_usb",
    ],

    shared_libs: [
        "libasyncio",
        "libbase",
        "libcrypto",
        "libcrypto_utils",
        "libcutils",
        "liblog",
    ],

    target: {
        android: {
            whole_static_libs: [
                "libqemu_pipe",
            ],
            srcs: [
                "daemon/transport_qemu.cpp",
                "daemon/usb.cpp",
                "daemon/usb_ffs.cpp",
                "daemon/usb_legacy.cpp",
            ]
        },
        linux_glibc: {
            srcs: [
                "daemon/usb_dummy.cpp",
            ]
        }
    },
}

cc_library {
    name: "libadbd_services",
    defaults: ["adbd_defaults", "host_adbd_supported"],
    recovery_available: true,
    compile_multilib: "both",

    srcs: [
        "daemon/file_sync_service.cpp",
        "daemon/services.cpp",
        "daemon/shell_service.cpp",
        "shell_service_protocol.cpp",
    ],

    cflags: [
        "-D_GNU_SOURCE",
        "-Wno-deprecated-declarations",
    ],

    static_libs: [
        "libadbd_core",
        "libdiagnose_usb",
    ],

    shared_libs: [
        "libasyncio",
        "libbase",
        "libcrypto",
        "libcrypto_utils",
        "libcutils",
        "liblog",
    ],

    product_variables: {
        debuggable: {
            required: [
                "remount",
            ],
        },
    },

    target: {
        android: {
            srcs: [
                "daemon/abb_service.cpp",
                "daemon/framebuffer_service.cpp",
                "daemon/mdns.cpp",
                "daemon/reboot_service.cpp",
                "daemon/remount_service.cpp",
                "daemon/restart_service.cpp",
                "daemon/set_verity_enable_state_service.cpp",
            ],
            static_libs: [
                "libavb_user",
            ],
            shared_libs: [
                "libbootloader_message",
                "libmdnssd",
                "libext4_utils",
                "libfec",
                "libfs_mgr",
                "libselinux",
            ],
        },
        recovery: {
            exclude_srcs: [
                "daemon/abb_service.cpp",
            ],
        },
    },
}

cc_library {
    name: "libadbd",
    defaults: ["adbd_defaults", "host_adbd_supported"],
    recovery_available: true,

    // Avoid getting duplicate symbol of android::build::GetBuildNumber().
    use_version_lib: false,

    // libminadbd wants both, as it's used to build native tests.
    compile_multilib: "both",

    // libadbd doesn't build any additional source, but to expose libadbd_core as a shared library.
    whole_static_libs: [
        "libadbd_core",
    ],

    shared_libs: [
        "libadbd_services",
        "libasyncio",
        "libbase",
        "libcrypto",
        "libcrypto_utils",
        "libcutils",
        "liblog",
    ],

    export_include_dirs: [
        "daemon/include",
    ],
}

cc_binary {
    name: "adbd",
    defaults: ["adbd_defaults", "host_adbd_supported"],
    recovery_available: true,

    srcs: [
        "daemon/main.cpp",
    ],

    cflags: [
        "-D_GNU_SOURCE",
        "-Wno-deprecated-declarations",
    ],

    strip: {
        keep_symbols: true,
    },

    shared_libs: [
        "libadbd",
        "libadbd_services",
        "libbase",
        "libcap",
        "libcrypto",
        "libcutils",
        "liblog",
        "libminijail",
        "libselinux",
    ],
}

cc_binary {
    name: "abb",

    defaults: ["adbd_defaults"],
    recovery_available: false,

    srcs: [
        "daemon/abb.cpp",
    ],

    cflags: [
        "-D_GNU_SOURCE",
        "-Wno-deprecated-declarations",
    ],

    strip: {
        keep_symbols: true,
    },

    static_libs: [
        "libadbd_core",
        "libadbd_services",
        "libcmd",
    ],

    shared_libs: [
        "libbase",
        "libbinder",
        "liblog",
        "libutils",
        "libselinux",
    ],
}

cc_test {
    name: "adbd_test",
    defaults: ["adbd_defaults"],
    srcs: libadb_test_srcs + [
        "daemon/services.cpp",
        "daemon/shell_service.cpp",
        "daemon/shell_service_test.cpp",
        "shell_service_protocol.cpp",
        "shell_service_protocol_test.cpp",
    ],

    static_libs: [
        "libadbd",
        "libbase",
        "libbootloader_message",
        "libcutils",
        "libcrypto_utils",
        "libcrypto",
        "libdiagnose_usb",
        "liblog",
        "libusb",
        "libmdnssd",
        "libselinux",
    ],
    test_suites: ["device-tests"],
}

python_test_host {
    name: "adb_integration_test_adb",
    main: "test_adb.py",
    srcs: [
        "test_adb.py",
    ],
    test_config: "adb_integration_test_adb.xml",
    test_suites: ["general-tests"],
    version: {
        py2: {
            enabled: false,
        },
        py3: {
            enabled: true,
        },
    },
}

python_test_host {
    name: "adb_integration_test_device",
    main: "test_device.py",
    srcs: [
        "test_device.py",
    ],
    libs: [
        "adb_py",
    ],
    test_config: "adb_integration_test_device.xml",
    test_suites: ["general-tests"],
    version: {
        py2: {
            enabled: true,
        },
        py3: {
            enabled: false,
        },
    },
}