浏览模式: 标准 | 列表
11月
25

免发激活短信

可能很多人把WIFI激活和免发激活短信弄混(包括我最开始也有弄混),实际上它们之间没有任何关系。

WIFI激活并不能免发激活国际短信,免发激活国际短信也不一定非要WIFI激活。

如果只是向上文中那样改成可WIFI激活,并不能免发激活短信。

那怎么才能免发激活短信呢?

最简单就是同时开启BYPASS_ACTIVATION和我们上篇中添加的WIFI_ACTIVATION选项。并在刷机时不要插卡(不插卡能不能成功激活Profile还不好说,反正我没成功过,不知是当时的网络问题还是不插卡就不能注册或登录Profile),或者插一张废卡(这个有人测试成功过),即可避免发激活短信了。

但上面的方法是有缺陷的,首先你不能用2G、3G这些传统的方法来注册或登录Profile了。然后就是进入系统之后,手势教程也是不能用的。BYPASS_ACTIVATION可能还会带来一些其它的副作用。所以,我们不推荐用上面的方法。

下面就来说一下本人发现的免发激活短信的方法。

虽然发现该方法费了好多工夫,但该方法在实现上却非常简单。在com.palm.app.firstuse的app/models/account-service.js文件中有一个方法:postLoginSettings。这个方法是发送激活短信的罪魁祸首。

它是在哪儿被调用的呢?

它在两处被调用。一处是在com.palm.app.firstuse的app/controllers/restorecomplete-assistant.js的restoreDone方法中被调用的。另一处是com.palm.app.firstuse的app/controllers/status-assistant.js的setup方法中被调用的。

restoreDone这个方法显然是在Profile被恢复的之后,按了完成按钮之后执行的。而status-assistant.js的情况稍微复杂一点。

但是不管是在哪儿被调用,他们都有一个共同点,就是这个方法不管是调用成功还是调用失败都不影响后续正常执行,因为它的成功回调和失败回调除了日志内容不同以外,其它的主要操作都是一模一样的。也就是说完全可以跳过这个方法的执行。

最简单的跳过方式当然就是直接修改postLoginSettings方法,而不是修改调用的地方。那该如何修改呢?最简单的方法就是把原来的对服务的调用注释掉,然后改为直接调用回调方法:

JavaScript代码
 
  1. postLoginSettings: function(AccountLocales, successCallback, errorCallback, sceneController) {  
  2.     /*return sceneController.serviceRequest(NovaAccountService.identifier, { 
  3.         method: 'postLoginSettings', 
  4.         parameters: {"firstTime": true, 'language':AccountLocales.language, 'country':AccountLocales.country}, 
  5.         onSuccess: successCallback, 
  6.         onFailure: errorCallback 
  7.     }, true);*/ successCallback({ "returnValue"true"errorCode": 0, "errorString""success"});  
  8. },  

 注意,这里我们没有增加行数,没有减少行数,为的是避免跟其它的补丁产生冲突。这样修改之后,对于restoreDone中的调用可以完美实现不发激活国际短信了。但是对于新注册或者原来的帐号没有备份的情况下,却会发生点击完成无限转圈圈的问题。这是什么原因呢?

仔细分析我们会发现,在status-assistant.js的setup最后有两行代码:

JavaScript代码
 
  1. this.postLoginRequestComplete = false;  
  2. this.provisioningRequestComplete = false;  

而在对postLoginSettings的回调方法中会将this.postLoginRequestComplete设置为true。并在最后的saveDoneState方法中对这两个标志检测是否都为true,只有都为true时才会保存设置并重启手机。

而上面的修改我们把正常的回调改成了直接调用回调方法,结果就是回调方法被提前执行了,之后又执行到setup底部时,this.postLoginRequestComplete又被重新设置为了false,导致这个标志永远都无法变成true,也就导致了无法重启,一直转圈圈了。

所以,我们应该把直接调用回调方法改成延迟回调,最简单的方法就是用setTimeout方法,下面是正确的修改:

JavaScript代码
 
  1. postLoginSettings: function(AccountLocales, successCallback, errorCallback, sceneController) {  
  2.     /*return sceneController.serviceRequest(NovaAccountService.identifier, { 
  3.         method: 'postLoginSettings', 
  4.         parameters: {"firstTime": true, 'language':AccountLocales.language, 'country':AccountLocales.country}, 
  5.         onSuccess: successCallback, 
  6.         onFailure: errorCallback 
  7.     }, true);*/setTimeout(function() {successCallback({ "returnValue"true"errorCode": 0, "errorString""success"});}, 3000);  
  8. },  

如此修改之后,便实现了完美的任何环境下激活都免发国际短信了。

我们可以把这个修改合并到前面的WIFI激活补丁中去,这样就可以直接用MetaDoctor来实现对ROM的完美修改了。

11月
04

WiFi激活

WiFi激活不是本人首创,该方法在WebOS还只是1.0.2的时候,就已经被开发出来了,并被记录在了 http://www.webos-internals.org/wiki/Patch_webOS_Bypassing_Activation 上。

但是上面写的都是手工修改的方法,做起来比较麻烦,用MetaDoctor就会简单的多:

第一步,在patches目录下找到你需要修改的版本的目录,然后在里面创建一个空的patch文件,比如叫wifi-activation.patch。

第二步,用MetaDoctor的scripts目录下面的unpack-doctor或者unpack-rootfs把WebOS Doctor解开。

第三步,找到/usr/palm/applications/com.palm.app.firstuse/app/controllers/firstuse-util.js,复制一份,比如叫firstuse-util.new.js,然后对其修改保存。

第四步,运行diff –u firstuse-util.js firstuse-util.new.js > firstuse-util.patch,生成补丁。

第五步,同样方法修改并生成account-service.patch。

第六步,把这两个patch里的内容复制到patches目录下创建的那个wifi-activation.patch文件中,每个文件开头那两行的格式,可以按照bypass-activation.patch里面的格式改一下(我没试过不改可不可以用)。

最后,修改Makefile,在其中加上WIFI_ACTIVATION这个选项,修改方法可以参考它原来的BYPASS_ACTIVATION的代码,具体修改那几行这里就不列出来了。 上面的说明中,细心的读者也许会发现,我把Wiki里面关于app-assistant.js的修改给忽略了。不是我忘记了,而是故意的,下面就来解释为何忽略。关于app-assistant.js的修改其实就是bypass-activation.patch做的事情,不同版本的webOS的bypass-activation.patch并不相同,所以按照那个修改并不是最好的方法,最好的方法是直接在Makefile中把BYPASS_ACTIVATION这一项打开就一样了。另外,WIFI_ACTIVATION跟BYPASS_ACTIVATION并没有直接的关系,只是打开BYPASS_ACTIVATION之后,你可以在刷机之后不用插卡,但是不能用其它方式激活,只能用WIFI激活。而不打开BYPASS_ACTIVATION的话则必须插卡,但是除了可以用WIFI激活意外,也可以用2G、3G方式激活。

好了,现在运行一下MetaDoctor的make命令,你的带WIFI激活的ROM就生成了。

刷机之后,在紧急拨号菜单里就可以打开WIFI设置页了。

但这个WIFI设置有一点点小问题,就是设置完成之后,你会发现无法退出这个设置界面,要想继续激活的过程,就需要用“方块+Sym+R”来重启手机才能继续。

那如何才能让让WIFI设置界面可以在设置完成之后正常退出呢?这个思路可以参考紧急拨号界面。

在account-service.js这个文件中,有一个方法是用来打开紧急拨号界面的,我们来看一下它的代码:

JavaScript代码
 
  1. makeEmergencyCall: function (emergencyNumber) {  
  2.     Mojo.Log.info("Emegerncy call to phone app -------------------------------------------------: ",emergencyNumber);  
  3.     return new Mojo.Service.Request("palm://com.palm.applicationManager/open", {  
  4.            parameters: {  
  5.                id: 'com.palm.app.phone',  
  6.                params: {  
  7.                    "prefill": emergencyNumber,  
  8.                 "firstuse":true,  
  9.                 "locale": Account.language + '_' + Account.country   
  10.                }  
  11.            }  
  12.        });  
  13.       
  14. },  

这段代码中,我们可以看到firstuse和locale这两个参数,也就是说紧急拨号调用的就是电话程序,只不过是传入了一个firstuse参数让其可以作特殊处理(locale则是可以在调用它时设置语言)。所以,我们在紧急拨号界面下可以看到取消按钮,而普通情况下打电话则没有这个按钮。

所以,我们也可以给WIFI设置程序增加一个firstuse参数,如果要让他也能根据调用环境设置语言,我们也可以给它增加一个locale参数,不过com.palm.app.wifi本身是不支持这两个参数的,因此我们要对它进行修改。下面是对com.palm.app.wifi相关文件进行的修改:

JavaScript代码
 
  1. --- .orig/usr/palm/applications/com.palm.app.wifi/app/controllers/app-assistant.js  
  2. +++ /usr/palm/applications/com.palm.app.wifi/app/controllers/app-assistant.js  
  3. @@ -9,6 +9,16 @@  
  4.     var dashboardStage = this.controller.getStageProxy('wifidashboard');  
  5.     var networkListStage = this.controller.getStageProxy('networklist');  
  6.    
  7. +   if (params) {  
  8. +       this.firstuse = PalmSystem.isMinimal || params.firstuse === true;  
  9. +       //If the First Use passes the locale different than the current one, change the Mojo.Locale(Framework)  
  10. +       if (this.firstuse) {  
  11. +           if (params.locale && params.locale.length === 5 && params.locale != Mojo.Locale.current) {  
  12. +               Mojo.Locale.set(params.locale);  
  13. +           }  
  14. +       }  
  15. +    }  
  16. +  
  17.     if (networkListStage)  
  18.     {  
  19.         Mojo.Log.info("Wifi launch reactivate");  
  20. --- .orig/usr/palm/applications/com.palm.app.wifi/app/controllers/networklist-assistant.js  
  21. +++ /usr/palm/applications/com.palm.app.wifi/app/controllers/networklist-assistant.js  
  22. @@ -3,6 +3,7 @@  
  23.  var list_label_toggle_off = $L("Off");  
  24.  var list_label_list_other_network = $L("Join other network");  
  25.  var list_label_list_network = $L("Join network");  
  26. +var list_label_done_button = $L("Done");  
  27.    
  28.  var list_label_status_associating = $L("Connecting......");  
  29.  var list_label_status_associated = $L("...Connecting...");  
  30. @@ -70,7 +71,7 @@  
  31.              Mojo.Log.info("initialize(): called via wifi preferences with params - " + Object.toJSON(params));  
  32.              this.bRunViaPreferencesMenu = true;  
  33.              this.params = params;  
  34. -        } else if (params.hotspot) {  
  35. +        } else if (params.hotspot || params.firstuse) {  
  36.              this.params = params;  
  37.          }  
  38.          this.findNetworksHandle = undefined;  
  39. @@ -170,6 +171,17 @@  
  40.              }  
  41.          });  
  42.    
  43. +        this.doneButtonModel = {buttonLabel: list_label_done_button};        
  44. +        this.controller.setupWidget('doneButton', {type:Mojo.Widget.activityButton}, this.doneButtonModel);  
  45. +        this.doneButton = this.controller.get('doneButton');  
  46. +        if (this.params && this.params.firstuse) {  
  47. +            this.doneButton.style.display = "block";  
  48. +        }  
  49. +        else {  
  50. +            this.doneButton.style.display = "none";  
  51. +        }  
  52. +        Mojo.Event.listen(this.doneButton, 'mojo-tap'this.closeAllStages.bind(this))  
  53. +  
  54.          timing.pause('scene#networklist#setup');  
  55.  //        Mojo.Log.info("setup(): leaving");  
  56.      },  
  57. @@ -976,6 +988,10 @@  
  58.             template: 'joinwapicerts/joinwapicerts-scene',  
  59.             assistant: new JoinwapicertsAssistant(this, item)  
  60.          });  
  61. +    },  
  62. +  
  63. +    closeAllStages: function() {  
  64. +        this.controller.stageController.getAppController().closeAllStages();  
  65.      }  
  66.    
  67.  });  
  68. --- .orig/usr/palm/applications/com.palm.app.wifi/app/views/networklist/networklist-scene.html  
  69. +++ /usr/palm/applications/com.palm.app.wifi/app/views/networklist/networklist-scene.html  
  70. @@ -18,4 +18,5 @@  
  71.      <div id="wifiOffText" style="display:none;" class="palm-text-wrapper">  
  72.             <div class="palm-body-text" x-mojo-loc=''>Wi-Fi is turned off.</div>  
  73.      </div>  
  74. +    <div x-mojo-element="Button" style="display:none;" id="doneButton"></div>  
  75.  </div>  

其实很简单就是增加一个Done的按钮,这个按钮在com.palm.app.wifi启动时,如果带有firstuse这个参数就设置为可见,而这个按钮的用处就是关闭WIFI设置程序。另外,开头还会根据locale参数来设置一下语言。

那现在我们在com.palm.app.firstuse里面再调用它,只要带上这两个参数就可以了。接下来我们可能还希望在刷机第一次启动时,选择语言之前就能进行WIFI配置。最简单的方法当然就是在设置语言的页面里面也调用这个打开WIFI设置程序的方法咯。但如果你真的这样做的话,会发现你并看不到WIFI设置程序。原因是最开始执行时,被放在后面了,只有当它完全启动之后,再调用一次,他才会显示到前面来。但是我们不知道它需要多久才能启动完毕,所以我们设置几个定时器,每隔一段时间调用一次就可以啦:

JavaScript代码
 
  1. --- .orig/usr/palm/applications/com.palm.app.firstuse/app/controllers/language-assistant.js  
  2. +++ /usr/palm/applications/com.palm.app.firstuse/app/controllers/language-assistant.js  
  3. @@ -34,6 +34,7 @@  
  4.           
  5.         // Listen to ## key presses  
  6.         this.controller.listen(this.controller.sceneElement, Mojo.Event.keydown, FirstUseUtil.handleKeyPressEvent.bind(this));  
  7. +       AppAssistant.accountService.enableWifi();  
  8.     },  
  9.       
  10.     powerDownDevice: function () {  
  11. --- .orig/usr/palm/applications/com.palm.app.firstuse/app/controllers/firstuse-util.js  
  12. +++ /usr/palm/applications/com.palm.app.firstuse/app/controllers/firstuse-util.js  
  13. @@ -197,11 +197,13 @@  
  14.         }  
  15.         else{  
  16.             labels = [{label: $L('Emergency call'), command: 'emergency-call'},   
  17. +               {label: $L('Enable WiFi'), command: 'enable-wifi'},  
  18.                 {label: $L('Cancel'), command: 'cancel'}  
  19.                 ];  
  20.             if(FirstUseUtil.customerCareNumber && FirstUseUtil.customerCareNumber.length > 0) {  
  21.                 labels = [{label: $L('Emergency call'), command: 'emergency-call'},   
  22.                     {label: $L('Call customer service'), command: 'customer-care'},  
  23. +                   {label: $L('Enable WiFi'), command: 'enable-wifi'},  
  24.                     {label: $L('Cancel'), command: 'cancel'}  
  25.                 ];  
  26.             }  
  27. @@ -220,6 +222,8 @@  
  28.             Mojo.Log.info("----------------- FirstUseUtil.carrierName ----------------", FirstUseUtil.carrierName());  
  29.             var carrierName = Mojo.Environment.DeviceInfo.carrierName || (FirstUseUtil.carrierString && typeof FirstUseUtil.carrierString === "string" ? FirstUseUtil.carrierString.toUpperCase() : "");  
  30.             AppAssistant.accountService.callCustomerCare(FirstUseUtil.customerCareNumber, $L(carrierName));  
  31. +       } else if (value == "enable-wifi") {  
  32. +           AppAssistant.accountService.enableWifi();  
  33.         } else if(value == "exit"){  
  34.             if (isDemoMode){  
  35.                 new Mojo.Service.Request('palm://com.palm.oddService', {  
  36. --- .orig/usr/palm/applications/com.palm.app.firstuse/app/models/account-service.js  
  37. +++ /usr/palm/applications/com.palm.app.firstuse/app/models/account-service.js  
  38. @@ -408,6 +408,33 @@  
  39.         });  
  40.     },  
  41.       
  42. +   enableWifi: function() {  
  43. +       var method = function() {  
  44. +           return new Mojo.Service.Request("palm://com.palm.applicationManager/open", {  
  45. +               parameters: {  
  46. +                   id: 'com.palm.app.wifi',  
  47. +                   params: {  
  48. +                       "firstuse"true,  
  49. +                       "locale": Account.language + '_' + Account.country  
  50. +                   }  
  51. +               }  
  52. +           });  
  53. +       };  
  54. +       var t1 = setTimeout(function() {  
  55. +           clearTimeout(t1);  
  56. +           method();  
  57. +       }, 8000);  
  58. +       var t2 = setTimeout(function() {  
  59. +           clearTimeout(t2);  
  60. +           method();  
  61. +       }, 4000);  
  62. +       var t3 = setTimeout(function() {  
  63. +           clearTimeout(t3);  
  64. +           method();  
  65. +       }, 2000);  
  66. +       return method();  
  67. +   },  
  68. +  
  69.     makeEmergencyCall: function (emergencyNumber) {  
  70.         Mojo.Log.info("Emegerncy call to phone app -------------------------------------------------: ",emergencyNumber);  
  71.         return new Mojo.Service.Request("palm://com.palm.applicationManager/open", {  

经过这样的修改,我们就可以实现完美的开机WIFI设置了。

上面两段加起来就是WIFI激活的补丁了。我们用这个补丁来替换最开始那个wifi-activation.patch就可以啦。

不过我们还需要作一点小小的工作,那就是要把com.palm.app.wifi这个包的处理部分也要加入到Makefile中,我们可以在Makefile中寻找这段代码:

  1. ifeq (${ADD_EXTRA_CARRIERS},1)  
  2.     OLDIPKGS += pmcarrierdb  
  3. endif  

然后再它前面加入:

  1. ifeq (${WIFI_ACTIVATION},1)  
  2.     OLDIPKGS += com.palm.app.wifi  
  3. endif  

就可以啦,接下来的工作,Makefile就可以正确处理了。

最后我们运行:

make DEVICE=veer CARRIER=att all

就可以生成带有WIFI激活功能的ROM了。

11月
04

WebOS ROM修改工具

工欲善其事,必先利其器。所以,我们要先把用于修改WebOS ROM的工具找好,其实工具不多,下面先列一下这些工具:

  1. Linux(例如Ubuntu或Debian)或Mac OS X
  2. JRE
  3. Palm SDK
  4. MetaDoctor

接下来,我们就有细细讲解了。

Linux或Mac OS X

必须的!

Windows不行,因为后面要介绍的主力工具MetaDoctor不支持Windows,就算在Windows上装了Cygwin也不支持。至于是不是真是这样,我倒没有亲自验证过,www.webos-internals.org上是这样写的。具有科学态度的同学如果有时间,可以自己验证一下。

用Linux的话,它的shell是现成的,定制ROM需要到一些命令和工具在系统装好之后也都有了,比如tar、ar、unzip、make等等。另外,推荐用Ubuntu或Debian。因为就算缺少什么命令没有安装,直接用apt-get或者图形界面的软件包管理器安装就可以啦,非常方便。

用Mac OS X的话,需要把XCode一起安装一下,虽然用不到XCode本身,但需要用到它带的一些开发用的工具。另外,还需要安装MacPorts,它也依赖XCode。所以,用Mac OS X的话,比起用Ubuntu或Debian来还是比较麻烦的。

至于这两个系统怎么用这里就不再详解了,否则就跑题了。

JRE

必须的!

后面介绍的工具需要调用它来完成一些工作。

这个怎么安装,干啥用的也不介绍了。我想用webOS手机的同学应该没有不知道它的。而且资料多的很,就算真的不了解的同学也可以自己去查嘛。我就不再废话了。

Palm SDK

必须的吗?不是。它是webOS的开发包,虽然我们并不是要用它来做开发,但它在我们用于定制ROM的调试过程中会很有用。另外,MetaDoctor中也有调用它的地方,不过也不是在定制ROM的环节上。但我们装了它总没坏处。

MetaDoctor

定制WebOS ROM的主力工具。虽然它只是几个不算怎么长的脚本的集合,但是有了它,可以让你在定制ROM上做到事半功倍,比纯手工打造要方便太多了。当然,它本身内置的脚本并不一定能满足你所有的要求,但你可以扩展修改它,至于怎么扩展修改,我们下一节再举例说明。

现在先介绍它的基本功能。

http://www.webos-internals.org/wiki/Application:MetaDoctor上有关于MetaDoctor的一些英文介绍,大致涵盖了安装,基本运行方法,和一些杂七杂八的东西。所以,这些也不详细讲解了,不过为了保持文章完整性,还是要大体说一下。

安装

很简单。

只有Windows的同学,需要安装一下Linux,推荐是Ubuntu最新版。安装方式上面的英文介绍里说的是用Wubi方式,其实装在虚拟机里也一样用。

然后呢,就是安装git,安装jre,之后用git来把meta-doctor从服务器上下载下来,这样你就有了。

在Mac OS X上也差不多,不过要先安装XCode、再安装MacPorts,再用MacPorts安装md5sha1sum、gnutar、git-core、wget、gpatch这些基本工具,最后也是用git把meta-doctor从服务器上下载下来。

目录结构

从服务器上下载的meta-doctor目录下面有一个Makefile和三个目录。

这个Makefile是定制ROM的最关键的主文件,后面详解其中的关键。先说说那三个目录:

patches目录

这个目录下,保存的是一些补丁。

其中carriers目录下是某些运营商的网络配置的定制文件,doctor目录下是对刷机工具的几个补丁文件。

webos-x.x.x这些目录下面是对具体版本的ROM的一些补丁,自带的里面只有一个bypass-activation的补丁。

这些文件都是供Makefile调用的,如果有需要我们也可以把自己写的补丁放在它下面,然后对Makefile做相应修改之后,我们自己的补丁也就可以用了。

hashes目录

这个目录下,保存的是一些运营商(carriers)和手机制式(models)的散列数据。用于设置自定义ROM的运营商和手机制式用。它们也是供Makefile调用的。

scripts目录

这个目录下保存了很多宝贝脚本。

一部分是供Makefile调用的,一部分是单独使用的,还有一部分是例子。

这里面replace-md5sums.py是供Makefile调用的。

preware-ca-bundle.crt和preware-install.db也是供Makefile调用的,不过已经过时,没啥用了。

decode-hashes是解码刷机文件中recoverytool.config这个文件里面那些运营商、手机制式等Hash值用的工具。

encode-hash是教你如何实现自定义运营商、手机制式等Hash值的编码的一个例子。

unpack-doctor可以帮你把刷机的doctor的jar分解成目录和文件的工具。

unpack-rootfs跟unpack-doctor功能类似,但它只分解rootfs。

WebOS-Internals.tga是Makefile用来替换手机启动时的第一个启动画面的文件。你也可以把它替换掉。

剩下的那些xxx-xxx-1.4.5.1是用来自制某些运营商发布的某些制式的手机的1.4.5.1的刷机ROM的。xxx-xxx-2.1.0当然就是定制2.1.0的刷机ROM的咯。关于这些2.1.0的脚本的使用方法,可以参见:http://www.webos-internals.org/wiki/WebOS_2_Upgrade。因为这不是本文的重点,这里就不做更进一步的介绍了。

Makefile

这个文件才是重点要介绍的。

该文件开头有许多选项,这些是基本功能定制的开关。下面先把这些选项作个简单说明。

BYPASS_ACTIVATION

该选项的功能说明是去掉刷机后第一次启动时的激活过程。而实际上它的作用仅仅是让第一次启动的运营商网络变得无效,以至于无法激活。另外,它还有一个作用就是让机器不检查Sim卡状态。这时,你就是插一张坏卡也能开机,不插卡也能开机。但不能激活你就进不了系统啊。那怎么办呢?

如果是2.x的系统,那好办,可以在紧急拨号界面里,输入#*3386633#来启动开发者模式开关程序,打开开发者模式之后重启,第二次启动就自动进入系统了。

但如果是1.x的系统,那就麻烦了。因为上面的方法对1.x系统不适用啊。那该怎么办呢?

一种办法当然就是我们下一节介绍的WIFI激活。另一种方法则是跳过第一次启动时运行的First Use程序,也就是第二个选项。

BYPASS_FIRST_USE_APP

这个选项做的事情正如上面所说,是跳过第一次启动时运行的First Use程序,如何实现的呢?

他在rootfs(就是ROM的根分区)的/var/luna/preferences下建了两个空文件,一个是ran-first-use,另一个是first-use-profile-created,这样就可以欺骗系统在第一次运行时就认为已经运行过firstuse程序了,所以,第一次运行就进入了桌面。

2.x系统的firstuse程序跟手势教程是同一个,想要激活profile,直接运行手势教程就好了。所以就不存在什么问题。但对于1.x的系统来说,firstuse程序默认是不可见的,所以进入桌面之后,想再激活profile就难了。这一点其实开发meta-doctor的大婶们早就想到了。所以,这个选项做的第二件事情就是将/usr/palm/applications/com.palm.app.firstuse下面的appinfo.json和它的资源目录下所有语言的appinfo.json中的visible选项从false改为true。

所以,一般要实现免激活的ROM,只要打开上面两个选项就好了。

注意:BYPASS_FIRST_USE_APP这个选项在修改程序可见性时,有点小问题。使得它跟1.x的advanced configuration for app laucher这个补丁有冲突,使其无法正确安装。解决方法有很多,比如用户安装advanced configuration for app laucher前先把原始的appinfo.json文件替换回去。或者把Makefile中关于appinfo.json的修改的那一段代码注释掉。更多方法大家可以自己琢磨。

ENABLE_DEVELOPER_MODE

第三个选项是默认打开开发者模式,这样在第一次启动时,WQI就可以跟手机连接啦。这个选项打开是安全的。它的实现也很简单,就是在根分区的/var/gadget目录下建立一个novacom_enabled的空文件。

该选项只对刷机后未运行删除应用程序和数据(或完全清除)前有效。如果日后在系统的“重设选项”中选择了任何上述按钮的话,则该文件也会被清除,这样系统启动时,再次进入First Use界面时,开发者模式就关闭了。

ENABLE_BETA_FEEDS、ENABLE_ALPHA_FEEDS

第四个选项是针对preware的,该选项打开之后,可以允许preware载入测试版本的程序和补丁列表。

这两个选项的实现是在rootfs(根分区)的/var/preferences/org.webosinternals.preware目录下面建立enable-beta-feeds或enable-alpha-feeds这两个空文件。所以它们并不依赖于是否在ROM中集成preware。

INSTALL_SSH_AUTH_KEYS

这个选项不用于定制通用ROM,仅用于定制个人使用的ROM时使用。它的作用是将SSH的authorized_keys文件导入到设备的用户目录下,这样当在设备上安装了ssh监听程序后,就可以直接从自己的电脑上通过ssh来登录到设备上了。

INSTALL_WIFI_PROFILES

这个选项跟上面一样不能用于定制通用ROM,仅用于定制个人使用的ROM。它的作用是让用户刷机之后第一次启动就可以连接上WiFi,这个功能听上去很神奇,但如果你知道该怎么做才能实现时,你就会觉得很没用了。你需要先把现在设备上设置好的WiFi配置文件(/var/preferences/com.palm.wifi/ prefsDB.sl)复制到自己PC(Linux)上,路径是:~/.ssh/com.palm.wifi.prefsDB.sl 或 to ./config/com.palm.wifi.prefsDB.sl,然后开启这个选项后,在运行make时,meta-doctor会把这个文件放到你的ROM中的那个目录下。而每个人的WiFi配置各不相同,所以它不是一个通用的选项。

AUTO_INSTALL_PREWARE

这个选项的本意是系统启动后,自动通过网络安装preware。但很不幸,这个选项已经不好用了。所以你只能在注释中看到它。在下面的主要开关列表部分你并看不到它的身影。所以如果你想实现在ROM中集成preware,不要使用这个选项,后面我会介绍如何集成软件到ROM中。

DISABLE_UPLOAD_DAEMON

这是一个很有用的选项。官方ROM里有个自动上传数据到PALM服务器的功能。这个自动上传数据的功能会在后台悄悄地自动地上传系统或应用程序崩溃的相关调试信息,用户的GPS信息,每个应用程序所使用的数据,以及它们的运行时长。关掉它可以节省大量的流量。

这个选项的实现很简单,就是把/usr/bin下面的uploadd、contextupload、rdxd这三个程序的可执行权限去掉了。这样当你真的需要恢复时,只要改一下权限就好了。所以即使在刷机之后,用同样的方法也可以关闭上传功能。

DISABLE_UPDATE_DAEMON

这个是用来关闭升级服务的。通常用于定制比较旧的,官方不再提供升级的ROM时使用,在定制较新的ROM时,如果开启这个选项,对于不懂下面这段话的用户会影响后续的正常升级。

这个选项的实现跟上面那个选项差不多,它是把/usr/bin目录下的UpdateDaemon和OmaDm这两个程序的可执行权限去掉了。所以如果到时候真的系统真的有升级,用户其实也是可以通过修改这两个文件的权限来恢复升级服务功能的。同样,如果没有开启这个选项,用户在刷机后,也可以用这个方法来关闭升级服务。

DISABLE_MODEM_UPDATE

该选项的作用是禁止刷写设备的MODEM。因为对于同一款手机的同一个版本的ROM来说,MODEM通常是不会单独升级的,只有大版本升级时,MODEM才会有可能升级(例如从1.4.5到2.1),通常忽略MODEM刷写是安全的。而且它可以节省刷机的时间,刷写MODEM时,大约需要4-5分钟,禁止刷写MODEM可以节省将近1/3的刷机时间。不过,要是为了保险的话,这个选项还是不要开启的好。

它的实现方式是修改webOS.tar里面的installer.xml,将其中ModemUpdater开头的这行删除掉。

ENABLE_USB_NETWORKING

该选项的作用是激活USB网络功能。因为这个功能需要电脑上单独安装驱动。所以一般不打开。

它的实现方式是在/var/gadget下建立一个名为usbnet_enabled的空文件。

REMOVE_MODEL_CHECK

该选项的作用是移除手机型号检查。例如将P130UNA的ROM刷到P130UEU的设备上时,可以使用该选项。但你如果把P101UNA刷到P121UNA的设备上时,也是可以使用该选项的,但这真的很有风险,因为没有人可以保证任何两个不同型号的手机的ROM一定会兼容,所以,如果你不知道你在干什么,就不要随便打开这个选项。

这个选项的实现其实很简单,将doctor里面的resources目录下的recoverytool.config文件中的ApprovalMikeHash那一行删除就可以啦。

REMOVE_CARRIER_CHECK

该选项的作用是移除运营商检测。例如你打算将ATT的ROM刷到O2上(当然因为这两个手机的型号也不同,所以你还需要把上面那个选项也打开),你就应该打开这个选项。不过它会带来很多副作用,因为开启这个选项之后,刷机时将不会为你安装运营商提供的系统级的ipk,而这些ipk有几个还是相当重要的,完全忽略安装的情况下,你会得到一个很纯的系统,而这个很纯的系统还会有些功能上的缺失,例如壁纸、铃声设置不能保存,应用商店可能无法使用,也无法升级程序等等。所以,通常我们也不会打开这个选项。要实现刷写其它运营商更高版本的ROM,我们其实还有更好的方法。

这个选项的实现比上面的选项稍微复杂些,除了将doctor里面的resources目录下的recoverytool.config文件中的ApprovalCharlieHash和CustomizationBuild这两行删除外,对正常的关于运营商提供的安装包的操作也都忽略不做了。这个功能其实没啥用,所以就不做更详细解释了。如果大家感兴趣,还是自己读代码吧。

CHANGE_KEYBOARD_TYPE

这个选项很有用,主要用于给德国键盘、法国键盘的手机替换为正键键盘时制作ROM使用。它有三个选项,z表示QWERTY键盘,y或者y1表示QWERTZ键盘,w1表示AZERTY键盘。

它是通过修改webOS.tar中的intaller.xml以外的另一个xml文件实现的,那个文件的名字对于不同的手机有所差别。它是在这个文件的tokens这个段中,插入<Val name="KEYoBRD" action="overwrite" value="${CHANGE_KEYBOARD_TYPE}"/>这个选项来实现的,其中${CHANGE_KEYBOARD_TYPE}就是上面列出的三个选项值。

ADD_EXTRA_CARRIERS

这个选项是用来增加运营商网络配置信息的,还记得上面提到的patches/carriers目录吗?

这个选项就是将这个目录中的文件信息都加到根分区的/etc/carrierdb/carrierdb.json文件中,这样就可以实现自定义网络运营商的网络参数了。虽然这个选项的注释中说仅对2.0.0系统有效,其实是对2.0.0及其以上的版本都有效。只不过我们用不到,因为中国移动、中国联通和中国电信这三大运营商的配置早就写在这个配置文件里了。根本不需要我们去添加,这也是我们为什么拿到手机,插卡就能上网的主要原因。

VAR_PARTITION_SIZE

该选项可以让你更改/var分区的大小。这个分区用于保存一些用户数据,不过它下面还有几个目录实际上也是独立的分区都有自己固定的大小,单纯扩大/var分区不能够改变那些目录的空间大小,比如/var/log,/var/db,/var/file-cache等。

该选项的实现也是通过修改webOS.tar中的那个xml文件实现的。

SWAP_PARTITION_SIZE

该选项可以让你更改交换分区的大小。实现方式同上。

EXT3FS_PARTITION_SIZE

该选项可以增加一个/media/ext3fs的分区。安装ubuntu、debian、android到webOS中时,创建这样一个分区可以让系统更快速稳定一些(跟没有创建这个分区时比,不是跟没有安装上述系统时比)。实现方式同上。

总结

上面的修改中,有些修改涉及到根分区下的文件,这些文件中有些不属于某个包(ipk),添加之后只需要计算它的md5值,然后将该值增加到根分区根目录下的md5sum.tar中就可以啦。而有些文件是属于某个包的,对这些文件,在修改之后除了需要重新计算md5值,并将它写入根分区下的md5sum.tar中以外,还需要将该值写入到该包的md5sum校验文件中。另外,因为它所在包的md5sum校验文件也被修改过,因此它所在的包的md5sum校验文件也要重新计算md5值,并写入根分区总的md5sum校验文件包中。如果要在包中增加或删除文件,过程要更复杂,除了修改md5文件,还需要修改list文件和更新list文件的md5值。这个过程不但看上去非常复杂,手动作起来也确实繁琐,好在meta-doctor都帮我们做好了。所以我们借助meta-doctor这个工具,比我们纯手工修改定制ROM还是要方便的多的。

但是对recoverytool.config,webOS.tar下的两个xml文件的修改,手工修改可能比用meta-doctor更方便灵活一些。但手工修改难免会出错,所以风险也要大一些。修改ROM是个细心的活,一定要小心再小心。

meta-doctor的功能远不止上面介绍的这么点。其实它还提供了好多的选项让你更细化的对ROM做定制,只是这些选项并没有列在Makefile头顶的列表里罢了。如果你仔细读源码,你会发现很多有趣且有用的选项。另外,如果现有的功能真的不够用,你也可以通过修改Makefile来自己添加新的选项予以扩展。下一节我们就来讲如何通过修改meta-doctor来实现WIFI激活的功能。

11月
04

WebOS ROM修改入门教程

 我的Veer终于到了,其实这个是给我老婆买的,这样我是黑色的pixi plus,她用白色的veer,正好配一对。

当然原始的Veer ROM里面有很多的垃圾软件和垃圾信息,俺不喜欢,所以必须去掉。而且俺老婆的Sim卡是移动神州行,没有开通GPRS,但家里有Wifi,所以必须要支持Wifi激活Profile才行。所以,特此定制了这个ROM。

还是先介绍一下该 ROM 的特点吧:

  1. 删掉了amazonservice,attwisprd,com.palm.app.amazonstore,com.palm.app.attsyncpanel,com.palm.app.minidm,com.palm.app.mobilehotspot,com.palm.attaddresssync,com.telenav.attnavigation,com.yellowpages.ypmobile.preload,contacts.plugin.pmvoicecommand,minidm,pmvoicecommand-enus,pmvoicecommand-esmx,pmvoicecommand这些 att 的定制包。
  2. 对 sweatshop-attwireless-broadway 做了修改:
    • 删除了att的客服电话。
    • 删除了att的电话号码。
    • 删除了att在浏览器中加入的书签。
    • 删除了在音乐中加入的amazon市场按钮。
    • 删除了上面步骤1中删除的包的桌面布局。
    • 关闭了语音拨号。
    • 在激活页面时打开了WIFI。
    • 其它几个记不太清的小的修改。
  3. 刷机后第一次启动自动开启WIFI配置,打开WIFI之后,再选择语言(只有英语可选)可以免发国际短信(节省1块钱)。手机激活后,可以通过WIFI来激活或注册profile。另外,在激活页面中也有开启WIFI选项卡的功能。
  4. 关闭了自动数据上传功能。这个自动上传功能会在后台悄悄地自动地上传系统或应用程序崩溃的相关调试信息,用户的GPS信息,每个应用程序所使用的数据,以及它们的运行时长。关掉它可以节省大量的流量。据很多人说,他们使用Veer后,一旦打开2G或3G,每天甚至每小时都有大量的数据通讯,应该就是系统自带的这个功能造成的,现在关闭了,应该就好了。

大概的修改就这么多,在优化的同时仍然保持了系统的原汁原味。

下载地址:/webos/veer/webosdoctorp160unaatt-2.1.2.jar

 

10月24日更新:

修复了手势教程不能打开的问题。

除了可用WIFI激活,GSM也可以激活了。 

关闭了系统更新,再也不会被系统更新打扰了。

必须插卡才能激活(但是开始可以配置WIFI,免发1元国际短信)。

可选择多国语言。

 

10月26、27日更新:

对网络运营商(中国移动、中国联通、中国电信)标识进行了汉化,在中文下自动显示中文,英文下还是显示英文。当然veer不支持中国电信,所以你可能没机会看到这个标识。

删除了内置的Google地图,因为它不支持中国地区。现在刷机完毕之后可以从HP App Catalog中查找Map,有个HP的Bing地图,这个是支持中国的,并且内置中文,而且安装之后,你的veer就有了Enyo框架了。删除的Google地图可以在此下载:http://bbs.zoopda.com/thread-94913-1-1.html

默认开启了开发者模式,刷机之后就可以马上使用WQI用电脑连手机装软件了,不需要用咒语开启开发者模式了。

将中日韩文的字体替换为了最新的android 4.0的Droid Sans FallBack字体,这个字体比旧的android字体体积大一点点,有5M,但是效果却比旧的android字体效果好。而且简体中文、繁体中文、韩文、日文这四种字体都使用这个字体,并且用的是硬链接方式,所以虽然你看到有4个文件,其实只占一份空间。

删除了烦人、无用且乱码的 STK 程序。删除的 STK 程序可以在此下载:http://115.com/file/cl7ik95p#com.palm.app.stk_1.0-64_armv7.ipk有需要的同学,单独安装就可以用了,不想用了还可以卸载掉。

 

10月29日更新:

1、任意方式下激活(GPRS/EDGE,3G,WIFI)都免发国际短信,我现在终于不纠结了。

2、中文下有完美的手势教程。

3、更完美的细节汉化(波浪乱码仍然无法解决,没找到可以修改的地方)。

4、集成了Preware 1.8.3官方版本(带中文),可升级,防卸载(实在想卸载也可以用命令行操作,但这个应该说是必装软件,你真的会卸载吗?)。以后刷完机装软件,不需要WQI了。

5、集成了Diffstat、GNU Patch、Lsdiff、UnZip、Zip这五个装补丁之前必装的软件,以后不用担心装以前下载好的补丁缺少依赖无法安装的问题了。

6、App Catalog 内置的是 2.0.23300 版本,比之前自动更新的版本还要新,这个版本是从pre3里面提取出来的,经测试,完美支持Veer。

7、提供了集成软件的新方式(其实是在2.x自带的集成软件方式基础上作了修改,增加了对postinst脚本的支持),基于这个ROM,你可以轻松制作集成版了。

8、不再显示SIM卡联系人。激活后,SIM卡显示的号码是:460004433591831,而不是你的手机号(这也是免发国际短信的关键)。但不影响电话、短信等功能。有同学说他的还是原来的号码,有两个可能,一是原来注册的没删掉,旧的就会保留,二是可能手机卡不同效果也不同,我是动感地带,刷前一个版本时用的是神州行,刷完之后,帐号里显示2个手机卡,一个是旧的神州行,另一个是这个460004433591831,如果你的刷完不变,应该就是你没换卡,显示的就是旧的。

9、免刷MODEM,免查MODEL,刷机速度更快,大约10分钟就可以刷好(不包括重启时间)。

 

 11月1日更新:

1、去掉了29日更新的第9条,因为它会引起某些机器激活之后无法重启,或者强制重启之后启动不了。现在不会出现刷机之后不能重启的问题了。

2、集成了enyo框架,来自pre3的ROM,以后可以装enyo的程序了。

3、字体换成了Arial Unicode MS,可显示简、繁、日、韩、阿拉伯等国文字。官方的字体和Android字体均不能显示阿拉伯文。

4、在高级大厨jarryson的完美汉化包的基础上做了一些很小的修改,并重新打包为可卸载语言包(App Catalog 我还是没汉化)。感谢jarryson和最初提供汉化包的elite大神们为汉化所做的工作。

5、更正上一个版本的说明,SIM卡卡号虽然在帐号里不一定能看到(有些同学能看到),但Sim卡联系人仍然可以正常访问。也就是说功能跟原版一样。如果不想显示SIM卡联系人,可能只有清空SIM卡了(我不是开玩笑,我本人就是这么干的)。

 

11月6日更新:

 

1、完美的,不同于任何其它ROM的,任意环境下激活,都免发国际短信(过几天放出方法,正在整理成文)。

2、完全修复刷机之后设置完成最后一步转圈圈的问题(所有情况均已亲测)。

3、集成了最新的preware 1.8.5。一是为了提供一个安装软件的基础环境,二是为了提供一个基础的集成软件的例子(过几天放出方法)。

4、集成了Homebrew JS Service Framework 1.0.1,FileMgr 2.0.7,Internalz Pro 1.5.0。一是为了提供一个文件管理器。二是提供一个集成多个具有依赖,具有服务的软件集成的例子(过几天放出方法)。

5、集成了Unthrottle Download Manager补丁(这个补丁是用来解除下载限制的,该补丁没有任何副作用),集成这个仅是为了提供一个集成补丁的例子,该补丁可卸载,通过该方法集成其它本来可以卸载的补丁均可卸载(过几天放出方法)。

6、集成了jarryson提供的带有iphone UserAgent的libWebKitLuna.so,可以方便浏览针对iphone优化的3G网站,还可以继续使用Google maps了,详细描述请参见jarryson大大的帖子:http://bbs.zoopda.com/thread-97790-1-1.html。

 

可卸载的中文包:/webos/veer/com.palm.veer.languagepack.zh-cn_2.1.2-6_all.ipk