[上接 android linux基础知识总结[上]] ================================================= 5. 设置模块流程分析 rild 流程分析 5.1 设置 pin 状态,pin认证 5.1.1 设置pin状态 5.1.2 修改sim卡pin 5.1.3 pin认证流程 5.2 网络设置 5.3 屏幕背光设置 5.4 获取,显示电池状态 ================ EditPinPreference.java (packages\apps\settings\src\com\android\settings) private OnPinEnteredListener mPinListener; protected void onDialogClosed(boolean positiveResult) mPinListener.onPinEntered(this, positiveResult); 执行 SimLockSettings.java (packages\apps\settings\src\com\android\settings)中函数: public void onPinEntered(EditPinPreference preference, boolean positiveResult) 修改pin状态: tryChangeSimLockState(); 修改pin: tryChangePin(); 5.1.1 设置pin状态 private void tryChangeSimLockState() Message callback = Message.obtain(mHandler, ENABLE_SIM_PIN_COMPLETE); mPhone.getSimCard().setSimLockEnabled(mToState, mPin, callback); 进入sim lock 菜单会显示初始化pin状态,是通过下面语句得到: mPinToggle.setChecked(mPhone.getSimCard().getSimLockEnabled()); mPhone.getSimCard().setSimLockEnabled(mToState, mPin, callback)调用的是文件: GsmSimCard.java (frameworks\base\telephony\java\com\android\internal\telephony\gsm)中的函数: public void setSimLockEnabled (boolean enabled,String password, Message onComplete) { int serviceClassX; serviceClassX = CommandsInterface.SERVICE_CLASS_VOICE + CommandsInterface.SERVICE_CLASS_DATA + CommandsInterface.SERVICE_CLASS_FAX; mDesiredPinLocked = enabled; phone.mCM.setFacilityLock(CommandsInterface.CB_FACILITY_BA_SIM, enabled, password, serviceClassX, obtainMessage(EVENT_CHANGE_FACILITY_LOCK_DONE, onComplete)); phone.mCM.setFacilityLock 调用的是文件: RIL.java (frameworks\base\telephony\java\com\android\internal\telephony\gsm)中的函数: public void setFacilityLock (String facility, boolean lockState, String password, int serviceClass, Message response) { String lockString; RILRequest rr = RILRequest.obtain(RIL_REQUEST_SET_FACILITY_LOCK, response); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); // count strings rr.mp.writeInt(4); rr.mp.writeString(facility); lockString = (lockState)?"1":"0"; rr.mp.writeString(lockString); rr.mp.writeString(password); rr.mp.writeString(Integer.toString(serviceClass)); send(rr); } 设置应用程序向 rild 发送 RIL_REQUEST_SET_FACILITY_LOCK 请求的 socket消息, android的初始源代码中 RIL_REQUEST_SET_FACILITY_LOCK 请求,在参考实现 Reference-ril.c (hardware\ril\reference-ril) 中没有实现。 我们需要做得工作是: ========== 5.1.2 修改sim卡pin private void tryChangePin() mPhone.getSimCard().changeSimLockPassword(mOldPin,mNewPin, callback); mPhone.getSimCard 调用的是文件: GsmSimCard.java (frameworks\base\telephony\java\com\android\internal\telephony\gsm)中的函数: public void changeSimLockPassword(String oldPassword, String newPassword, Message onComplete) phone.mCM.changeSimPin(oldPassword, newPassword, obtainMessage(EVENT_CHANGE_SIM_PASSWORD_DONE, onComplete)); phone.mCM.changeSimPin 调用的是文件: RIL.java (frameworks\base\telephony\java\com\android\internal\telephony\gsm)中的函数: public void changeSimPin(String oldPin, String newPin, Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_CHANGE_SIM_PIN, result); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); rr.mp.writeInt(2); rr.mp.writeString(oldPin); rr.mp.writeString(newPin); send(rr); } rild端处理流程: 5.1.3 pin认证流程 ======== 5.2 网络设置 ======= 5.3 屏幕背光设置 packages/apps/Settings/src/com/android/settings/BrightnessPreference.java 背光设置滚动条和关闭按钮都会调用 setBrightness(mOldBrightness); public void onProgressChanged(SeekBar seekBar, int progress,boolean fromTouch) protected void onDialogClosed(boolean positiveResult) private void setBrightness(int brightness) { try { IHardwareService hardware = IHardwareService.Stub.asInterface( ServiceManager.getService("hardware")); if (hardware != null) { hardware.setBacklights(brightness); } } catch (RemoteException doe) { } } 调用硬件服务器 HardwareService 的 setBacklights 函数 HardwareService.java (frameworks\base\services\java\com\android\server): public void setBacklights(int brightness) { . . . // Don't let applications turn the screen all the way off brightness = Math.max(brightness, Power.BRIGHTNESS_DIM); setLightBrightness_UNCHECKED(LIGHT_ID_BACKLIGHT, brightness); setLightBrightness_UNCHECKED(LIGHT_ID_KEYBOARD, brightness); setLightBrightness_UNCHECKED(LIGHT_ID_BUTTONS, brightness); . . . } void setLightOff_UNCHECKED(int light) { //本地调用 setLight_native setLight_native(mNativePointer, light, 0, LIGHT_FLASH_NONE, 0, 0); } void setLightBrightness_UNCHECKED(int light, int brightness) { int b = brightness & 0x000000ff; b = 0xff000000 | (b = LIGHT_COUNT || devices->lights[light] == NULL) { return ; } memset(&state, 0, sizeof(light_state_t)); state.color = colorARGB; state.flashMode = flashMode; state.flashOnMS = onMS; state.flashOffMS = offMS; devices->lights[light]->set_light(devices->lights[light], &state); } Lights.h (hardware\libhardware\include\hardware):#define LIGHTS_HARDWARE_MODULE_ID "lights" com_android_server_HardwareService.cpp (frameworks\base\services\jni) err = hw_get_module(LIGHTS_HARDWARE_MODULE_ID, (hw_module_t const**)&module); static const char *variant_keys[] = { "ro.hardware", /* This goes first so that it can pick up a different file on the emulator. */ "ro.product.board", "ro.board.platform", "ro.arch" }; int hw_get_module(const char *id, const struct hw_module_t **module) status = load(id, prop, &hmi); status = load(id, HAL_DEFAULT_VARIANT, &hmi); static int load(const char *id, const char *variant,const struct hw_module_t **pHmi) snprintf(path, sizeof(path), "%s/%s.%s.so", HAL_LIBRARY_PATH, id, variant); #define HAL_DEFAULT_VARIANT "default" #define HAL_LIBRARY_PATH "/system/lib/hw" 所以path等于: /system/lib/hw/light.marvell.so /system/lib/hw/light.default.so 我们编译的light模块放在 /system/lib/hw/light.default.so 所以初始化成功。 property_get(variant_keys, prop, NULL) 只有 ro.hardware 存在 [ro.hardware]: [marvell] static int lights_device_open(const struct hw_module_t* module, const char* name,struct hw_device_t** device) dev->set_light = set_light_backlight; static struct hw_module_methods_t lights_module_methods = { open: lights_device_open }; hardware/libhardware/modules/lights/Android.mk LOCAL_MODULE:= lights.default err = module->methods->open(module, name, &device); 执行的是 : lights_device_open const char * const brightness_file = "/sys/class/backlight/micco-bl/brightness"; static int set_light_backlight(struct light_device_t* dev, struct light_state_t const* state) { . . . color = state->color; tmp = ((77*((color>>16)&0x00ff)) + (150*((color>>8)&0x00ff)) + (29*(color&0x00ff))) >> 8; brightness = tmp/16; LOGD("---->calling %s(),line=%d state->color=%d,brightness=%d\n",__FUNCTION__,__LINE__,state->color,brightness); len = sprintf(buf,"%d",brightness); len = write(fd, buf, len); . . . } 上面的函数完成了与内核的交互 综上所述,程序调用流程如下,上层应用通过 /sys/class/leds/lcd-backlight/brightnes 于内核打交道 设置模块 -> 硬件服务器 -> 本地调用 ->功能库 -> 读写 /sys/class/leds/lcd-backlight/brightness 函数与内核交互 Init.rc (vendor\marvell\littleton): chown system system /sys/class/leds/keyboard-backlight/brightness Init.rc (vendor\marvell\littleton): chown system system /sys/class/leds/lcd-backlight/brightness Init.rc (vendor\marvell\littleton): chown system system /sys/class/leds/button-backlight/brightness 5.4 获取,显示电池状态 电池状态(正在充电(AC)): Status.java String statusString; mBatteryStatus.setSummary(statusString); public static final int BATTERY_STATUS_UNKNOWN = 1; public static final int BATTERY_STATUS_CHARGING = 2; public static final int BATTERY_STATUS_DISCHARGING = 3; public static final int BATTERY_STATUS_NOT_CHARGING = 4; public static final int BATTERY_STATUS_FULL = 5; // values for "health" field in the ACTION_BATTERY_CHANGED Intent public static final int BATTERY_HEALTH_UNKNOWN = 1; public static final int BATTERY_HEALTH_GOOD = 2; public static final int BATTERY_HEALTH_OVERHEAT = 3; public static final int BATTERY_HEALTH_DEAD = 4; public static final int BATTERY_HEALTH_OVER_VOLTAGE = 5; public static final int BATTERY_HEALTH_UNSPECIFIED_FAILURE = 6; public static final int BATTERY_PLUGGED_AC = 1; 电源充电 public static final int BATTERY_PLUGGED_USB = 2; USB充电 BatteryInfo.java (packages\apps\settings\src\com\android\settings) 电池级别(50%) BatteryService.java (frameworks\base\services\java\com\android\server) 电池服务器: 构造函数: public BatteryService(Context context) mUEventObserver.startObserving("SUBSYSTEM=power_supply"); ---------- UEventObserver.java (frameworks\base\core\java\android\os) void startObserving(String match) ensureThreadStarted(); sThread = new UEventThread(); sThread.start(); sThread.addObserver(match, this); ----------- update() native_update(); sendIntent(); private final void sendIntent() Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); ... intent.putExtra("status", mBatteryStatus); intent.putExtra("health", mBatteryHealth); intent.putExtra("present", mBatteryPresent); intent.putExtra("level", mBatteryLevel); intent.putExtra("scale", BATTERY_SCALE); intent.putExtra("icon-small", icon); intent.putExtra("plugged", mPlugType); intent.putExtra("voltage", mBatteryVoltage); intent.putExtra("temperature", mBatteryTemperature); intent.putExtra("technology", mBatteryTechnology); ActivityManagerNative.broadcastStickyIntent(intent, null); 把读取的电池信息通过广播信息发送给所有的应用程序。 native_update 本地调用的是文件 com_android_server_BatteryService.cpp (frameworks\base\services\jni) 中的函数: 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)); } #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" ================================================= ================================================= 6. linux系统启动流程分析 6.1 桌面操作系统启动流程(redhat,federa,ubuntu) 6.2 小型嵌入式系统启动流程 6.3 android 系统启动流程 ============== 6.1 桌面操作系统启动流程(redhat,federa,ubuntu) ubuntu从6.10开始逐步用upstart代替原来的sysinit,进行服务进程的管理。为了对原有的init实现向后兼容, 目前ubuntu中与init相关的几个目录和应用程序,可以方便后面的论述。这些目录和程序包括: init telinit //字面理解 tell init runlevel /etc/event.d/ /etc/init.d/ /etc/rcX.d/ 首先是/etc/event.d/目录,这是upstart的核心,upstart不同于原有的init的地方就在于它引入了event机制。Event 机制通俗的 讲就是将所有进程的触发、停止等等都看作event(事件)。/etc/event.d/中就存放了目前upstart需要识别的event。这其中主要有三种 rc-default, rcX(x=0,1,...6,S)以及ttyX。这rc-default就类似于 inittab文件,它就是设置默认运行级别的 ,需要运行程序的 脚本,而ttyX则是设置伪终端数目的,也就是你Ctrl+Alt+F(1~6)调出的那个Console。我们以rc2为例,cat rc2: rc-default start on stopped rcS telinit 2 所以会依次执行 /etc/event.d/rcS /etc/event.d/rc2 它们又会分别执行: exec /etc/init.d/rc S exec /etc/init.d/rc 2 这样,我们就可以自然地过渡到下一个重要的目录,/etc/init.d/了。 /etc/init.d/中存放的是服务(services)或者任务(tasks)的执行脚本。可以这么说,只要你安装了一个程序(特别是服务程序daemon), 它可以在系统启动的时候运行,那么它必定会在/etc/init.d/中有一个脚本文件。 执行了一个exec /etc/init.d/rc 2的命令。也就是说,给/etc/init.d/rc脚本传递了一个参数"2",让它执行。 rc脚本(很长,耐心点),能看到这样的一段: # Now run the START scripts for this runlevel. # Run all scripts with the same level in parallel ....... for s in /etc/rc$runlevel.d/S* ....... 将会开始执行/etc/rc2.d/下S开头的脚本。这就过渡到下一个目录/etc/rc2.d/了。 /etc/rc2.d 都是一些到/etc/init.d/中脚本的符号链接。不同的是在开头加上了S和一个数字,S表示在启动时运行,数字则表示执行的先后顺序。 /etc/rcS.d/S35mountall.sh K08vmware S19vmware S20nfs-common |
|
来自: shaobin0604@1... > 《Android》