├── .gitignore ├── .idea ├── .name ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── encodings.xml ├── gradle.xml ├── misc.xml ├── modules.xml ├── scopes │ └── scope_settings.xml └── vcs.xml ├── NativeService.iml ├── README.md ├── app ├── .gitignore ├── app.iml ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── aidl │ └── com │ │ └── test │ │ └── nativeservice │ │ └── IMyLight.aidl │ ├── java │ └── com │ │ └── test │ │ └── nativeservice │ │ └── MainActivity.java │ ├── jni │ ├── Android.mk │ ├── Application.mk │ ├── IMyLight.h │ ├── MyLightService.h │ ├── include │ ├── lib │ └── service │ │ └── mainService.cpp │ └── res │ ├── drawable-hdpi │ └── ic_launcher.png │ ├── drawable-mdpi │ └── ic_launcher.png │ ├── drawable-xhdpi │ └── ic_launcher.png │ ├── drawable-xxhdpi │ └── ic_launcher.png │ ├── layout │ └── activity_main.xml │ ├── menu │ └── menu_main.xml │ ├── values-w820dp │ └── dimens.xml │ └── values │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | /local.properties 3 | /.idea/workspace.xml 4 | /.idea/libraries 5 | .DS_Store 6 | /build 7 | -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | NativeService -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Android 15 | 16 | 17 | Android Lint 18 | 19 | 20 | Java language level migration aids 21 | 22 | 23 | 24 | 25 | Abstraction issues 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 1.8 39 | 40 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.idea/scopes/scope_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /NativeService.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #Native Service Demo 2 | Native Service that use libhardware directly, this demo require `system` or higher permission.
3 | For how to use some hidden APIs that don't exist in Android SDK like `ServiceManager` class.
4 | You can reference my blogspot's post:
5 | http://mshockwave.blogspot.tw/2015/01/how-to-use-android-internal-apis.html -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | src/androidTest 3 | src/main/obj 4 | src/main/libs -------------------------------------------------------------------------------- /app/app.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 21 5 | buildToolsVersion "21.1.2" 6 | 7 | defaultConfig { 8 | applicationId "com.test.nativeservice" 9 | minSdkVersion 18 10 | targetSdkVersion 21 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | 21 | sourceSets.main.jni.srcDirs = [] 22 | } 23 | 24 | dependencies { 25 | compile fileTree(dir: 'libs', include: ['*.jar']) 26 | compile 'com.android.support:appcompat-v7:21.0.3' 27 | } 28 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/mac/android-sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 10 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/aidl/com/test/nativeservice/IMyLight.aidl: -------------------------------------------------------------------------------- 1 | // IMyLight.aidl 2 | package com.test.nativeservice; 3 | 4 | // Declare any non-default types here with import statements 5 | 6 | interface IMyLight { 7 | 8 | void flashOn(int onMs, int offMs, int color); 9 | void turnOff(); 10 | } 11 | -------------------------------------------------------------------------------- /app/src/main/java/com/test/nativeservice/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.test.nativeservice; 2 | 3 | import android.graphics.Color; 4 | import android.os.Handler; 5 | import android.os.IBinder; 6 | import android.os.RemoteException; 7 | import android.os.ServiceManager; 8 | import android.support.v7.app.ActionBarActivity; 9 | import android.os.Bundle; 10 | import android.util.Log; 11 | import android.view.View; 12 | 13 | 14 | public class MainActivity extends ActionBarActivity { 15 | private static final String TAG = "MainActivity"; 16 | 17 | private IMyLight mMyLight = null; 18 | 19 | @Override 20 | protected void onCreate(Bundle savedInstanceState) { 21 | super.onCreate(savedInstanceState); 22 | setContentView(R.layout.activity_main); 23 | 24 | initBinder(); 25 | if(mMyLight == null){ 26 | Log.e(TAG, "Get MyLight interface failed"); 27 | }else{ 28 | Log.i(TAG, "Successfully get MyLight interface"); 29 | } 30 | } 31 | 32 | private void initBinder(){ 33 | IBinder serviceBinder = ServiceManager.getService("my_light"); 34 | if(serviceBinder == null){ 35 | Log.e(TAG, "Get service binder failed"); 36 | }else{ 37 | Log.i(TAG, "Get service binder"); 38 | mMyLight = IMyLight.Stub.asInterface(serviceBinder); 39 | } 40 | } 41 | 42 | public void startBlinkingOnClick(View v){ 43 | if(mMyLight == null) return; 44 | try { 45 | mMyLight.flashOn(50, 500, Color.GREEN); 46 | } catch (RemoteException e) { 47 | Log.e(TAG, "Blinking failed"); 48 | e.printStackTrace(); 49 | } 50 | } 51 | public void stopLightingOnClick(View v){ 52 | if(mMyLight == null) return; 53 | try { 54 | mMyLight.turnOff(); 55 | } catch (RemoteException e) { 56 | Log.e(TAG, "Turning off failed"); 57 | e.printStackTrace(); 58 | } 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /app/src/main/jni/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH := $(call my-dir) 2 | 3 | include $(CLEAR_VARS) 4 | 5 | LOCAL_C_INCLUDES += $(LOCAL_PATH)/include 6 | LOCAL_C_INCLUDES += $(LOCAL_PATH) 7 | LOCAL_LDLIBS += -L$(LOCAL_PATH)/lib 8 | LOCAL_LDLIBS += -lbinder -lcutils -lutils -llog -lhardware 9 | 10 | LOCAL_SRC_FILES += service/mainService.cpp 11 | LOCAL_MODULE := myLightService 12 | 13 | #Build native service 14 | include $(BUILD_EXECUTABLE) 15 | 16 | -------------------------------------------------------------------------------- /app/src/main/jni/Application.mk: -------------------------------------------------------------------------------- 1 | APP_PLATFORM := android-21 2 | 3 | APP_CPPFLAGS += -fno-rtti -Wno-psabi -Wno-switch 4 | -------------------------------------------------------------------------------- /app/src/main/jni/IMyLight.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace android; 6 | 7 | class IMyLight : public IInterface { 8 | 9 | public: 10 | DECLARE_META_INTERFACE(MyLight); 11 | 12 | virtual void flashOn(int32_t onMs, int32_t offMs, int32_t color) = 0; 13 | virtual void turnOff(void) = 0; 14 | }; 15 | 16 | #define TRANSACTION_flashOn (IBinder::FIRST_CALL_TRANSACTION + 0) 17 | #define TRANSACTION_turnOff (IBinder::FIRST_CALL_TRANSACTION + 1) -------------------------------------------------------------------------------- /app/src/main/jni/MyLightService.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | 7 | #undef LOG_TAG 8 | #define LOG_TAG "MyLight" 9 | 10 | using namespace android; 11 | 12 | class BpMyLight : public BpInterface { 13 | 14 | public: 15 | BpMyLight(const sp& remote) : BpInterface(remote) { } 16 | 17 | //We don't have to implement it 18 | //Since we want to call from AIDL 19 | virtual void flashOn(int32_t onMs, int32_t offMs, int32_t color) { } 20 | virtual void turnOff(void) { } 21 | }; 22 | IMPLEMENT_META_INTERFACE(MyLight, "com.test.nativeservice.IMyLight"); 23 | 24 | class BnMyLight : public BnInterface { 25 | 26 | public: 27 | virtual status_t onTransact( uint32_t code, 28 | const Parcel& data, 29 | Parcel* reply, 30 | uint32_t flags = 0){ 31 | ALOGD("BnMyLight::onTransact invoked"); 32 | //CHECK_INTERFACE(IMyLight, data, reply); 33 | switch(code){ 34 | case INTERFACE_TRANSACTION: { 35 | reply -> writeString16( IMyLight::getInterfaceDescriptor() ); 36 | return NO_ERROR; 37 | } break; 38 | 39 | case TRANSACTION_flashOn: { 40 | int32_t _onMs, _offMs, _color; 41 | _onMs = data.readInt32(); 42 | _offMs = data.readInt32(); 43 | _color = data.readInt32(); 44 | flashOn(_onMs, _offMs, _color); 45 | return NO_ERROR; 46 | } break; 47 | 48 | case TRANSACTION_turnOff: { 49 | turnOff(); 50 | return NO_ERROR; 51 | } break; 52 | 53 | default: 54 | return BBinder::onTransact(code, data, reply, flags); 55 | } 56 | } 57 | }; 58 | 59 | class MyLightService : public BnMyLight { 60 | 61 | private: 62 | hw_module_t *mModule; 63 | struct light_device_t *mNotifyDevice; 64 | 65 | int getModule(){ 66 | if( hw_get_module(LIGHTS_HARDWARE_MODULE_ID, (hw_module_t const**)&mModule) != 0){ 67 | ALOGE("Error getting hardware module"); 68 | return -1; 69 | } 70 | return 0; 71 | } 72 | 73 | void getNotifyDevice(){ 74 | if( (mModule -> methods -> open(mModule, LIGHT_ID_NOTIFICATIONS, (hw_device_t**)&mNotifyDevice)) != 0){ 75 | ALOGE("Error getting notification device"); 76 | mNotifyDevice = NULL; 77 | }else{ 78 | ALOGI("Successfully get notification device"); 79 | } 80 | } 81 | 82 | public: 83 | MyLightService() { 84 | //Open hardware and devices 85 | if(getModule() == 0){ 86 | getNotifyDevice(); 87 | } 88 | } 89 | 90 | virtual void flashOn(int32_t onMs, int32_t offMs, int32_t color){ 91 | if(mNotifyDevice != NULL){ 92 | struct light_state_t lightMode; 93 | lightMode.color = (unsigned int)color; 94 | lightMode.flashMode = LIGHT_FLASH_TIMED; 95 | lightMode.flashOnMS = onMs; 96 | lightMode.flashOffMS = offMs; 97 | lightMode.brightnessMode = BRIGHTNESS_MODE_SENSOR; 98 | 99 | int err = mNotifyDevice -> set_light(mNotifyDevice, &lightMode); 100 | if(err == 0){ 101 | ALOGI("set_light succeed"); 102 | }else{ 103 | ALOGE("set_light failed"); 104 | } 105 | } 106 | } 107 | 108 | virtual void turnOff(){ 109 | if(mNotifyDevice != NULL){ 110 | struct light_state_t lightMode; 111 | lightMode.color = 0; 112 | lightMode.flashMode = LIGHT_FLASH_NONE; 113 | lightMode.brightnessMode = BRIGHTNESS_MODE_SENSOR; 114 | 115 | int err = mNotifyDevice -> set_light(mNotifyDevice, &lightMode); 116 | if(err == 0){ 117 | ALOGI("turnOff succeed"); 118 | }else{ 119 | ALOGE("turnOff failed"); 120 | } 121 | } 122 | } 123 | }; -------------------------------------------------------------------------------- /app/src/main/jni/include: -------------------------------------------------------------------------------- 1 | /Users/mac/workspace/VibratorBinder/app/src/main/jni/include -------------------------------------------------------------------------------- /app/src/main/jni/lib: -------------------------------------------------------------------------------- 1 | /Users/mac/workspace/VibratorBinder/app/src/main/jni/lib -------------------------------------------------------------------------------- /app/src/main/jni/service/mainService.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace android; 8 | 9 | int main(int argc, char **argv){ 10 | //Register Service 11 | defaultServiceManager() -> addService(String16("my_light"), new MyLightService()); 12 | 13 | //Start thread pool and join to it 14 | ProcessState::self() -> startThreadPool(); 15 | ALOGI("Service my_light started"); 16 | IPCThreadState::self() -> joinThreadPool(); 17 | 18 | return 0; 19 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mshockwave/android-native-service-demo/679eb8dc9cabcfc5d15a12b44ad0275c44ccad34/app/src/main/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mshockwave/android-native-service-demo/679eb8dc9cabcfc5d15a12b44ad0275c44ccad34/app/src/main/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mshockwave/android-native-service-demo/679eb8dc9cabcfc5d15a12b44ad0275c44ccad34/app/src/main/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mshockwave/android-native-service-demo/679eb8dc9cabcfc5d15a12b44ad0275c44ccad34/app/src/main/res/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 |