diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-09 11:52:12 -0700 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-09 11:52:12 -0700 |
commit | b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54 (patch) | |
tree | e167affc928677f3dd70e173150a77e3943e97a9 /services | |
parent | f5b4b98fada53d91c4c2ebeb5a1d33ccc95c94d2 (diff) | |
download | frameworks_base-b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54.zip frameworks_base-b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54.tar.gz frameworks_base-b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54.tar.bz2 |
auto import from //branches/cupcake/...@137197
Diffstat (limited to 'services')
-rw-r--r-- | services/java/Android.mk (renamed from services/Android.mk) | 0 | ||||
-rw-r--r-- | services/java/com/android/server/InputMethodManagerService.java | 77 | ||||
-rw-r--r-- | services/java/com/android/server/WifiService.java | 12 | ||||
-rw-r--r-- | services/jni/Android.mk | 40 | ||||
-rw-r--r-- | services/jni/com_android_server_AlarmManagerService.cpp | 143 | ||||
-rw-r--r-- | services/jni/com_android_server_BatteryService.cpp | 274 | ||||
-rw-r--r-- | services/jni/com_android_server_HardwareService.cpp | 54 | ||||
-rw-r--r-- | services/jni/com_android_server_KeyInputQueue.cpp | 320 | ||||
-rw-r--r-- | services/jni/com_android_server_SensorService.cpp | 125 | ||||
-rw-r--r-- | services/jni/com_android_server_SystemServer.cpp | 47 | ||||
-rw-r--r-- | services/jni/onload.cpp | 36 |
11 files changed, 1100 insertions, 28 deletions
diff --git a/services/Android.mk b/services/java/Android.mk index 5e912d6..5e912d6 100644 --- a/services/Android.mk +++ b/services/java/Android.mk diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java index a254081..9948322 100644 --- a/services/java/com/android/server/InputMethodManagerService.java +++ b/services/java/com/android/server/InputMethodManagerService.java @@ -196,6 +196,11 @@ public class InputMethodManagerService extends IInputMethodManager.Stub ClientState mCurClient; /** + * The last window token that gained focus. + */ + IBinder mCurFocusedWindow; + + /** * The input context last provided by the current client. */ IInputContext mCurInputContext; @@ -557,7 +562,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } } - void unbindCurrentInputLocked() { + void unbindCurrentClientLocked() { if (mCurClient != null) { if (DEBUG) Log.v(TAG, "unbindCurrentInputLocked: client = " + mCurClient.client.asBinder()); @@ -658,7 +663,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub if (mCurClient != cs) { // If the client is changing, we need to switch over to the new // one. - unbindCurrentInputLocked(); + unbindCurrentClientLocked(); if (DEBUG) Log.v(TAG, "switching to client: client = " + cs.client.asBinder()); @@ -721,21 +726,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub throw new IllegalArgumentException("Unknown id: " + mCurMethodId); } - if (mHaveConnection) { - mContext.unbindService(this); - mHaveConnection = false; - } - - if (mCurToken != null) { - try { - if (DEBUG) Log.v(TAG, "Removing window token: " + mCurToken); - mIWindowManager.removeWindowToken(mCurToken); - } catch (RemoteException e) { - } - mCurToken = null; - } - - clearCurMethod(); + unbindCurrentMethodLocked(false); mCurIntent = new Intent(InputMethod.SERVICE_INTERFACE); mCurIntent.setComponent(info.getComponent()); @@ -814,7 +805,30 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } } - void clearCurMethod() { + void unbindCurrentMethodLocked(boolean reportToClient) { + if (mHaveConnection) { + mContext.unbindService(this); + mHaveConnection = false; + } + + if (mCurToken != null) { + try { + if (DEBUG) Log.v(TAG, "Removing window token: " + mCurToken); + mIWindowManager.removeWindowToken(mCurToken); + } catch (RemoteException e) { + } + mCurToken = null; + } + + clearCurMethodLocked(); + + if (reportToClient && mCurClient != null) { + executeOrSendMessage(mCurClient.client, mCaller.obtainMessageIO( + MSG_UNBIND_METHOD, mCurSeq, mCurClient.client)); + } + } + + void clearCurMethodLocked() { if (mCurMethod != null) { for (ClientState cs : mClients.values()) { cs.sessionRequested = false; @@ -831,7 +845,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub + " mCurIntent=" + mCurIntent); if (mCurMethod != null && mCurIntent != null && name.equals(mCurIntent.getComponent())) { - clearCurMethod(); + clearCurMethodLocked(); // We consider this to be a new bind attempt, since the system // should now try to restart the service for us. mLastBindTime = SystemClock.uptimeMillis(); @@ -871,14 +885,22 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } void updateFromSettingsLocked() { + // We are assuming that whoever is changing DEFAULT_INPUT_METHOD and + // ENABLED_INPUT_METHODS is taking care of keeping them correctly in + // sync, so we will never have a DEFAULT_INPUT_METHOD that is not + // enabled. String id = Settings.Secure.getString(mContext.getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD); - if (id != null) { + if (id != null && id.length() > 0) { try { setInputMethodLocked(id); } catch (IllegalArgumentException e) { Log.w(TAG, "Unknown input method from prefs: " + id, e); + unbindCurrentMethodLocked(true); } + } else { + // There is no longer an input method set, so stop any current one. + unbindCurrentMethodLocked(true); } } @@ -903,7 +925,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub intent.putExtra("input_method_id", id); mContext.sendBroadcast(intent); } - unbindCurrentInputLocked(); + unbindCurrentClientLocked(); } finally { Binder.restoreCallingIdentity(ident); } @@ -1023,7 +1045,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub return res; } - public void windowGainedFocus(IInputMethodClient client, + public void windowGainedFocus(IInputMethodClient client, IBinder windowToken, boolean viewHasFocus, boolean isTextEditor, int softInputMode, boolean first, int windowFlags) { long ident = Binder.clearCallingIdentity(); @@ -1043,13 +1065,19 @@ public class InputMethodManagerService extends IInputMethodManager.Stub // focus in the window manager, to allow this call to // be made before input is started in it. if (!mIWindowManager.inputMethodClientHasFocus(client)) { - Log.w(TAG, "Ignoring focus gain of: " + client); + Log.w(TAG, "Client not active, ignoring focus gain of: " + client); return; } } catch (RemoteException e) { } } + if (mCurFocusedWindow == windowToken) { + Log.w(TAG, "Window already focused, ignoring focus gain of: " + client); + return; + } + mCurFocusedWindow = windowToken; + switch (softInputMode&WindowManager.LayoutParams.SOFT_INPUT_MASK_STATE) { case WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED: if (!isTextEditor || (softInputMode & @@ -1558,7 +1586,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub p.println(" mInputMethodData=" + mInputMethodData); p.println(" mCurrentMethod=" + mCurMethodId); client = mCurClient; - p.println(" mCurSeq=" + mCurSeq + " mCurClient=" + client); + p.println(" mCurClient=" + client + " mCurSeq=" + mCurSeq); + p.println(" mCurFocusedWindow=" + mCurFocusedWindow); p.println(" mCurId=" + mCurId + " mHaveConnect=" + mHaveConnection + " mBoundToMethod=" + mBoundToMethod); p.println(" mCurToken=" + mCurToken); diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java index eece581..e298f49 100644 --- a/services/java/com/android/server/WifiService.java +++ b/services/java/com/android/server/WifiService.java @@ -22,9 +22,9 @@ import static android.net.wifi.WifiManager.WIFI_STATE_ENABLED; import static android.net.wifi.WifiManager.WIFI_STATE_ENABLING; import static android.net.wifi.WifiManager.WIFI_STATE_UNKNOWN; -import android.app.ActivityManagerNative; import android.app.AlarmManager; import android.app.PendingIntent; +import android.bluetooth.BluetoothA2dp; import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.Context; @@ -1491,6 +1491,12 @@ public class WifiService extends IWifiManager.Stub { return; } mPluggedType = pluggedType; + } else if (action.equals(BluetoothA2dp.SINK_STATE_CHANGED_ACTION)) { + boolean isBluetoothPlaying = + intent.getIntExtra( + BluetoothA2dp.SINK_STATE, + BluetoothA2dp.STATE_DISCONNECTED) == BluetoothA2dp.STATE_PLAYING; + mWifiStateTracker.setBluetoothScanMode(isBluetoothPlaying); } else { return; } @@ -1603,13 +1609,11 @@ public class WifiService extends IWifiManager.Stub { private void registerForBroadcasts() { IntentFilter intentFilter = new IntentFilter(); - if (isAirplaneSensitive()) { - intentFilter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED); - } intentFilter.addAction(Intent.ACTION_SCREEN_ON); intentFilter.addAction(Intent.ACTION_SCREEN_OFF); intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED); intentFilter.addAction(ACTION_DEVICE_IDLE); + intentFilter.addAction(BluetoothA2dp.SINK_STATE_CHANGED_ACTION); mContext.registerReceiver(mReceiver, intentFilter); } diff --git a/services/jni/Android.mk b/services/jni/Android.mk new file mode 100644 index 0000000..2f48edf --- /dev/null +++ b/services/jni/Android.mk @@ -0,0 +1,40 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES:= \ + com_android_server_AlarmManagerService.cpp \ + com_android_server_BatteryService.cpp \ + com_android_server_HardwareService.cpp \ + com_android_server_KeyInputQueue.cpp \ + com_android_server_SensorService.cpp \ + com_android_server_SystemServer.cpp \ + onload.cpp + +LOCAL_C_INCLUDES += \ + $(JNI_H_INCLUDE) + +LOCAL_SHARED_LIBRARIES := \ + libcutils \ + libhardware \ + libhardware_legacy \ + libnativehelper \ + libsystem_server \ + libutils \ + libui + +ifeq ($(TARGET_SIMULATOR),true) +ifeq ($(TARGET_OS),linux) +ifeq ($(TARGET_ARCH),x86) +LOCAL_LDLIBS += -lpthread -ldl -lrt +endif +endif +endif + +ifeq ($(WITH_MALLOC_LEAK_CHECK),true) + LOCAL_CFLAGS += -DMALLOC_LEAK_CHECK +endif + +LOCAL_MODULE:= libandroid_servers + +include $(BUILD_SHARED_LIBRARY) + diff --git a/services/jni/com_android_server_AlarmManagerService.cpp b/services/jni/com_android_server_AlarmManagerService.cpp new file mode 100644 index 0000000..1d66fb1 --- /dev/null +++ b/services/jni/com_android_server_AlarmManagerService.cpp @@ -0,0 +1,143 @@ +/* //device/libs/android_runtime/android_server_AlarmManagerService.cpp +** +** Copyright 2006, 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. +*/ + +#define LOG_TAG "AlarmManagerService" + +#include "JNIHelp.h" +#include "jni.h" +#include "utils/Log.h" +#include "utils/misc.h" + +#include <fcntl.h> +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <arpa/inet.h> +#include <netinet/in.h> +#include <stdlib.h> +#include <errno.h> +#include <unistd.h> + +#if HAVE_ANDROID_OS +#include <linux/ioctl.h> +#include <linux/android_alarm.h> +#endif + +#define ONE_NANOSECOND 1000000000LL +#define NANOSECONDS_TO_SECONDS(x) (x / ONE_NANOSECOND) +#define SECONDS_TO_NANOSECONDS(x) (x * ONE_NANOSECOND) + +namespace android { + +static jint android_server_AlarmManagerService_setKernelTimezone(JNIEnv* env, jobject obj, jint fd, jint minswest) +{ +#if HAVE_ANDROID_OS + struct timezone tz; + + tz.tz_minuteswest = minswest; + tz.tz_dsttime = 0; + + int result = settimeofday(NULL, &tz); + if (result < 0) { + LOGE("Unable to set kernel timezone to %d: %s\n", minswest, strerror(errno)); + return -1; + } else { + LOGD("Kernel timezone updated to %d minutes west of GMT\n", minswest); + } + + return 0; +#else + return -ENOSYS; +#endif +} + +static jint android_server_AlarmManagerService_init(JNIEnv* env, jobject obj) +{ +#if HAVE_ANDROID_OS + return open("/dev/alarm", O_RDWR); +#else + return -1; +#endif +} + +static void android_server_AlarmManagerService_close(JNIEnv* env, jobject obj, jint fd) +{ +#if HAVE_ANDROID_OS + close(fd); +#endif +} + +static void android_server_AlarmManagerService_set(JNIEnv* env, jobject obj, jint fd, jint type, jlong nanoseconds) +{ +#if HAVE_ANDROID_OS + struct timespec ts; + ts.tv_sec = NANOSECONDS_TO_SECONDS(nanoseconds); + ts.tv_nsec = nanoseconds - SECONDS_TO_NANOSECONDS(ts.tv_sec); + + int result = ioctl(fd, ANDROID_ALARM_SET(type), &ts); + if (result < 0) + { + LOGE("Unable to set alarm to %lld: %s\n", nanoseconds, strerror(errno)); + } +#endif +} + +static jint android_server_AlarmManagerService_waitForAlarm(JNIEnv* env, jobject obj, jint fd) +{ +#if HAVE_ANDROID_OS + int result = 0; + + do + { + result = ioctl(fd, ANDROID_ALARM_WAIT); + } while (result < 0 && errno == EINTR); + + if (result < 0) + { + LOGE("Unable to wait on alarm: %s\n", strerror(errno)); + return 0; + } + + return result; +#endif +} + +static JNINativeMethod sMethods[] = { + /* name, signature, funcPtr */ + {"init", "()I", (void*)android_server_AlarmManagerService_init}, + {"close", "(I)V", (void*)android_server_AlarmManagerService_close}, + {"set", "(IIJ)V", (void*)android_server_AlarmManagerService_set}, + {"waitForAlarm", "(I)I", (void*)android_server_AlarmManagerService_waitForAlarm}, + {"setKernelTimezone", "(II)I", (void*)android_server_AlarmManagerService_setKernelTimezone}, +}; + +int register_android_server_AlarmManagerService(JNIEnv* env) +{ + jclass clazz = env->FindClass("com/android/server/AlarmManagerService"); + + if (clazz == NULL) + { + LOGE("Can't find com/android/server/AlarmManagerService"); + return -1; + } + + return jniRegisterNativeMethods(env, "com/android/server/AlarmManagerService", + sMethods, NELEM(sMethods)); +} + +} /* namespace android */ diff --git a/services/jni/com_android_server_BatteryService.cpp b/services/jni/com_android_server_BatteryService.cpp new file mode 100644 index 0000000..6636a97 --- /dev/null +++ b/services/jni/com_android_server_BatteryService.cpp @@ -0,0 +1,274 @@ +/* + * Copyright (C) 2008 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. + */ + +#define LOG_TAG "BatteryService" + +#include "JNIHelp.h" +#include "jni.h" +#include "utils/Log.h" +#include "utils/misc.h" + +#include <fcntl.h> +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <arpa/inet.h> +#include <netinet/in.h> +#include <stdlib.h> +#include <errno.h> +#include <unistd.h> + +#if HAVE_ANDROID_OS +#include <linux/ioctl.h> +#endif + +namespace android { + +#define AC_ONLINE_PATH "/sys/class/power_supply/ac/online" +#define USB_ONLINE_PATH "/sys/class/power_supply/usb/online" +#define BATTERY_STATUS_PATH "/sys/class/power_supply/battery/status" +#define BATTERY_HEALTH_PATH "/sys/class/power_supply/battery/health" +#define BATTERY_PRESENT_PATH "/sys/class/power_supply/battery/present" +#define BATTERY_CAPACITY_PATH "/sys/class/power_supply/battery/capacity" +#define BATTERY_VOLTAGE_PATH "/sys/class/power_supply/battery/batt_vol" +#define BATTERY_TEMPERATURE_PATH "/sys/class/power_supply/battery/batt_temp" +#define BATTERY_TECHNOLOGY_PATH "/sys/class/power_supply/battery/technology" + +struct FieldIds { + // members + jfieldID mAcOnline; + jfieldID mUsbOnline; + jfieldID mBatteryStatus; + jfieldID mBatteryHealth; + jfieldID mBatteryPresent; + jfieldID mBatteryLevel; + jfieldID mBatteryVoltage; + jfieldID mBatteryTemperature; + jfieldID mBatteryTechnology; +}; +static FieldIds gFieldIds; + +struct BatteryManagerConstants { + jint statusUnknown; + jint statusCharging; + jint statusDischarging; + jint statusNotCharging; + jint statusFull; + jint healthUnknown; + jint healthGood; + jint healthOverheat; + jint healthDead; + jint healthOverVoltage; + jint healthUnspecifiedFailure; +}; +static BatteryManagerConstants gConstants; + +static jint getBatteryStatus(const char* status) +{ + switch (status[0]) { + case 'C': return gConstants.statusCharging; // Charging + case 'D': return gConstants.statusDischarging; // Discharging + case 'F': return gConstants.statusFull; // Not charging + case 'N': return gConstants.statusNotCharging; // Full + case 'U': return gConstants.statusUnknown; // Unknown + + default: { + LOGW("Unknown battery status '%s'", status); + return gConstants.statusUnknown; + } + } +} + +static jint getBatteryHealth(const char* status) +{ + switch (status[0]) { + case 'D': return gConstants.healthDead; // Dead + case 'G': return gConstants.healthGood; // Good + case 'O': { + if (strcmp(status, "Overheat") == 0) { + return gConstants.healthOverheat; + } else if (strcmp(status, "Over voltage") == 0) { + return gConstants.healthOverVoltage; + } + LOGW("Unknown battery health[1] '%s'", status); + return gConstants.healthUnknown; + } + + case 'U': { + if (strcmp(status, "Unspecified failure") == 0) { + return gConstants.healthUnspecifiedFailure; + } else if (strcmp(status, "Unknown") == 0) { + return gConstants.healthUnknown; + } + // fall through + } + + default: { + LOGW("Unknown battery health[2] '%s'", status); + return gConstants.healthUnknown; + } + } +} + +static int readFromFile(const char* path, char* buf, size_t size) +{ + int fd = open(path, O_RDONLY, 0); + if (fd == -1) { + LOGE("Could not open '%s'", path); + return -1; + } + + size_t count = read(fd, buf, size); + if (count > 0) { + count = (count < size) ? count : size - 1; + while (count > 0 && buf[count-1] == '\n') count--; + buf[count] = '\0'; + } else { + buf[0] = '\0'; + } + + close(fd); + return count; +} + +static void setBooleanField(JNIEnv* env, jobject obj, const char* path, jfieldID fieldID) +{ + const int SIZE = 16; + char buf[SIZE]; + + jboolean value = false; + if (readFromFile(path, buf, SIZE) > 0) { + if (buf[0] == '1') { + value = true; + } + } + env->SetBooleanField(obj, fieldID, value); +} + +static void setIntField(JNIEnv* env, jobject obj, const char* path, jfieldID fieldID) +{ + const int SIZE = 128; + char buf[SIZE]; + + jint value = 0; + if (readFromFile(path, buf, SIZE) > 0) { + value = atoi(buf); + } + env->SetIntField(obj, fieldID, value); +} + +static void android_server_BatteryService_update(JNIEnv* env, jobject obj) +{ + setBooleanField(env, obj, AC_ONLINE_PATH, gFieldIds.mAcOnline); + setBooleanField(env, obj, USB_ONLINE_PATH, gFieldIds.mUsbOnline); + setBooleanField(env, obj, BATTERY_PRESENT_PATH, gFieldIds.mBatteryPresent); + + setIntField(env, obj, BATTERY_CAPACITY_PATH, gFieldIds.mBatteryLevel); + setIntField(env, obj, BATTERY_VOLTAGE_PATH, gFieldIds.mBatteryVoltage); + setIntField(env, obj, BATTERY_TEMPERATURE_PATH, gFieldIds.mBatteryTemperature); + + const int SIZE = 128; + char buf[SIZE]; + + if (readFromFile(BATTERY_STATUS_PATH, buf, SIZE) > 0) + env->SetIntField(obj, gFieldIds.mBatteryStatus, getBatteryStatus(buf)); + + if (readFromFile(BATTERY_HEALTH_PATH, buf, SIZE) > 0) + env->SetIntField(obj, gFieldIds.mBatteryHealth, getBatteryHealth(buf)); + + if (readFromFile(BATTERY_TECHNOLOGY_PATH, buf, SIZE) > 0) + env->SetObjectField(obj, gFieldIds.mBatteryTechnology, env->NewStringUTF(buf)); +} + +static JNINativeMethod sMethods[] = { + /* name, signature, funcPtr */ + {"native_update", "()V", (void*)android_server_BatteryService_update}, +}; + +int register_android_server_BatteryService(JNIEnv* env) +{ + jclass clazz = env->FindClass("com/android/server/BatteryService"); + + if (clazz == NULL) { + LOGE("Can't find com/android/server/BatteryService"); + return -1; + } + + gFieldIds.mAcOnline = env->GetFieldID(clazz, "mAcOnline", "Z"); + gFieldIds.mUsbOnline = env->GetFieldID(clazz, "mUsbOnline", "Z"); + gFieldIds.mBatteryStatus = env->GetFieldID(clazz, "mBatteryStatus", "I"); + gFieldIds.mBatteryHealth = env->GetFieldID(clazz, "mBatteryHealth", "I"); + gFieldIds.mBatteryPresent = env->GetFieldID(clazz, "mBatteryPresent", "Z"); + gFieldIds.mBatteryLevel = env->GetFieldID(clazz, "mBatteryLevel", "I"); + gFieldIds.mBatteryTechnology = env->GetFieldID(clazz, "mBatteryTechnology", "Ljava/lang/String;"); + gFieldIds.mBatteryVoltage = env->GetFieldID(clazz, "mBatteryVoltage", "I"); + gFieldIds.mBatteryTemperature = env->GetFieldID(clazz, "mBatteryTemperature", "I"); + + LOG_FATAL_IF(gFieldIds.mAcOnline == NULL, "Unable to find BatteryService.AC_ONLINE_PATH"); + LOG_FATAL_IF(gFieldIds.mUsbOnline == NULL, "Unable to find BatteryService.USB_ONLINE_PATH"); + LOG_FATAL_IF(gFieldIds.mBatteryStatus == NULL, "Unable to find BatteryService.BATTERY_STATUS_PATH"); + LOG_FATAL_IF(gFieldIds.mBatteryHealth == NULL, "Unable to find BatteryService.BATTERY_HEALTH_PATH"); + LOG_FATAL_IF(gFieldIds.mBatteryPresent == NULL, "Unable to find BatteryService.BATTERY_PRESENT_PATH"); + LOG_FATAL_IF(gFieldIds.mBatteryLevel == NULL, "Unable to find BatteryService.BATTERY_CAPACITY_PATH"); + LOG_FATAL_IF(gFieldIds.mBatteryVoltage == NULL, "Unable to find BatteryService.BATTERY_VOLTAGE_PATH"); + LOG_FATAL_IF(gFieldIds.mBatteryTemperature == NULL, "Unable to find BatteryService.BATTERY_TEMPERATURE_PATH"); + LOG_FATAL_IF(gFieldIds.mBatteryTechnology == NULL, "Unable to find BatteryService.BATTERY_TECHNOLOGY_PATH"); + + clazz = env->FindClass("android/os/BatteryManager"); + + if (clazz == NULL) { + LOGE("Can't find android/os/BatteryManager"); + return -1; + } + + gConstants.statusUnknown = env->GetStaticIntField(clazz, + env->GetStaticFieldID(clazz, "BATTERY_STATUS_UNKNOWN", "I")); + + gConstants.statusCharging = env->GetStaticIntField(clazz, + env->GetStaticFieldID(clazz, "BATTERY_STATUS_CHARGING", "I")); + + gConstants.statusDischarging = env->GetStaticIntField(clazz, + env->GetStaticFieldID(clazz, "BATTERY_STATUS_DISCHARGING", "I")); + + gConstants.statusNotCharging = env->GetStaticIntField(clazz, + env->GetStaticFieldID(clazz, "BATTERY_STATUS_NOT_CHARGING", "I")); + + gConstants.statusFull = env->GetStaticIntField(clazz, + env->GetStaticFieldID(clazz, "BATTERY_STATUS_FULL", "I")); + + gConstants.healthUnknown = env->GetStaticIntField(clazz, + env->GetStaticFieldID(clazz, "BATTERY_HEALTH_UNKNOWN", "I")); + + gConstants.healthGood = env->GetStaticIntField(clazz, + env->GetStaticFieldID(clazz, "BATTERY_HEALTH_GOOD", "I")); + + gConstants.healthOverheat = env->GetStaticIntField(clazz, + env->GetStaticFieldID(clazz, "BATTERY_HEALTH_OVERHEAT", "I")); + + gConstants.healthDead = env->GetStaticIntField(clazz, + env->GetStaticFieldID(clazz, "BATTERY_HEALTH_DEAD", "I")); + + gConstants.healthOverVoltage = env->GetStaticIntField(clazz, + env->GetStaticFieldID(clazz, "BATTERY_HEALTH_OVER_VOLTAGE", "I")); + + gConstants.healthUnspecifiedFailure = env->GetStaticIntField(clazz, + env->GetStaticFieldID(clazz, "BATTERY_HEALTH_UNSPECIFIED_FAILURE", "I")); + + return jniRegisterNativeMethods(env, "com/android/server/BatteryService", sMethods, NELEM(sMethods)); +} + +} /* namespace android */ diff --git a/services/jni/com_android_server_HardwareService.cpp b/services/jni/com_android_server_HardwareService.cpp new file mode 100644 index 0000000..ac36348 --- /dev/null +++ b/services/jni/com_android_server_HardwareService.cpp @@ -0,0 +1,54 @@ +/* //device/libs/android_runtime/android_os_Vibrator.cpp +** +** Copyright 2006, 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. +*/ + +#define LOG_TAG "Vibrator" + +#include "jni.h" +#include "JNIHelp.h" +#include <stdio.h> +#include "android_runtime/AndroidRuntime.h" +#include <utils/misc.h> +#include <utils/Log.h> +#include <hardware_legacy/vibrator.h> + +namespace android +{ + +static void vibratorOn(JNIEnv *env, jobject clazz, jlong timeout_ms) +{ + // LOGI("vibratorOn\n"); + vibrator_on(timeout_ms); +} + +static void vibratorOff(JNIEnv *env, jobject clazz) +{ + // LOGI("vibratorOff\n"); + vibrator_off(); +} + +static JNINativeMethod method_table[] = { + { "vibratorOn", "(J)V", (void*)vibratorOn }, + { "vibratorOff", "()V", (void*)vibratorOff } +}; + +int register_android_os_Vibrator(JNIEnv *env) +{ + return jniRegisterNativeMethods(env, "com/android/server/HardwareService", + method_table, NELEM(method_table)); +} + +}; diff --git a/services/jni/com_android_server_KeyInputQueue.cpp b/services/jni/com_android_server_KeyInputQueue.cpp new file mode 100644 index 0000000..63830d5 --- /dev/null +++ b/services/jni/com_android_server_KeyInputQueue.cpp @@ -0,0 +1,320 @@ +/* + * Copyright (C) 2007 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. + */ + +#define LOG_TAG "Input" + +#include "jni.h" +#include "JNIHelp.h" +#include <utils/misc.h> +#include <utils/Log.h> + +#include <ui/EventHub.h> +#include <utils/threads.h> + +#include <stdio.h> + +namespace android { + +// ---------------------------------------------------------------------------- + +static struct input_offsets_t +{ + jfieldID mMinValue; + jfieldID mMaxValue; + jfieldID mFlat; + jfieldID mFuzz; + + jfieldID mDeviceId; + jfieldID mType; + jfieldID mScancode; + jfieldID mKeycode; + jfieldID mFlags; + jfieldID mValue; + jfieldID mWhen; +} gInputOffsets; + +// ---------------------------------------------------------------------------- + +static Mutex gLock; +static sp<EventHub> gHub; + +static jboolean +android_server_KeyInputQueue_readEvent(JNIEnv* env, jobject clazz, + jobject event) +{ + gLock.lock(); + sp<EventHub> hub = gHub; + if (hub == NULL) { + hub = new EventHub; + gHub = hub; + } + gLock.unlock(); + + int32_t deviceId; + int32_t type; + int32_t scancode, keycode; + uint32_t flags; + int32_t value; + nsecs_t when; + bool res = hub->getEvent(&deviceId, &type, &scancode, &keycode, + &flags, &value, &when); + + env->SetIntField(event, gInputOffsets.mDeviceId, (jint)deviceId); + env->SetIntField(event, gInputOffsets.mType, (jint)type); + env->SetIntField(event, gInputOffsets.mScancode, (jint)scancode); + env->SetIntField(event, gInputOffsets.mKeycode, (jint)keycode); + env->SetIntField(event, gInputOffsets.mFlags, (jint)flags); + env->SetIntField(event, gInputOffsets.mValue, value); + env->SetLongField(event, gInputOffsets.mWhen, + (jlong)(nanoseconds_to_milliseconds(when))); + + return res; +} + +static jint +android_server_KeyInputQueue_getDeviceClasses(JNIEnv* env, jobject clazz, + jint deviceId) +{ + jint classes = 0; + gLock.lock(); + if (gHub != NULL) classes = gHub->getDeviceClasses(deviceId); + gLock.unlock(); + return classes; +} + +static jstring +android_server_KeyInputQueue_getDeviceName(JNIEnv* env, jobject clazz, + jint deviceId) +{ + String8 name; + gLock.lock(); + if (gHub != NULL) name = gHub->getDeviceName(deviceId); + gLock.unlock(); + + if (name.size() > 0) { + return env->NewStringUTF(name.string()); + } + return NULL; +} + +static jboolean +android_server_KeyInputQueue_getAbsoluteInfo(JNIEnv* env, jobject clazz, + jint deviceId, jint axis, + jobject info) +{ + int32_t minValue, maxValue, flat, fuzz; + int res = -1; + gLock.lock(); + if (gHub != NULL) { + res = gHub->getAbsoluteInfo(deviceId, axis, + &minValue, &maxValue, &flat, &fuzz); + } + gLock.unlock(); + + if (res < 0) return JNI_FALSE; + + env->SetIntField(info, gInputOffsets.mMinValue, (jint)minValue); + env->SetIntField(info, gInputOffsets.mMaxValue, (jint)maxValue); + env->SetIntField(info, gInputOffsets.mFlat, (jint)flat); + env->SetIntField(info, gInputOffsets.mFuzz, (jint)fuzz); + return JNI_TRUE; +} + +static jint +android_server_KeyInputQueue_getSwitchState(JNIEnv* env, jobject clazz, + jint sw) +{ + jint st = -1; + gLock.lock(); + if (gHub != NULL) st = gHub->getSwitchState(sw); + gLock.unlock(); + + return st; +} + +static jint +android_server_KeyInputQueue_getSwitchStateDevice(JNIEnv* env, jobject clazz, + jint deviceId, jint sw) +{ + jint st = -1; + gLock.lock(); + if (gHub != NULL) st = gHub->getSwitchState(deviceId, sw); + gLock.unlock(); + + return st; +} + +static jint +android_server_KeyInputQueue_getScancodeState(JNIEnv* env, jobject clazz, + jint sw) +{ + jint st = -1; + gLock.lock(); + if (gHub != NULL) st = gHub->getScancodeState(sw); + gLock.unlock(); + + return st; +} + +static jint +android_server_KeyInputQueue_getScancodeStateDevice(JNIEnv* env, jobject clazz, + jint deviceId, jint sw) +{ + jint st = -1; + gLock.lock(); + if (gHub != NULL) st = gHub->getScancodeState(deviceId, sw); + gLock.unlock(); + + return st; +} + +static jint +android_server_KeyInputQueue_getKeycodeState(JNIEnv* env, jobject clazz, + jint sw) +{ + jint st = -1; + gLock.lock(); + if (gHub != NULL) st = gHub->getKeycodeState(sw); + gLock.unlock(); + + return st; +} + +static jint +android_server_KeyInputQueue_getKeycodeStateDevice(JNIEnv* env, jobject clazz, + jint deviceId, jint sw) +{ + jint st = -1; + gLock.lock(); + if (gHub != NULL) st = gHub->getKeycodeState(deviceId, sw); + gLock.unlock(); + + return st; +} + +static jboolean +android_server_KeyInputQueue_hasKeys(JNIEnv* env, jobject clazz, + jintArray keyCodes, jbooleanArray outFlags) +{ + jboolean ret = JNI_FALSE; + + int32_t* codes = env->GetIntArrayElements(keyCodes, NULL); + uint8_t* flags = env->GetBooleanArrayElements(outFlags, NULL); + size_t numCodes = env->GetArrayLength(keyCodes); + if (numCodes == env->GetArrayLength(outFlags)) { + gLock.lock(); + if (gHub != NULL) ret = gHub->hasKeys(numCodes, codes, flags); + gLock.unlock(); + } + + env->ReleaseBooleanArrayElements(outFlags, flags, 0); + env->ReleaseIntArrayElements(keyCodes, codes, 0); + return ret; +} + +// ---------------------------------------------------------------------------- + +/* + * JNI registration. + */ +static JNINativeMethod gInputMethods[] = { + /* name, signature, funcPtr */ + { "readEvent", "(Landroid/view/RawInputEvent;)Z", + (void*) android_server_KeyInputQueue_readEvent }, + { "getDeviceClasses", "(I)I", + (void*) android_server_KeyInputQueue_getDeviceClasses }, + { "getDeviceName", "(I)Ljava/lang/String;", + (void*) android_server_KeyInputQueue_getDeviceName }, + { "getAbsoluteInfo", "(IILcom/android/server/InputDevice$AbsoluteInfo;)Z", + (void*) android_server_KeyInputQueue_getAbsoluteInfo }, + { "getSwitchState", "(I)I", + (void*) android_server_KeyInputQueue_getSwitchState }, + { "getSwitchState", "(II)I", + (void*) android_server_KeyInputQueue_getSwitchStateDevice }, + { "getScancodeState", "(I)I", + (void*) android_server_KeyInputQueue_getScancodeState }, + { "getScancodeState", "(II)I", + (void*) android_server_KeyInputQueue_getScancodeStateDevice }, + { "getKeycodeState", "(I)I", + (void*) android_server_KeyInputQueue_getKeycodeState }, + { "getKeycodeState", "(II)I", + (void*) android_server_KeyInputQueue_getKeycodeStateDevice }, + { "hasKeys", "([I[Z)Z", + (void*) android_server_KeyInputQueue_hasKeys }, +}; + +int register_android_server_KeyInputQueue(JNIEnv* env) +{ + jclass input = env->FindClass("com/android/server/KeyInputQueue"); + LOG_FATAL_IF(input == NULL, "Unable to find class com/android/server/KeyInputQueue"); + int res = jniRegisterNativeMethods(env, "com/android/server/KeyInputQueue", + gInputMethods, NELEM(gInputMethods)); + + jclass absoluteInfo = env->FindClass("com/android/server/InputDevice$AbsoluteInfo"); + LOG_FATAL_IF(absoluteInfo == NULL, "Unable to find class com/android/server/InputDevice$AbsoluteInfo"); + + gInputOffsets.mMinValue + = env->GetFieldID(absoluteInfo, "minValue", "I"); + LOG_FATAL_IF(gInputOffsets.mMinValue == NULL, "Unable to find InputDevice.AbsoluteInfo.minValue"); + + gInputOffsets.mMaxValue + = env->GetFieldID(absoluteInfo, "maxValue", "I"); + LOG_FATAL_IF(gInputOffsets.mMaxValue == NULL, "Unable to find InputDevice.AbsoluteInfo.maxValue"); + + gInputOffsets.mFlat + = env->GetFieldID(absoluteInfo, "flat", "I"); + LOG_FATAL_IF(gInputOffsets.mFlat == NULL, "Unable to find InputDevice.AbsoluteInfo.flat"); + + gInputOffsets.mFuzz + = env->GetFieldID(absoluteInfo, "fuzz", "I"); + LOG_FATAL_IF(gInputOffsets.mFuzz == NULL, "Unable to find InputDevice.AbsoluteInfo.fuzz"); + + jclass inputEvent = env->FindClass("android/view/RawInputEvent"); + LOG_FATAL_IF(inputEvent == NULL, "Unable to find class android/view/RawInputEvent"); + + gInputOffsets.mDeviceId + = env->GetFieldID(inputEvent, "deviceId", "I"); + LOG_FATAL_IF(gInputOffsets.mDeviceId == NULL, "Unable to find RawInputEvent.deviceId"); + + gInputOffsets.mType + = env->GetFieldID(inputEvent, "type", "I"); + LOG_FATAL_IF(gInputOffsets.mType == NULL, "Unable to find RawInputEvent.type"); + + gInputOffsets.mScancode + = env->GetFieldID(inputEvent, "scancode", "I"); + LOG_FATAL_IF(gInputOffsets.mScancode == NULL, "Unable to find RawInputEvent.scancode"); + + gInputOffsets.mKeycode + = env->GetFieldID(inputEvent, "keycode", "I"); + LOG_FATAL_IF(gInputOffsets.mKeycode == NULL, "Unable to find RawInputEvent.keycode"); + + gInputOffsets.mFlags + = env->GetFieldID(inputEvent, "flags", "I"); + LOG_FATAL_IF(gInputOffsets.mFlags == NULL, "Unable to find RawInputEvent.flags"); + + gInputOffsets.mValue + = env->GetFieldID(inputEvent, "value", "I"); + LOG_FATAL_IF(gInputOffsets.mValue == NULL, "Unable to find RawInputEvent.value"); + + gInputOffsets.mWhen + = env->GetFieldID(inputEvent, "when", "J"); + LOG_FATAL_IF(gInputOffsets.mWhen == NULL, "Unable to find RawInputEvent.when"); + + return res; +} + +}; // namespace android + diff --git a/services/jni/com_android_server_SensorService.cpp b/services/jni/com_android_server_SensorService.cpp new file mode 100644 index 0000000..695a8a3 --- /dev/null +++ b/services/jni/com_android_server_SensorService.cpp @@ -0,0 +1,125 @@ +/* + * Copyright 2008, 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. + */ + +#define LOG_TAG "Sensors" + +#include <hardware/sensors.h> + +#include "jni.h" +#include "JNIHelp.h" + +namespace android { + +static struct file_descriptor_offsets_t +{ + jclass mClass; + jmethodID mConstructor; + jfieldID mDescriptor; +} gFileDescriptorOffsets; + +static struct parcel_file_descriptor_offsets_t +{ + jclass mClass; + jmethodID mConstructor; +} gParcelFileDescriptorOffsets; + +/* + * The method below are not thread-safe and not intended to be + */ + +static sensors_control_device_t* sSensorDevice = 0; + +static jint +android_init(JNIEnv *env, jclass clazz) +{ + sensors_module_t* module; + if (hw_get_module(SENSORS_HARDWARE_MODULE_ID, (const hw_module_t**)&module) == 0) { + if (sensors_control_open(&module->common, &sSensorDevice) == 0) { + const struct sensor_t* list; + int count = module->get_sensors_list(module, &list); + return count; + } + } + return 0; +} + +static jobject +android_open(JNIEnv *env, jclass clazz) +{ + int fd = sSensorDevice->open_data_source(sSensorDevice); + // new FileDescriptor() + jobject filedescriptor = env->NewObject( + gFileDescriptorOffsets.mClass, + gFileDescriptorOffsets.mConstructor); + + if (filedescriptor != NULL) { + env->SetIntField(filedescriptor, gFileDescriptorOffsets.mDescriptor, fd); + // new ParcelFileDescriptor() + return env->NewObject(gParcelFileDescriptorOffsets.mClass, + gParcelFileDescriptorOffsets.mConstructor, + filedescriptor); + } + close(fd); + return NULL; +} + +static jboolean +android_activate(JNIEnv *env, jclass clazz, jint sensor, jboolean activate) +{ + int active = sSensorDevice->activate(sSensorDevice, sensor, activate); + return (active<0) ? false : true; +} + +static jint +android_set_delay(JNIEnv *env, jclass clazz, jint ms) +{ + return sSensorDevice->set_delay(sSensorDevice, ms); +} + +static jint +android_data_wake(JNIEnv *env, jclass clazz) +{ + int res = sSensorDevice->wake(sSensorDevice); + return res; +} + + +static JNINativeMethod gMethods[] = { + {"_sensors_control_init", "()I", (void*) android_init }, + {"_sensors_control_open", "()Landroid/os/ParcelFileDescriptor;", (void*) android_open }, + {"_sensors_control_activate", "(IZ)Z", (void*) android_activate }, + {"_sensors_control_wake", "()I", (void*) android_data_wake }, + {"_sensors_control_set_delay","(I)I", (void*) android_set_delay }, +}; + +int register_android_server_SensorService(JNIEnv *env) +{ + jclass clazz; + + clazz = env->FindClass("java/io/FileDescriptor"); + gFileDescriptorOffsets.mClass = (jclass)env->NewGlobalRef(clazz); + gFileDescriptorOffsets.mConstructor = env->GetMethodID(clazz, "<init>", "()V"); + gFileDescriptorOffsets.mDescriptor = env->GetFieldID(clazz, "descriptor", "I"); + + clazz = env->FindClass("android/os/ParcelFileDescriptor"); + gParcelFileDescriptorOffsets.mClass = (jclass) env->NewGlobalRef(clazz); + gParcelFileDescriptorOffsets.mConstructor = env->GetMethodID(clazz, "<init>", "(Ljava/io/FileDescriptor;)V"); + + return jniRegisterNativeMethods(env, "com/android/server/SensorService", + gMethods, NELEM(gMethods)); +} + +}; // namespace android diff --git a/services/jni/com_android_server_SystemServer.cpp b/services/jni/com_android_server_SystemServer.cpp new file mode 100644 index 0000000..ae29405 --- /dev/null +++ b/services/jni/com_android_server_SystemServer.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2007 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. + */ +#include <utils/Log.h> +#include <utils/misc.h> + +#include "jni.h" +#include "JNIHelp.h" + +namespace android { + +extern "C" int system_init(); + +static void android_server_SystemServer_init1(JNIEnv* env, jobject clazz) +{ + system_init(); +} + +/* + * JNI registration. + */ +static JNINativeMethod gMethods[] = { + /* name, signature, funcPtr */ + { "init1", "([Ljava/lang/String;)V", (void*) android_server_SystemServer_init1 }, +}; + +int register_android_server_SystemServer(JNIEnv* env) +{ + return jniRegisterNativeMethods(env, "com/android/server/SystemServer", + gMethods, NELEM(gMethods)); +} + +}; // namespace android + + diff --git a/services/jni/onload.cpp b/services/jni/onload.cpp new file mode 100644 index 0000000..3d68cfb --- /dev/null +++ b/services/jni/onload.cpp @@ -0,0 +1,36 @@ +#include "JNIHelp.h" +#include "jni.h" +#include "utils/Log.h" +#include "utils/misc.h" + +namespace android { +int register_android_server_AlarmManagerService(JNIEnv* env); +int register_android_server_BatteryService(JNIEnv* env); +int register_android_server_KeyInputQueue(JNIEnv* env); +int register_android_os_Vibrator(JNIEnv* env); +int register_android_server_SensorService(JNIEnv* env); +int register_android_server_SystemServer(JNIEnv* env); +}; + +using namespace android; + +extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved) +{ + JNIEnv* env = NULL; + jint result = -1; + + if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) { + LOGE("GetEnv failed!"); + return result; + } + LOG_ASSERT(env, "Could not retrieve the env!"); + + register_android_server_KeyInputQueue(env); + register_android_os_Vibrator(env); + register_android_server_AlarmManagerService(env); + register_android_server_BatteryService(env); + register_android_server_SensorService(env); + register_android_server_SystemServer(env); + + return JNI_VERSION_1_4; +} |