├── porting
├── adb
│ ├── client
│ │ ├── usb_libusb.cpp
│ │ ├── usb_osx.cpp
│ │ ├── adb_porting.h
│ │ ├── file_sync_client.h
│ │ ├── adb_porting.cpp
│ │ ├── transport_usb.cpp
│ │ ├── commandline.h
│ │ ├── bugreport.cpp
│ │ ├── main.cpp
│ │ ├── adb_client.cpp
│ │ └── adb_install.cpp
│ ├── include
│ │ ├── sys
│ │ │ └── user.h
│ │ └── adb_public.h
│ ├── crypto
│ │ └── include
│ │ │ └── adb
│ │ │ └── crypto
│ │ │ ├── x509_generator.h
│ │ │ └── key.h
│ ├── fdevent
│ │ ├── fdevent.h
│ │ ├── fdevent_poll.cpp
│ │ └── fdevent.cpp
│ └── adb_listeners.cpp
├── scripts
│ ├── make-zstd.sh
│ ├── make-lz4.sh
│ ├── make-brotli.sh
│ ├── defines.sh
│ ├── make-protobuf.sh
│ └── make-adb.sh
├── CMakeLists.txt
├── Makefile
├── protobuf.rb
├── cmake
│ └── CMakeLists.protobuf.txt
└── protobuf
│ └── src
│ └── google
│ └── protobuf
│ └── map_probe_benchmark.cc
├── .gitignore
├── example
└── adb-demo
│ ├── adb-demo
│ ├── Assets.xcassets
│ │ ├── Contents.json
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── ViewController.h
│ ├── AppDelegate.h
│ ├── SceneDelegate.h
│ ├── main.m
│ ├── Info.plist
│ ├── AppDelegate.m
│ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ ├── SceneDelegate.m
│ └── ViewController.m
│ └── adb-demo.xcodeproj
│ ├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ ├── xcuserdata
│ │ └── ethan.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
│ ├── xcuserdata
│ └── ethan.xcuserdatad
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
│ └── project.pbxproj
├── .gitmodules
├── Makefile
├── README.zh-cn.md
└── README.md
/porting/adb/client/usb_libusb.cpp:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/porting/adb/include/sys/user.h:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/porting/adb/client/usb_osx.cpp:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | android-tools/build
2 | output
3 | cmake-build-debug
4 | .idea
5 | xcuserdata
6 |
--------------------------------------------------------------------------------
/example/adb-demo/adb-demo/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/example/adb-demo/adb-demo.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/adb-demo/adb-demo/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/example/adb-demo/adb-demo/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // adb-demo
4 | //
5 | // Created by Ethan on 2022/6/1.
6 | //
7 |
8 | #import
9 |
10 | @interface ViewController : UIViewController
11 |
12 |
13 | @end
14 |
15 |
--------------------------------------------------------------------------------
/example/adb-demo/adb-demo.xcodeproj/project.xcworkspace/xcuserdata/ethan.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsvn53/adb-mobile/HEAD/example/adb-demo/adb-demo.xcodeproj/project.xcworkspace/xcuserdata/ethan.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/example/adb-demo/adb-demo/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // adb-demo
4 | //
5 | // Created by Ethan on 2022/6/1.
6 | //
7 |
8 | #import
9 |
10 | @interface AppDelegate : UIResponder
11 |
12 |
13 | @end
14 |
15 |
--------------------------------------------------------------------------------
/example/adb-demo/adb-demo/SceneDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // SceneDelegate.h
3 | // adb-demo
4 | //
5 | // Created by Ethan on 2022/6/1.
6 | //
7 |
8 | #import
9 |
10 | @interface SceneDelegate : UIResponder
11 |
12 | @property (strong, nonatomic) UIWindow * window;
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/example/adb-demo/adb-demo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/adb-demo/adb-demo.xcodeproj/xcuserdata/ethan.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | adb-demo.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/example/adb-demo/adb-demo/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // adb-demo
4 | //
5 | // Created by Ethan on 2022/6/1.
6 | //
7 |
8 | #import
9 | #import "AppDelegate.h"
10 |
11 | int main(int argc, char * argv[]) {
12 | NSString * appDelegateClassName;
13 | @autoreleasepool {
14 | // Setup code that might create autoreleased objects goes here.
15 | appDelegateClassName = NSStringFromClass([AppDelegate class]);
16 | }
17 | return UIApplicationMain(argc, argv, nil, appDelegateClassName);
18 | }
19 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "android-tools"]
2 | path = android-tools
3 | url = https://github.com/nmeum/android-tools.git
4 | [submodule "ios-cmake"]
5 | path = ios-cmake
6 | url = https://github.com/leetal/ios-cmake.git
7 | [submodule "external/lz4"]
8 | path = external/lz4
9 | url = https://android.googlesource.com/platform/external/lz4
10 | [submodule "external/zstd"]
11 | path = external/zstd
12 | url = https://android.googlesource.com/platform/external/zstd
13 | [submodule "external/brotli"]
14 | path = external/brotli
15 | url = https://android.googlesource.com/platform/external/brotli
16 | [submodule "external/protobuf"]
17 | path = external/protobuf
18 | url = https://github.com/protocolbuffers/protobuf.git
19 |
--------------------------------------------------------------------------------
/porting/scripts/make-zstd.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | . "$(dirname $0)/defines.sh";
4 |
5 | cmake_root=$SOURCE_ROOT/external/zstd/build/cmake/out;
6 |
7 | # Clean built products
8 | [[ -d "$cmake_root" ]] && rm -rfv "$cmake_root";
9 | mkdir -pv "$cmake_root";
10 |
11 | cd "$cmake_root"
12 |
13 | echo "→ Running cmake...";
14 | cmake .. -G Xcode -DCMAKE_TOOLCHAIN_FILE="$CMAKE_TOOLCHAIN_FILE" -DPLATFORM="$PLATFORM" \
15 | -DDEPLOYMENT_TARGET="$DEPLOYMENT_TARGET" $CMAKE_COMPAT_FLAGS
16 |
17 | echo "→ Building...";
18 | cmake --build . --config Debug --target libzstd_static --parallel 8
19 |
20 | echo "→ Copying output...";
21 | find . -name "*.a" -exec cp -av {} "$FULL_OUTPUT" \;
22 |
23 | echo "✅ zstd build completed successfully!"
24 |
--------------------------------------------------------------------------------
/porting/scripts/make-lz4.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | . "$(dirname $0)/defines.sh";
4 |
5 | cmake_root=$SOURCE_ROOT/external/lz4/contrib/cmake_unofficial/out;
6 |
7 | # Clean built products
8 | [[ -d "$cmake_root" ]] && rm -rfv "$cmake_root";
9 | mkdir -pv "$cmake_root";
10 |
11 | cd "$cmake_root"
12 |
13 | echo "→ Running cmake...";
14 | cmake .. -G Xcode -DCMAKE_TOOLCHAIN_FILE="$CMAKE_TOOLCHAIN_FILE" -DPLATFORM="$PLATFORM" \
15 | -DDEPLOYMENT_TARGET="$DEPLOYMENT_TARGET" -DBUILD_STATIC_LIBS=ON -DBUILD_SHARED_LIBS=OFF \
16 | $CMAKE_COMPAT_FLAGS
17 |
18 | echo "→ Building...";
19 | cmake --build . --config Debug --target lz4_static --parallel 8
20 |
21 | echo "→ Copying output...";
22 | find . -name "*.a" -exec cp -av {} "$FULL_OUTPUT" \;
23 |
24 | echo "✅ lz4 build completed successfully!"
25 |
--------------------------------------------------------------------------------
/example/adb-demo/adb-demo/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UIApplicationSceneManifest
6 |
7 | UIApplicationSupportsMultipleScenes
8 |
9 | UISceneConfigurations
10 |
11 | UIWindowSceneSessionRoleApplication
12 |
13 |
14 | UISceneConfigurationName
15 | Default Configuration
16 | UISceneDelegateClassName
17 | SceneDelegate
18 | UISceneStoryboardFile
19 | Main
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/porting/scripts/make-brotli.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | . "$(dirname $0)/defines.sh";
4 |
5 | cmake_root=$SOURCE_ROOT/external/brotli/out;
6 |
7 | # Clean built products
8 | [[ -d "$cmake_root" ]] && rm -rfv "$cmake_root";
9 | mkdir -pv "$cmake_root";
10 |
11 | cd "$cmake_root"
12 |
13 | echo "→ Running cmake...";
14 | cmake .. -G Xcode -DCMAKE_TOOLCHAIN_FILE="$CMAKE_TOOLCHAIN_FILE" -DPLATFORM="$PLATFORM" \
15 | -DDEPLOYMENT_TARGET="$DEPLOYMENT_TARGET" -DBROTLI_BUNDLED_MODE=1 $CMAKE_COMPAT_FLAGS
16 |
17 | echo "→ Building...";
18 | cmake --build . --config Debug --parallel 8 \
19 | --target brotlidec-static --target brotlienc-static --target brotlicommon-static
20 |
21 | echo "→ Copying output...";
22 | find . -name "*.a" -exec cp -av {} "$FULL_OUTPUT" \;
23 |
24 | echo "✅ brotli build completed successfully!"
25 |
--------------------------------------------------------------------------------
/porting/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.10)
2 |
3 | project(adb-porting)
4 |
5 | set(CMAKE_CXX_STANDARD 17)
6 | set(CMAKE_CXX_STANDARD_REQUIRED ON)
7 |
8 | set(ADB_CLIENT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/adb/client)
9 | set(ADB_VENDOR_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../android-tools/vendor/adb)
10 |
11 | file(GLOB_RECURSE ADB_CLIENT_SOURCES ${ADB_CLIENT_DIR}/*.cpp ${ADB_CLIENT_DIR}/*.h)
12 | file(GLOB_RECURSE ADB_VENDOR_SOURCES ${ADB_VENDOR_DIR}/*.cpp ${ADB_VENDOR_DIR}/*.h)
13 |
14 | set(ADB_PORTING_SOURCES ${ADB_CLIENT_SOURCES} ${ADB_VENDOR_SOURCES})
15 | add_library(adb-porting ${ADB_PORTING_SOURCES})
16 |
17 | target_compile_definitions(adb-porting PUBLIC ADB_HOST)
18 |
19 | target_include_directories(adb-porting PUBLIC
20 | ${ADB_CLIENT_DIR}
21 | ${ADB_VENDOR_DIR}
22 | ${ADB_VENDOR_DIR}/client
23 | ${CMAKE_CURRENT_SOURCE_DIR}/../android-tools/vendor/libbase/include
24 | ${CMAKE_CURRENT_SOURCE_DIR}/../android-tools/vendor/core/include
25 | ${CMAKE_CURRENT_SOURCE_DIR}/../external/protobuf/src
26 | )
27 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | all: check-protobuf-version libs libadb.a libadb.include
2 |
3 | brew-install-deps:
4 | brew install fmt cmake pkgconfig googletest
5 |
6 | check-protobuf-version:
7 | @grep $$(protoc --version | cut -d' ' -f2) porting/protobuf.rb || { echo "* To compile libadb please install protobuf version 28.3 by:" && echo "brew unlink protobuf && brew install porting/protobuf.rb" && echo "" && exit 1; }
8 | protoc --version
9 | exit 0
10 |
11 | check-golang:
12 | @which go || { echo "* To compile libadb please install golang by execute:"; echo ""; }
13 |
14 | libs:
15 | [[ -d output ]] || mkdir output && echo "mkdir output"
16 | make -C porting
17 |
18 | libadb.include:
19 | [[ ! -d output/include ]] && mkdir output/include || echo "make include";
20 | cp -av porting/adb/include/*.h output/include;
21 |
22 | libadb.a:
23 | rm -fv output/*/*/libadb-full.a || echo ""
24 | libtool -static -o output/iphoneos/arm64/libadb-full.a output/iphoneos/arm64/*.a
25 | libtool -static -o output/iphonesimulator/x86_64/libadb-full.a output/iphonesimulator/x86_64/*.a
26 | libtool -static -o output/iphonesimulator/arm64/libadb-full.a output/iphonesimulator/arm64/*.a
27 |
--------------------------------------------------------------------------------
/porting/adb/crypto/include/adb/crypto/x509_generator.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2019 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except
6 | * in compliance with the License. You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | #pragma once
18 |
19 | #include
20 | #include
21 |
22 | #include
23 | #include
24 |
25 | // bssl::UniquePtr is provided by BoringSSL's openssl/base.h
26 |
27 | namespace adb {
28 | namespace crypto {
29 |
30 | // Generate a X.509 certificate based on the key |pkey|.
31 | bssl::UniquePtr GenerateX509Certificate(EVP_PKEY* pkey);
32 |
33 | // Convert X509* to PEM string format
34 | std::string X509ToPEMString(X509* x509);
35 |
36 | } // namespace crypto
37 | } // namespace adb
38 |
--------------------------------------------------------------------------------
/porting/adb/client/adb_porting.h:
--------------------------------------------------------------------------------
1 | /**
2 | * @brief this file contains the hijack functions for porting adb
3 | */
4 |
5 | #ifndef ADB_PORTING
6 | #define ADB_PORTING 1
7 |
8 | #include
9 | #include
10 |
11 | #define __android_log_print(...) porting_log_print(__VA_ARGS__)
12 | #define __android_log_buf_print(...) porting_log_buf_print(__VA_ARGS__)
13 |
14 | #ifdef __cplusplus
15 | extern "C" {
16 | #endif
17 |
18 | // enum AdbTrace {
19 | // ADB = 0, /* 0x001 */
20 | // SOCKETS,
21 | // PACKETS,
22 | // TRANSPORT,
23 | // RWX, /* 0x010 */
24 | // USB,
25 | // SYNC,
26 | // SYSDEPS,
27 | // JDWP, /* 0x100 */
28 | // SERVICES,
29 | // AUTH,
30 | // FDEVENT,
31 | // SHELL,
32 | // INCREMENTAL,
33 | // }
34 |
35 |
36 | // capture printf output as adb command result
37 | int capture_printf(char **output_buffer, size_t *output_size, const char *format, ...);
38 |
39 | // new method to call adb_commandline for public
40 | int adb_commandline_porting(char **output_buffer, size_t *output_buffer_size, int argc, const char** argv);
41 |
42 | // for init adb trace
43 | void adb_trace_init_porting(char**);
44 |
45 | // for enable adb trace
46 | void adb_trace_enable_porting(int trace_tag);
47 |
48 | #ifdef __cplusplus
49 | }
50 | #endif
51 |
52 | #endif
53 |
--------------------------------------------------------------------------------
/porting/adb/include/adb_public.h:
--------------------------------------------------------------------------------
1 | /**
2 | * adb.h used for export adb functions
3 | */
4 |
5 | #include
6 | #include
7 |
8 | enum AdbTrace {
9 | ADB = 0, /* 0x001 */
10 | SOCKETS,
11 | PACKETS,
12 | TRANSPORT,
13 | RWX, /* 0x010 */
14 | USB,
15 | SYNC,
16 | SYSDEPS,
17 | JDWP, /* 0x100 */
18 | SERVICES,
19 | AUTH,
20 | FDEVENT,
21 | SHELL,
22 | INCREMENTAL,
23 | };
24 |
25 | void adb_trace_init_porting(char**);
26 | void adb_trace_enable_porting(enum AdbTrace trace_tag);
27 |
28 | // execute adb_commoandline
29 | int adb_commandline_porting(char **output_buffer, size_t *output_buffer_size, int argc, const char** argv);
30 |
31 | // enable adb verbose trace
32 | static inline void adb_enable_trace(void) {
33 | setenv("ADB_TRACE", "all", 1);
34 | const char *argv[] = { "adb" };
35 | adb_trace_init_porting((char **)argv);
36 | adb_trace_enable_porting(ADB);
37 | }
38 |
39 | // set home directory
40 | static inline void adb_set_home(const char *home_dir) {
41 | setenv("HOME", home_dir, 1);
42 | }
43 |
44 | // set adb daemon port
45 | static inline void adb_set_server_port(const char *port) {
46 | setenv("ANDROID_ADB_SERVER_PORT", port, 1);
47 | }
48 |
49 | // required function body
50 | void adb_connect_status_updated(const char *serial, const char *status);
51 |
--------------------------------------------------------------------------------
/example/adb-demo/adb-demo/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // adb-demo
4 | //
5 | // Created by Ethan on 2022/6/1.
6 | //
7 |
8 | #import "AppDelegate.h"
9 |
10 | @interface AppDelegate ()
11 |
12 | @end
13 |
14 | @implementation AppDelegate
15 |
16 |
17 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
18 | // Override point for customization after application launch.
19 | return YES;
20 | }
21 |
22 |
23 | #pragma mark - UISceneSession lifecycle
24 |
25 |
26 | - (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options {
27 | // Called when a new scene session is being created.
28 | // Use this method to select a configuration to create the new scene with.
29 | return [[UISceneConfiguration alloc] initWithName:@"Default Configuration" sessionRole:connectingSceneSession.role];
30 | }
31 |
32 |
33 | - (void)application:(UIApplication *)application didDiscardSceneSessions:(NSSet *)sceneSessions {
34 | // Called when the user discards a scene session.
35 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
36 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
37 | }
38 |
39 |
40 | @end
41 |
--------------------------------------------------------------------------------
/porting/adb/client/file_sync_client.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2018 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | #pragma once
18 |
19 | #include
20 | #include
21 |
22 | #include "file_sync_protocol.h"
23 |
24 | bool do_sync_ls(char **output_buffer, size_t *output_size, const char* path);
25 | bool do_sync_push(char **output_buffer, size_t *output_size, const std::vector& srcs, const char* dst, bool sync,
26 | CompressionType compression, bool dry_run, bool quiet);
27 | bool do_sync_pull(char **output_buffer, size_t *output_size, const std::vector& srcs, const char* dst, bool copy_attrs,
28 | CompressionType compression, const char* name = nullptr, bool quiet = false);
29 |
30 | bool do_sync_sync(char **output_buffer, size_t *output_size, const std::string& lpath, const std::string& rpath, bool list_only,
31 | CompressionType compression, bool dry_run, bool quiet);
32 |
--------------------------------------------------------------------------------
/porting/scripts/defines.sh:
--------------------------------------------------------------------------------
1 | # Exit immediately on error, treat unset variables as error, and fail on pipe errors
2 | set -euo pipefail
3 |
4 | # Common Supports:
5 | # - TARGET=lz4/iphoneos/arm64
6 | # - OUTPUT=...
7 |
8 | [[ -z "${TARGET:-}" ]] && echo "** ❌ ERROR: TARGET is REQUIRED." && exit 1;
9 | [[ -z "${OUTPUT:-}" ]] && echo "** ❌ ERROR: OUTPUT is REQUIRED." && exit 1;
10 |
11 | LIB_NAME=$(echo "$TARGET" | cut -d/ -f1);
12 | SDK_NAME=$(echo "$TARGET" | cut -d/ -f2);
13 | ARCH_NAME=$(echo "$TARGET" | cut -d/ -f3);
14 |
15 | # Src root
16 | SOURCE_ROOT=$(cd "$(dirname $0)/../.." && pwd);
17 |
18 | # Porting root
19 | PORTING_ROOT=$SOURCE_ROOT/porting;
20 |
21 | # Prepare output path
22 | FULL_OUTPUT=$(cd $OUTPUT && pwd)/$SDK_NAME/$ARCH_NAME;
23 | [[ ! -d $FULL_OUTPUT ]] && mkdir -p $FULL_OUTPUT;
24 |
25 | # For iphone, change to platform
26 | PLATFORM=$([[ $SDK_NAME == iphoneos ]] && echo "OS64" || echo "SIMULATOR64");
27 | [[ $SDK_NAME == iphonesimulator ]] && [[ $ARCH_NAME == arm64 ]] && PLATFORM=SIMULATORARM64;
28 |
29 | # Setup iphone deploy target
30 | DEPLOYMENT_TARGET=12.0;
31 |
32 | # Setup toolchains
33 | if [[ $SDK_NAME == *iphone* ]]; then
34 | CMAKE_TOOLCHAIN_FILE=$SOURCE_ROOT/ios-cmake/ios.toolchain.cmake;
35 | fi
36 |
37 | # CMake compatibility flag for older CMakeLists.txt files
38 | CMAKE_COMPAT_FLAGS="-DCMAKE_POLICY_VERSION_MINIMUM=3.5"
39 |
40 | # Print summary
41 | echo " - Lib Name: $LIB_NAME";
42 | echo " - SDK Name: $SDK_NAME";
43 | echo " - Arch Name: $ARCH_NAME";
44 | echo " - CMake Toolchain: $CMAKE_TOOLCHAIN_FILE";
45 | echo " - CMake PLATFORM: $PLATFORM";
46 |
--------------------------------------------------------------------------------
/porting/adb/crypto/include/adb/crypto/key.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2019 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except
6 | * in compliance with the License. You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | #pragma once
18 |
19 | #include
20 | #include
21 |
22 | #include
23 | #include
24 |
25 | #include "key_type.pb.h"
26 |
27 | // bssl::UniquePtr is provided by BoringSSL's openssl/base.h
28 |
29 | namespace adb {
30 | namespace crypto {
31 |
32 | // Class that represents a public/private key pair.
33 | class Key {
34 | public:
35 | explicit Key(bssl::UniquePtr&& pkey, adb::proto::KeyType type)
36 | : pkey_(std::move(pkey)), key_type_(type) {}
37 | Key(Key&&) = default;
38 | Key& operator=(Key&&) = default;
39 |
40 | EVP_PKEY* GetEvpPkey() const { return pkey_.get(); }
41 | adb::proto::KeyType GetKeyType() const { return key_type_; }
42 | static std::string ToPEMString(EVP_PKEY* pkey);
43 |
44 | private:
45 | bssl::UniquePtr pkey_;
46 | adb::proto::KeyType key_type_;
47 | }; // Key
48 |
49 | } // namespace crypto
50 | } // namespace adb
51 |
--------------------------------------------------------------------------------
/porting/Makefile:
--------------------------------------------------------------------------------
1 | # Use bash with error checking
2 | SHELL := /bin/bash
3 | .SHELLFLAGS := -e -o pipefail -c
4 |
5 | # Stop on first error
6 | .POSIX:
7 |
8 | .PHONY: iphone lz4 zstd brotli protobuf adb clean
9 |
10 | iphone: lz4 zstd brotli protobuf adb
11 | @echo "✅ All builds completed successfully!"
12 |
13 | ## lz4
14 | lz4: lz4/iphoneos/arm64 lz4/iphonesimulator/arm64 lz4/iphonesimulator/x86_64
15 | lz4/%:
16 | @echo "🔨 Making $@ ..."
17 | TARGET=$@ OUTPUT=../output bash ./scripts/make-lz4.sh
18 |
19 | ## zstd
20 | zstd: zstd/iphoneos/arm64 zstd/iphonesimulator/arm64 zstd/iphonesimulator/x86_64
21 | zstd/%:
22 | @echo "🔨 Making $@ ..."
23 | TARGET=$@ OUTPUT=../output bash ./scripts/make-zstd.sh
24 |
25 | ## brotli
26 | brotli: brotli/iphoneos/arm64 brotli/iphonesimulator/arm64 brotli/iphonesimulator/x86_64
27 | brotli/%:
28 | @echo "🔨 Making $@ ..."
29 | TARGET=$@ OUTPUT=../output bash ./scripts/make-brotli.sh
30 |
31 | ## protobuf
32 | protobuf: protobuf/iphoneos/arm64 protobuf/iphonesimulator/arm64 protobuf/iphonesimulator/x86_64
33 | protobuf/%:
34 | @echo "🔨 Making $@ ..."
35 | TARGET=$@ OUTPUT=../output bash ./scripts/make-protobuf.sh
36 |
37 | ## adb
38 | adb: adb/iphoneos/arm64 adb/iphonesimulator/arm64 adb/iphonesimulator/x86_64
39 | adb/%:
40 | @echo "🔨 Making $@ ..."
41 | TARGET=$@ OUTPUT=../output bash ./scripts/make-adb.sh
42 |
43 | ## Clean all build artifacts
44 | clean:
45 | @echo "🧹 Cleaning build artifacts..."
46 | rm -rf ../output
47 | rm -rf ../android-tools/out
48 | rm -rf ../external/lz4/contrib/cmake_unofficial/out
49 | rm -rf ../external/zstd/build/cmake/out
50 | rm -rf ../external/brotli/out
51 | rm -rf ../external/protobuf/out
52 | @echo "✅ Clean completed!"
53 |
--------------------------------------------------------------------------------
/porting/scripts/make-protobuf.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | . "$(dirname $0)/defines.sh";
4 |
5 | cmake_root=$SOURCE_ROOT/external/protobuf/out;
6 |
7 | # Clean built products
8 | [[ -d "$cmake_root" ]] && rm -rfv "$cmake_root";
9 | mkdir -pv "$cmake_root";
10 |
11 | cd "$cmake_root"
12 |
13 | which protoc || {
14 | echo "** ❌ ERROR: protoc not installed";
15 | exit 1;
16 | }
17 | protoc_version=$(protoc --version | cut -d' ' -f2);
18 | echo "→ Using protobuf v$protoc_version";
19 |
20 | # Switch to version
21 | echo "→ Checking out protobuf v$protoc_version...";
22 | (cd "$SOURCE_ROOT/external/protobuf" && git clean -f && git checkout "v$protoc_version" && git submodule update --init --recursive)
23 |
24 | # Fix absl version
25 | echo "→ Fixing abseil-cpp version...";
26 | (cd "$SOURCE_ROOT/external/protobuf/third_party/abseil-cpp" && git checkout 20240722.0)
27 |
28 | # Copy CMakeLists.txt to source folder
29 | echo "→ Copying CMakeLists.txt...";
30 | cp "$SOURCE_ROOT/porting/cmake/CMakeLists.protobuf.txt" "$SOURCE_ROOT/external/protobuf/CMakeLists.txt"
31 |
32 | echo "→ Running cmake...";
33 | cmake .. -G Xcode -DCMAKE_TOOLCHAIN_FILE="$CMAKE_TOOLCHAIN_FILE" -DPLATFORM="$PLATFORM" \
34 | -DDEPLOYMENT_TARGET="$DEPLOYMENT_TARGET" $CMAKE_COMPAT_FLAGS
35 |
36 | # Hack files
37 | echo "→ Patching source files...";
38 | cp -av "$PORTING_ROOT/protobuf/src/google/protobuf/map_probe_benchmark.cc" \
39 | "$SOURCE_ROOT/external/protobuf/src/google/protobuf/map_probe_benchmark.cc"
40 |
41 | echo "→ Building...";
42 | cmake --build . --target protobuf --config Debug --parallel 8
43 |
44 | echo "→ Copying output...";
45 | find . -name "*.a" -exec cp -av {} "$FULL_OUTPUT" \;
46 |
47 | echo "✅ protobuf build completed successfully!"
48 |
--------------------------------------------------------------------------------
/example/adb-demo/adb-demo/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/porting/adb/client/adb_porting.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include "commandline.h"
5 | #include "adb_porting.h"
6 | #include "adb_trace.h"
7 |
8 | int capture_printf(char **output_buffer, size_t *output_size, const char *format, ...) {
9 | if (output_buffer == nullptr || output_size == nullptr || format == nullptr) {
10 | return -1;
11 | }
12 |
13 | va_list args;
14 | va_start(args, format);
15 |
16 | // Calculate the required buffer size.
17 | va_list args_copy;
18 | va_copy(args_copy, args);
19 | const int required_size = vsnprintf(nullptr, 0, format, args_copy) + 1; // +1 for null terminator
20 | va_end(args_copy);
21 |
22 | // If the buffer is empty or not large enough, expand the buffer.
23 | size_t current_used_size = *output_size; // Used output buffer size
24 | *output_buffer = static_cast(realloc(*output_buffer, current_used_size + required_size));
25 | if (*output_buffer == nullptr) {
26 | perror("realloc");
27 | va_end(args);
28 | return -1;
29 | }
30 |
31 | // Append new content to the end of the buffer.
32 | vsnprintf(*output_buffer + current_used_size, required_size, format, args);
33 | *output_size = current_used_size + required_size - 1; // Update the used buffer size (excluding null terminator)
34 |
35 | va_end(args);
36 |
37 | // return size of this output
38 | return required_size - 1;
39 | }
40 |
41 | int adb_commandline_porting(char **output_buffer, size_t *output_buffer_size, int argc, const char** argv) {
42 | return adb_commandline(output_buffer, output_buffer_size, argc, argv);
43 | }
44 |
45 | void adb_trace_init_porting(char** argv) {
46 | adb_trace_init(argv);
47 | }
48 |
49 | void adb_trace_enable_porting(int trace_tag) {
50 | adb_trace_enable((AdbTrace)trace_tag);
51 | }
52 |
--------------------------------------------------------------------------------
/README.zh-cn.md:
--------------------------------------------------------------------------------
1 | # adb-mobile
2 |
3 | Android Debug Bridge (adb) 移植到移动端的版本,目标是支持 iOS App 和 Android App 通过集成本项目生成的库可以连接开发者模式 (TCP/IP Mode) 的 Android 设备,并执行支持的 ADB 命令。
4 |
5 | 当前仅支持 iOS 平台,Android 版本正在开发中。
6 |
7 | [英文文档](README.md)
8 |
9 | ## 编译库
10 |
11 | 项目已经适配好了编译参数和脚本,仅需通过简单几步即可生成 libadb:
12 |
13 | ```sh
14 | # 1. 检出依赖的 submodules
15 | git submodule update --init --recursive
16 |
17 | # 2. 编译
18 | make
19 | ```
20 |
21 | 生成的 libadb 产物可以在项目目录下的 output 文件夹里找到,iOS 为 libadb.a。
22 |
23 | ## 集成到工程
24 |
25 | iOS 工程:
26 |
27 | ```ini
28 | # 设置头文件路径 - Header Search Paths
29 | HEADER_SEARCH_PATHS = $(SRCROOT)/../../output/include
30 |
31 | # 设置库搜索路径 - Library Search Paths
32 | LIBRARY_SEARCH_PATHS = $(SRCROOT)/../../output
33 |
34 | # 设置连接器参数 - Other Linker Flags
35 | OTHER_LDFLAGS = -ladb -lc++ -lz
36 | ```
37 |
38 | ## 使用说明
39 |
40 | iOS App:
41 |
42 | ```objc
43 | #import "adb_puiblic.h"
44 |
45 | // 开启调试信息输出,有助于排查问题
46 | adb_enable_trace();
47 |
48 | // 设置 ADB 的监听端口,默认为 5037
49 | adb_set_server_port("15037");
50 |
51 | // 设置 ADB 私钥和数据存放目录,一般为 App 的 Documents 目录
52 | NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
53 | const char *document_home = documentPaths.lastObject.UTF8String;
54 | adb_set_home(document_home);
55 |
56 | // 连接 Android 设备
57 | const char *argv[] = { "connect", "x.x.x." };
58 | const char *output = null;
59 | int ret = adb_commandline_porting(2, argv, &output);
60 |
61 | // 执行 ADB 命令
62 | const char *argv[] = { "shell", "ip", "route" };
63 | const char *output = null;
64 | int ret = adb_commandline_porting(2, argv, &output);
65 | ```
66 |
67 | ADB 状态回调:
68 |
69 | ```objc
70 | // 实现 adb_connect_status_updated 回调方法,可以获取 adb 连接状态
71 | void adb_connect_status_updated(const char *serial, const char *status) {
72 | NSLog(@"ADB Status: %s, %s", serial, status);
73 | }
74 | ```
75 |
76 | 也可以通过 example/adb-demo 工程查看具体使用方法。
--------------------------------------------------------------------------------
/example/adb-demo/adb-demo/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "scale" : "2x",
6 | "size" : "20x20"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "scale" : "3x",
11 | "size" : "20x20"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "scale" : "2x",
16 | "size" : "29x29"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "scale" : "3x",
21 | "size" : "29x29"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "scale" : "2x",
26 | "size" : "40x40"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "scale" : "3x",
31 | "size" : "40x40"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "scale" : "2x",
36 | "size" : "60x60"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "scale" : "3x",
41 | "size" : "60x60"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "scale" : "1x",
46 | "size" : "20x20"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "scale" : "2x",
51 | "size" : "20x20"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "scale" : "1x",
56 | "size" : "29x29"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "scale" : "2x",
61 | "size" : "29x29"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "scale" : "1x",
66 | "size" : "40x40"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "scale" : "2x",
71 | "size" : "40x40"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "scale" : "2x",
76 | "size" : "76x76"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "scale" : "2x",
81 | "size" : "83.5x83.5"
82 | },
83 | {
84 | "idiom" : "ios-marketing",
85 | "scale" : "1x",
86 | "size" : "1024x1024"
87 | }
88 | ],
89 | "info" : {
90 | "author" : "xcode",
91 | "version" : 1
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/example/adb-demo/adb-demo/SceneDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // SceneDelegate.m
3 | // adb-demo
4 | //
5 | // Created by Ethan on 2022/6/1.
6 | //
7 |
8 | #import "SceneDelegate.h"
9 |
10 | @interface SceneDelegate ()
11 |
12 | @end
13 |
14 | @implementation SceneDelegate
15 |
16 |
17 | - (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
18 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
19 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
20 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
21 | }
22 |
23 |
24 | - (void)sceneDidDisconnect:(UIScene *)scene {
25 | // Called as the scene is being released by the system.
26 | // This occurs shortly after the scene enters the background, or when its session is discarded.
27 | // Release any resources associated with this scene that can be re-created the next time the scene connects.
28 | // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead).
29 | }
30 |
31 |
32 | - (void)sceneDidBecomeActive:(UIScene *)scene {
33 | // Called when the scene has moved from an inactive state to an active state.
34 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
35 | }
36 |
37 |
38 | - (void)sceneWillResignActive:(UIScene *)scene {
39 | // Called when the scene will move from an active state to an inactive state.
40 | // This may occur due to temporary interruptions (ex. an incoming phone call).
41 | }
42 |
43 |
44 | - (void)sceneWillEnterForeground:(UIScene *)scene {
45 | // Called as the scene transitions from the background to the foreground.
46 | // Use this method to undo the changes made on entering the background.
47 | }
48 |
49 |
50 | - (void)sceneDidEnterBackground:(UIScene *)scene {
51 | // Called as the scene transitions from the foreground to the background.
52 | // Use this method to save data, release shared resources, and store enough scene-specific state information
53 | // to restore the scene back to its current state.
54 | }
55 |
56 |
57 | @end
58 |
--------------------------------------------------------------------------------
/porting/adb/client/transport_usb.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2007 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | #define TRACE_TAG TRANSPORT
18 |
19 | #include "sysdeps.h"
20 |
21 | #include "client/usb.h"
22 |
23 | #include
24 |
25 | #include "sysdeps.h"
26 | #include "transport.h"
27 |
28 | #include
29 | #include
30 | #include
31 |
32 | #include "adb.h"
33 |
34 | #if defined(__APPLE__)
35 | #define CHECK_PACKET_OVERFLOW 0
36 | #else
37 | #define CHECK_PACKET_OVERFLOW 1
38 | #endif
39 |
40 | // Call usb_read using a buffer having a multiple of usb_get_max_packet_size() bytes
41 | // to avoid overflow. See http://libusb.sourceforge.net/api-1.0/packetoverflow.html.
42 | static int UsbReadMessage(usb_handle* h, amessage* msg) {
43 | D("UsbReadMessage");
44 | return 0;
45 | }
46 |
47 | // Call usb_read using a buffer having a multiple of usb_get_max_packet_size() bytes
48 | // to avoid overflow. See http://libusb.sourceforge.net/api-1.0/packetoverflow.html.
49 | static int UsbReadPayload(usb_handle* h, apacket* p) {
50 | return 0;
51 | }
52 |
53 | static int remote_read(apacket* p, usb_handle* usb) {
54 | return 0;
55 | }
56 |
57 | UsbConnection::~UsbConnection() {
58 | }
59 |
60 | bool UsbConnection::Read(apacket* packet) {
61 | return false;
62 | }
63 |
64 | bool UsbConnection::Write(apacket* packet) {
65 | return false;
66 | }
67 |
68 | bool UsbConnection::DoTlsHandshake(RSA* key, std::string* auth_key) {
69 | // TODO: support TLS for usb connections
70 | LOG(FATAL) << "Not supported yet.";
71 | return false;
72 | }
73 |
74 | void UsbConnection::Reset() {
75 | }
76 |
77 | void UsbConnection::Close() {
78 | }
79 |
80 | void init_usb_transport(atransport* t, usb_handle* h) {
81 | D("transport: usb");
82 | }
83 |
84 | bool is_adb_interface(int usb_class, int usb_subclass, int usb_protocol) {
85 | return false;
86 | }
87 |
88 | bool is_libusb_enabled() {
89 | return false;
90 | }
91 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # adb-mobile
2 |
3 | Android Debug Bridge (adb) ported version for mobile apps, the goal of this project is supporting both iOS App and Android App to connect to Android devices in developer mode (TCP/IP Mode) and execute supported ADB commands by integrating the libraries generated by this project.
4 |
5 | Currently only iOS platform is supported, Android version is under development.
6 |
7 | Update Log:
8 |
9 | * 2024-11: Upgrade porting project to ADB 35.0.2, and some API changes.
10 |
11 | [中文文档](README.zh-cn.md)
12 |
13 | ## Build Library
14 |
15 | The project has already finished the build scripts to generate libadb in a few simple steps:
16 |
17 | ```sh
18 | # 1. checkout all the submodules
19 | git submodule update --init --recursive
20 |
21 | # 2. build
22 | make
23 | ```
24 |
25 | The generated libadb product can be found in the output folder of the project directory, for iOS is "libadb.a" that you can located at output folder.
26 |
27 | ## Integrate
28 |
29 | iOS Project:
30 |
31 | ```ini
32 | # Build Settings - Header Search Paths
33 | HEADER_SEARCH_PATHS = $(SRCROOT)/../../output/include
34 |
35 | # Build Settings - Library Search Paths
36 | LIBRARY_SEARCH_PATHS = $(SRCROOT)/../../output
37 |
38 | # Build Settings - Other Linker Flags
39 | OTHER_LDFLAGS = -ladb -lc++ -lz
40 | ```
41 |
42 | ## API Usage
43 |
44 | iOS App:
45 |
46 | ```objc
47 | #import "adb_puiblic.h"
48 |
49 | // Enable trace debug message
50 | adb_enable_trace();
51 |
52 | // Setup the ADB listening port, the default is 5037
53 | adb_set_server_port("15037");
54 |
55 | // Setup the ADB private key and data directory, which is usually the Documents directory of the App
56 | NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
57 | const char *document_home = documentPaths.lastObject.UTF8String;
58 | adb_set_home(document_home);
59 |
60 | // Connecting Android devices
61 | const char *argv[] = { "connect", "x.x.x." };
62 |
63 | // Initialize the output buffer
64 | char *output = NULL;
65 | size_t output_size = 0;
66 | int ret = adb_commandline_porting(&output, &output_size, 2, argv);
67 |
68 | // Execute the ADB commands
69 | const char *argv[] = { "shell", "ip", "route" };
70 | char *output = NULL;
71 | size_t output_size = 0;
72 | int ret = adb_commandline_porting((&output, &output_size, 2, argv);
73 | ```
74 |
75 | ADB Status Callback:
76 |
77 | ```objc
78 | // By define the adb_connect_status_updated callback method to get the adb connection status
79 | void adb_connect_status_updated(const char *serial, const char *status) {
80 | NSLog(@"ADB Status: %s, %s", serial, status);
81 | }
82 | ```
83 |
84 | You can also see how to use this library in the example/adb-demo project.
85 |
--------------------------------------------------------------------------------
/porting/protobuf.rb:
--------------------------------------------------------------------------------
1 | class Protobuf < Formula
2 | desc "Protocol buffers (Google's data interchange format)"
3 | homepage "https://protobuf.dev/"
4 | url "https://github.com/protocolbuffers/protobuf/releases/download/v28.3/protobuf-28.3.tar.gz"
5 | sha256 "7c3ebd7aaedd86fa5dc479a0fda803f602caaf78d8aff7ce83b89e1b8ae7442a"
6 | license "BSD-3-Clause"
7 |
8 | livecheck do
9 | url :stable
10 | strategy :github_latest
11 | end
12 |
13 | bottle do
14 | sha256 cellar: :any, arm64_sequoia: "cec9ebadfa0ff65482e3e195660a13ca43844792ed98822ad10b2bca4ef8e45c"
15 | sha256 cellar: :any, arm64_sonoma: "537ab66678b04aa2e770bc65aa710d63f37a1b5a1c65717c2e8954cdbb94d883"
16 | sha256 cellar: :any, arm64_ventura: "4a0a0e6db20bd8444491b35c34d6c51e42b493bcb3a3e6b309bdbd06bd85eab9"
17 | sha256 cellar: :any, sonoma: "446d7adcff7604c570a50f2aca5484612a32481cbe677e1bccdbe62989062de4"
18 | sha256 cellar: :any, ventura: "e52757d69a1f986314de2dd508eae336a544fb96838038fb76d0915b017bcc32"
19 | sha256 cellar: :any_skip_relocation, x86_64_linux: "b62500bd2fcf54e820720441d969bca0204ce95bab6e16dcb247bb28398356bd"
20 | end
21 |
22 | depends_on "cmake" => :build
23 | depends_on "abseil"
24 | uses_from_macos "zlib"
25 |
26 | on_macos do
27 | # We currently only run tests on macOS.
28 | # Running them on Linux requires rebuilding googletest with `-fPIC`.
29 | depends_on "googletest" => :build
30 | end
31 |
32 | patch do
33 | url "https://github.com/protocolbuffers/protobuf/commit/e490bff517916495ed3a900aa85791be01f674f5.patch?full_index=1"
34 | sha256 "7e89d0c379d89b24cb6fe795cd9d68e72f0b83fcc95dd91af721d670ad466022"
35 | end
36 |
37 | def install
38 | # Keep `CMAKE_CXX_STANDARD` in sync with the same variable in `abseil.rb`.
39 | abseil_cxx_standard = 17
40 | cmake_args = %W[
41 | -DBUILD_SHARED_LIBS=ON
42 | -Dprotobuf_BUILD_LIBPROTOC=ON
43 | -Dprotobuf_BUILD_SHARED_LIBS=ON
44 | -Dprotobuf_INSTALL_EXAMPLES=ON
45 | -Dprotobuf_BUILD_TESTS=#{OS.mac? ? "ON" : "OFF"}
46 | -Dprotobuf_USE_EXTERNAL_GTEST=ON
47 | -Dprotobuf_ABSL_PROVIDER=package
48 | -Dprotobuf_JSONCPP_PROVIDER=package
49 | ]
50 | cmake_args << "-DCMAKE_CXX_STANDARD=#{abseil_cxx_standard}"
51 |
52 | system "cmake", "-S", ".", "-B", "build", *cmake_args, *std_cmake_args
53 | system "cmake", "--build", "build"
54 | system "ctest", "--test-dir", "build", "--verbose" if OS.mac?
55 | system "cmake", "--install", "build"
56 |
57 | (share/"vim/vimfiles/syntax").install "editors/proto.vim"
58 | elisp.install "editors/protobuf-mode.el"
59 | end
60 |
61 | test do
62 | testdata = <<~EOS
63 | syntax = "proto3";
64 | package test;
65 | message TestCase {
66 | string name = 4;
67 | }
68 | message Test {
69 | repeated TestCase case = 1;
70 | }
71 | EOS
72 | (testpath/"test.proto").write testdata
73 | system bin/"protoc", "test.proto", "--cpp_out=."
74 | end
75 | end
76 |
--------------------------------------------------------------------------------
/porting/scripts/make-adb.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | . "$(dirname $0)/defines.sh";
4 |
5 | cmake_root=$SOURCE_ROOT/android-tools/out;
6 |
7 | # Init update android tools submodules FIRST (before creating output dir)
8 | # Force checkout to discard local changes
9 | echo "→ Reset android tools and submodules";
10 | (cd "$SOURCE_ROOT/android-tools" && git checkout -f . && git clean -fd -e out)
11 |
12 | # Force reset all submodules
13 | for dep_repo in "$SOURCE_ROOT"/android-tools/vendor/*; do
14 | [[ -d "$dep_repo" ]] || continue;
15 | echo "→ Force reset $dep_repo";
16 | (cd "$dep_repo" && git reset --hard HEAD && git clean -fd && git am --abort 2>/dev/null || true)
17 | done
18 |
19 | # Now update submodules
20 | echo "→ Updating submodules...";
21 | (cd "$SOURCE_ROOT/android-tools" && git submodule update --init --recursive --force)
22 |
23 | # Clean and create build directory AFTER git operations
24 | [[ -d "$cmake_root" ]] && rm -rfv "$cmake_root";
25 | mkdir -pv "$cmake_root";
26 |
27 | cd "$cmake_root"
28 |
29 | echo "→ Running cmake...";
30 | # Point OpenSSL to BoringSSL and exclude Homebrew's OpenSSL from include paths
31 | BORINGSSL_DIR="$SOURCE_ROOT/android-tools/vendor/boringssl"
32 |
33 | cmake -DCMAKE_OSX_SYSROOT="$SDK_NAME" -DCMAKE_OSX_ARCHITECTURES="$ARCH_NAME" \
34 | -DCMAKE_OSX_DEPLOYMENT_TARGET="$DEPLOYMENT_TARGET" -DCMAKE_BUILD_TYPE=Debug \
35 | -DOPENSSL_ROOT_DIR="$BORINGSSL_DIR" \
36 | -DOPENSSL_INCLUDE_DIR="$BORINGSSL_DIR/include" \
37 | -DCMAKE_DISABLE_FIND_PACKAGE_OpenSSL=ON \
38 | -DANDROID_TOOLS_USE_BUNDLED_FMT=ON \
39 | -DANDROID_TOOLS_USE_BUNDLED_LIBUSB=ON \
40 | $CMAKE_COMPAT_FLAGS ..
41 |
42 | # Patch generated Makefiles to prioritize BoringSSL includes
43 | # Prepend BoringSSL include to CXX_INCLUDES so it's searched first for openssl headers
44 | echo "→ Patching include paths to prioritize BoringSSL..."
45 | find "$cmake_root" -name "flags.make" -exec sed -i '' \
46 | "s|^CXX_INCLUDES = |CXX_INCLUDES = -I$BORINGSSL_DIR/include |g" {} \;
47 |
48 | # Hack to fix build files, these actions must execute after cmake, otherwise may cause file conflict
49 | # copy sys/user.h for libbase
50 | echo "→ Copying porting files...";
51 | cp -av "$PORTING_ROOT/adb/include/sys" "$SOURCE_ROOT/android-tools/vendor/libbase/include/"
52 | ln -sfv "$SOURCE_ROOT/android-tools/vendor/core/diagnose_usb/include/diagnose_usb.h" \
53 | "$SOURCE_ROOT/android-tools/vendor/core/include"
54 |
55 | # Hack source codes
56 | cp -av "$PORTING_ROOT/adb/"*.cpp "$SOURCE_ROOT/android-tools/vendor/adb/"
57 | cp -av "$PORTING_ROOT/adb/client/"* "$SOURCE_ROOT/android-tools/vendor/adb/client/"
58 | cp -av "$PORTING_ROOT/adb/fdevent/"* "$SOURCE_ROOT/android-tools/vendor/adb/fdevent/"
59 | cp -av "$PORTING_ROOT/adb/crypto/include/adb/crypto/"* "$SOURCE_ROOT/android-tools/vendor/adb/crypto/include/adb/crypto/"
60 |
61 | # Remove abort
62 | echo "→ Patching libbase logging.cpp...";
63 | grep -v "abort();" "$SOURCE_ROOT/android-tools/vendor/libbase/logging.cpp" > "$SOURCE_ROOT/android-tools/vendor/libbase/logging.cpp.tmp"
64 | mv -fv "$SOURCE_ROOT/android-tools/vendor/libbase/logging.cpp.tmp" \
65 | "$SOURCE_ROOT/android-tools/vendor/libbase/logging.cpp"
66 |
67 | echo "→ Building...";
68 | make -j16 libadb crypto decrepit libcutils libzip libdiagnoseusb libbase \
69 | libadb_crypto_defaults libcrypto libadb_tls_connection_defaults
70 |
71 | echo "→ Copying output...";
72 | find . -name "*.a" -exec cp -av {} "$FULL_OUTPUT" \;
73 |
74 | echo "✅ Build completed successfully!"
75 |
--------------------------------------------------------------------------------
/porting/cmake/CMakeLists.protobuf.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.4.1)
2 | set(CMAKE_CXX_STANDARD 17)
3 | project(protobuf C CXX)
4 | set(PROJECT_NAME protobuf)
5 |
6 | message(STATUS "CMake Path: ${CMAKE_CURRENT_SOURCE_DIR}")
7 | message(STATUS "Platform: ${PLATFORM}")
8 |
9 | include_directories(
10 | ../../external/protobuf/src
11 | ../../external/protobuf/third_party/abseil-cpp
12 | ../../external/protobuf/third_party/utf8_range
13 | ../../external/protobuf/third_party/googletest/googletest/include
14 | ../../external/protobuf/third_party/googletest/googlemock/include
15 | )
16 |
17 | file(GLOB protobuf_srcs
18 | ../../external/protobuf/src/google/protobuf/*.cc
19 | ../../external/protobuf/src/google/protobuf/stubs/*.cc
20 | ../../external/protobuf/src/google/protobuf/io/*.cc
21 | ../../external/protobuf/src/google/protobuf/util/*cc
22 | ../../external/protobuf/src/google/protobuf/util/internal/*.cc
23 | ../../external/protobuf/third_party/abseil-cpp/absl/strings/*.cc
24 | ../../external/protobuf/third_party/abseil-cpp/absl/strings/internal/*.cc
25 | ../../external/protobuf/third_party/abseil-cpp/absl/strings/internal/str_format/*.cc
26 | ../../external/protobuf/third_party/abseil-cpp/absl/types/*.cc
27 | ../../external/protobuf/third_party/abseil-cpp/absl/flags/*.cc
28 | ../../external/protobuf/third_party/abseil-cpp/absl/synchronization/*.cc
29 | ../../external/protobuf/third_party/abseil-cpp/absl/synchronization/internal/*.cc
30 | ../../external/protobuf/third_party/abseil-cpp/absl/hash/*.cc
31 | ../../external/protobuf/third_party/abseil-cpp/absl/hash/internal/*.cc
32 | ../../external/protobuf/third_party/abseil-cpp/absl/debugging/*.cc
33 | ../../external/protobuf/third_party/abseil-cpp/absl/debugging/internal/*.cc
34 | ../../external/protobuf/third_party/abseil-cpp/absl/crc/*.cc
35 | ../../external/protobuf/third_party/abseil-cpp/absl/crc/internal/*.cc
36 | ../../external/protobuf/third_party/abseil-cpp/absl/status/*.cc
37 | ../../external/protobuf/third_party/abseil-cpp/absl/status/internal/*.cc
38 | ../../external/protobuf/third_party/abseil-cpp/absl/time/*.cc
39 | ../../external/protobuf/third_party/abseil-cpp/absl/time/internal/*.cc
40 | ../../external/protobuf/third_party/abseil-cpp/absl/time/internal/cctz/src/*.cc
41 | ../../external/protobuf/third_party/abseil-cpp/absl/container/*.cc
42 | ../../external/protobuf/third_party/abseil-cpp/absl/container/internal/*.cc
43 | ../../external/protobuf/third_party/abseil-cpp/absl/numeric/*.cc
44 | ../../external/protobuf/third_party/abseil-cpp/absl/profiling/internal/*.cc
45 | ../../external/protobuf/third_party/abseil-cpp/absl/log/*.cc
46 | ../../external/protobuf/third_party/abseil-cpp/absl/log/internal/*.cc
47 | ../../external/protobuf/third_party/abseil-cpp/absl/random/*.cc
48 | ../../external/protobuf/third_party/abseil-cpp/absl/random/internal/*.cc
49 | ../../external/protobuf/third_party/abseil-cpp/absl/functional/*.cc
50 | ../../external/protobuf/third_party/abseil-cpp/absl/base/*.cc
51 | ../../external/protobuf/third_party/abseil-cpp/absl/base/internal/*.cc
52 | ../../external/protobuf/third_party/abseil-cpp/absl/debugging/*.cc
53 | ../../external/protobuf/third_party/abseil-cpp/absl/debugging/internal/*.cc
54 | ../../external/protobuf/third_party/utf8_range/*.cc
55 | ../../external/protobuf/third_party/utf8_range/utf8_range.c
56 | )
57 | list(FILTER protobuf_srcs EXCLUDE REGEX "benchmarks.cc|.*_test\\.*|.*_unittest\\.*|.*_benchmark\\.*|.*test_util.*|.*_tester.*")
58 |
59 | foreach(src IN LISTS protobuf_srcs)
60 | message(STATUS "- ${src}")
61 | endforeach()
62 |
63 | add_library(protobuf STATIC
64 | ${protobuf_srcs}
65 | )
66 |
--------------------------------------------------------------------------------
/example/adb-demo/adb-demo/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // adb-demo
4 | //
5 | // Created by Ethan on 2022/6/1.
6 | //
7 |
8 | #import "ViewController.h"
9 | #import "adb_public.h"
10 |
11 | void adb_connect_status_updated(const char *serial, const char *status) {
12 | NSLog(@"ADB Status: %s, %s", serial, status);
13 | }
14 |
15 | @interface ViewController ()
16 | @property (weak, nonatomic) IBOutlet UITextField *adbHost;
17 | @property (weak, nonatomic) IBOutlet UIButton *adbConnect;
18 | @property (weak, nonatomic) IBOutlet UITextField *adbCommand;
19 | @property (weak, nonatomic) IBOutlet UIButton *adbExecute;
20 |
21 | @end
22 |
23 | @implementation ViewController
24 |
25 | - (void)viewDidLoad {
26 | [super viewDidLoad];
27 |
28 | adb_enable_trace();
29 | adb_set_server_port("15037");
30 |
31 | NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
32 | const char *document_home = documentPaths.lastObject.UTF8String;
33 | adb_set_home(document_home);
34 |
35 | // Load defaults
36 | NSString *host = [NSUserDefaults.standardUserDefaults objectForKey:@"adbHost"];
37 | if (host.length > 0) {
38 | self.adbHost.text = host;
39 | }
40 | NSString *command = [NSUserDefaults.standardUserDefaults objectForKey:@"adbCommand"];
41 | if (command.length > 0) {
42 | self.adbCommand.text = command;
43 | }
44 |
45 | // Disable auto-correction
46 | self.adbHost.autocorrectionType = UITextAutocorrectionTypeNo;
47 | self.adbCommand.autocorrectionType = UITextAutocorrectionTypeNo;
48 | }
49 |
50 | -(NSString *)adbExecute:(NSArray *)commands success:(BOOL*)success {
51 | const char *argv[commands.count];
52 | for (NSInteger i = 0; i < commands.count; i++) {
53 | argv[i] = commands[i].UTF8String;
54 | }
55 |
56 | char *output = NULL;
57 | size_t output_size = 0;
58 | int ret = adb_commandline_porting(&output, &output_size, (int)commands.count, argv);
59 | *success = ret == 0;
60 |
61 | if (output_size > 0) {
62 | return [NSString stringWithUTF8String:output];
63 | }
64 |
65 | return @"";
66 | }
67 |
68 | -(void)showAlert:(NSString *)message {
69 | UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Message" message:message preferredStyle:(UIAlertControllerStyleAlert)];
70 | [alertController addAction:[UIAlertAction actionWithTitle:@"OK" style:(UIAlertActionStyleCancel) handler:nil]];
71 | [self presentViewController:alertController animated:YES completion:nil];
72 | }
73 |
74 | - (IBAction)connect:(id)sender {
75 | if (self.adbHost.text.length == 0) {
76 | [self showAlert:@"Host is empty!"];
77 | return;
78 | }
79 |
80 | [self.adbHost endEditing:YES];
81 |
82 | // Save text value into user defaults
83 | [NSUserDefaults.standardUserDefaults setObject:self.adbHost.text forKey:@"adbHost"];
84 | [NSUserDefaults.standardUserDefaults synchronize];
85 |
86 | NSDate *timeStart = [NSDate date];
87 |
88 | BOOL success = NO;
89 | NSString *message = [self adbExecute:@[ @"connect", self.adbHost.text ] success:&success];
90 | NSLog(@"Time cost: %0.4fs", -[timeStart timeIntervalSinceNow]);
91 | [self showAlert:[NSString stringWithFormat:@"Success: %@\nMessage: %@", success?@"YES":@"NO", message]];
92 | }
93 |
94 | - (IBAction)execute:(id)sender {
95 | if (self.adbCommand.text.length == 0) {
96 | [self showAlert:@"Command is empty!"];
97 | return;
98 | }
99 |
100 | [self.adbCommand endEditing:YES];
101 |
102 | // Save text value into user defaults
103 | [[NSUserDefaults standardUserDefaults] setObject:self.adbCommand.text forKey:@"adbCommand"];
104 | [[NSUserDefaults standardUserDefaults] synchronize];
105 |
106 | BOOL success = NO;
107 | NSString *message = [self adbExecute:[self.adbCommand.text componentsSeparatedByString:@" "] success:&success];
108 | [self showAlert:[NSString stringWithFormat:@"Success: %@\nMessage: %@", success?@"YES":@"NO", message]];
109 | }
110 |
111 | @end
112 |
--------------------------------------------------------------------------------
/porting/adb/client/commandline.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | #ifndef COMMANDLINE_H
18 | #define COMMANDLINE_H
19 |
20 | #include
21 |
22 | #include
23 |
24 | #include "adb.h"
25 | #include "adb_client.h"
26 | #include "adb_unique_fd.h"
27 | #include "transport.h"
28 |
29 | // Callback used to handle the standard streams (stdout and stderr) sent by the
30 | // device's upon receiving a command.
31 |
32 | //
33 | class StandardStreamsCallbackInterface {
34 | public:
35 | StandardStreamsCallbackInterface() {
36 | }
37 | // Handles the stdout output from devices supporting the Shell protocol.
38 | // Returns true on success and false on failure.
39 | virtual bool OnStdout(const char* buffer, size_t length) = 0;
40 |
41 | // Handles the stderr output from devices supporting the Shell protocol.
42 | // Returns true on success and false on failure.
43 | virtual bool OnStderr(const char* buffer, size_t length) = 0;
44 |
45 | // Indicates the communication is finished and returns the appropriate error
46 | // code.
47 | //
48 | // |status| has the status code returning by the underlying communication
49 | // channels
50 | virtual int Done(int status) = 0;
51 |
52 | protected:
53 | static bool OnStream(std::string* string, FILE* stream, const char* buffer, size_t length,
54 | bool returnErrors) {
55 | if (string != nullptr) {
56 | string->append(buffer, length);
57 | return true;
58 | } else {
59 | bool okay = (fwrite(buffer, 1, length, stream) == length);
60 | fflush(stream);
61 | return returnErrors ? okay : true;
62 | }
63 | }
64 |
65 | private:
66 | DISALLOW_COPY_AND_ASSIGN(StandardStreamsCallbackInterface);
67 | };
68 |
69 | // Default implementation that redirects the streams to the equivalent host
70 | // stream or to a string passed to the constructor.
71 | class DefaultStandardStreamsCallback : public StandardStreamsCallbackInterface {
72 | public:
73 | // If |stdout_str| is non-null, OnStdout will append to it.
74 | // If |stderr_str| is non-null, OnStderr will append to it.
75 | DefaultStandardStreamsCallback(std::string* stdout_str, std::string* stderr_str)
76 | : stdout_str_(stdout_str), stderr_str_(stderr_str), returnErrors_(false) {
77 | }
78 | DefaultStandardStreamsCallback(std::string* stdout_str, std::string* stderr_str,
79 | bool returnErrors)
80 | : stdout_str_(stdout_str), stderr_str_(stderr_str), returnErrors_(returnErrors) {
81 | }
82 |
83 | bool OnStdout(const char* buffer, size_t length) {
84 | return OnStream(stdout_str_, stdout, buffer, length, returnErrors_);
85 | }
86 |
87 | bool OnStderr(const char* buffer, size_t length) {
88 | return OnStream(stderr_str_, stderr, buffer, length, returnErrors_);
89 | }
90 |
91 | int Done(int status) {
92 | return status;
93 | }
94 |
95 | void ReturnErrors(bool returnErrors) {
96 | returnErrors_ = returnErrors;
97 | }
98 |
99 | private:
100 | std::string* stdout_str_;
101 | std::string* stderr_str_;
102 | bool returnErrors_;
103 |
104 | DISALLOW_COPY_AND_ASSIGN(DefaultStandardStreamsCallback);
105 | };
106 |
107 | class SilentStandardStreamsCallbackInterface : public StandardStreamsCallbackInterface {
108 | public:
109 | SilentStandardStreamsCallbackInterface() = default;
110 | bool OnStdout(const char*, size_t) override final { return true; }
111 | bool OnStderr(const char*, size_t) override final { return true; }
112 | int Done(int status) override final { return status; }
113 | };
114 |
115 | // Singleton.
116 | extern DefaultStandardStreamsCallback DEFAULT_STANDARD_STREAMS_CALLBACK;
117 |
118 | int adb_commandline(char** out_buf, size_t* out_buf_size, int argc, const char** argv);
119 |
120 | // Helper retrieval function.
121 | const std::optional& adb_get_feature_set_or_die(char** out_buf, size_t* out_buf_size);
122 |
123 | bool copy_to_file(int inFd, int outFd);
124 |
125 | // Connects to the device "shell" service with |command| and prints the
126 | // resulting output.
127 | // if |callback| is non-null, stdout/stderr output will be handled by it.
128 | int send_shell_command(
129 | const std::string& command, bool disable_shell_protocol = false,
130 | StandardStreamsCallbackInterface* callback = &DEFAULT_STANDARD_STREAMS_CALLBACK);
131 |
132 | // Reads from |fd| and prints received data. If |use_shell_protocol| is true
133 | // this expects that incoming data will use the shell protocol, in which case
134 | // stdout/stderr are routed independently and the remote exit code will be
135 | // returned.
136 | // if |callback| is non-null, stdout/stderr output will be handled by it.
137 | int read_and_dump(char **output_buffer, size_t *output_size, borrowed_fd fd, bool use_shell_protocol = false,
138 | StandardStreamsCallbackInterface* callback = &DEFAULT_STANDARD_STREAMS_CALLBACK);
139 |
140 | // Connects to the device "abb" service with |command| and returns the fd.
141 | template
142 | unique_fd send_abb_exec_command(const ContainerT& command_args, std::string* error) {
143 | std::string service_string = "abb_exec:" + android::base::Join(command_args, ABB_ARG_DELIMETER);
144 |
145 | unique_fd fd(adb_connect(service_string, error));
146 | if (fd < 0) {
147 | fprintf(stderr, "adb: failed to run abb_exec. Error: %s\n", error->c_str());
148 | return unique_fd{};
149 | }
150 | return fd;
151 | }
152 |
153 | #endif // COMMANDLINE_H
154 |
--------------------------------------------------------------------------------
/porting/adb/fdevent/fdevent.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2006 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | #ifndef __FDEVENT_H
18 | #define __FDEVENT_H
19 |
20 | #include
21 | #include
22 |
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include