2013-11-25

Android 4.4 WebView / Stock Browser

Androidのソースコードを先ほど同期したら、いろいろ変わってた。

external/webkitがめでたく4.4から削除されてた。そしてwebview自体Chromium/Blinkベースのものに変更。

標準ブラウザ自体のコードは、未だにpackages/apps/Browserに存在する。これはWebViewClassicを使わないのでそのままBlinkが使われると。

なので標準ブラウザは未だにOEMが選択可能ではある (WebViewがそのまま使えるんで)。でもchromium portベースになるんだから標準ブラウザと言っても今までよりマシなんじゃない? あと各OEMのカスタマイズはWebKitからBlinkに変わったからいろいろ変わって大変そうだね (WebKitとして考えてもAndroid portからChromium portに変わったからということでね)

PackageManager使ってWebViewをデバイス組み込みのもの使うとかインストールしたもの(Chrome経由)使うとかの選択肢を作るかと思ったら入れなかったところが、今後のWork Itemなんだろうなと。

2013-11-22

ATOK 2013をWindows 8.1で使うと仮想マシン接続が終了時にハングアップする

最近Hyper-Vクライアントを試しに使っているのだが、終了時にハングアップするんでちょっとだけ困ってる。

でなんでハングしてんだろと思って軽く見てみた。

メインスレッドの状況。mstscatかな?原因は。

0:016> ~0k
Child-SP          RetAddr           Call Site
000000d5`aa80b778 00007ffb`93431148 ntdll!NtWaitForSingleObject+0xa
000000d5`aa80b780 00007ffb`69814e92 KERNELBASE!WaitForSingleObjectEx+0x94
000000d5`aa80b820 00007ffb`69819ce4 mstscax!DllUnregisterServer+0x166726
000000d5`aa80b850 00007ffb`69aa5205 mstscax!DllUnregisterServer+0x16b578
000000d5`aa80b890 00007ffb`69aa2bbf mstscax!DllUnregisterServer+0x3f6a99
000000d5`aa80b930 00007ffb`699bfaed mstscax!DllUnregisterServer+0x3f4453
000000d5`aa80b980 00007ffb`699b7d68 mstscax!DllUnregisterServer+0x311381
000000d5`aa80b9e0 00007ffb`698b756c mstscax!DllUnregisterServer+0x3095fc
000000d5`aa80ba20 00007ffb`698a8715 mstscax!DllUnregisterServer+0x208e00
000000d5`aa80ba80 00007ffb`698aac69 mstscax!DllUnregisterServer+0x1f9fa9
000000d5`aa80bb00 00007ffb`93fe2524 mstscax!DllUnregisterServer+0x1fc4fd
000000d5`aa80bb90 00007ffb`93fe6773 USER32!UserCallWinProcCheckWow+0x140
000000d5`aa80bc50 00007ffb`776c52cb USER32!CallWindowProcW+0x93
000000d5`aa80bcb0 00007ffb`776bfeb6 System_Windows_Forms_ni+0x9052cb
000000d5`aa80bde0 00007ffb`77031e63 System_Windows_Forms_ni+0x8ffeb6
000000d5`aa80beb0 00007ffb`77651447 System_Windows_Forms_ni+0x271e63
000000d5`aa80bf80 00007ffb`7cba3ebe System_Windows_Forms_ni+0x891447
000000d5`aa80c010 00007ffb`93fe2524 clr!UMThunkStub+0x6e
000000d5`aa80c0a0 00007ffb`93fe3812 USER32!UserCallWinProcCheckWow+0x140
000000d5`aa80c160 00007ffb`93fe38cd USER32!DispatchClientMessage+0xa2
000000d5`aa80c1c0 00007ffb`9609838f USER32!_fnDWORD+0x2d
000000d5`aa80c220 00007ffb`93fe129a ntdll!KiUserCallbackDispatcherContinue
000000d5`aa80c2a8 00007ffb`698a6701 USER32!NtUserDestroyWindow+0xa
000000d5`aa80c2b0 00007ffb`77635883 mstscax!DllUnregisterServer+0x1f7f95
000000d5`aa80c2e0 00007ffb`776c328f System_Windows_Forms_ni+0x875883
000000d5`aa80c3e0 00007ffb`776c2c91 System_Windows_Forms_ni+0x90328f
000000d5`aa80c440 00007ffb`776c024e System_Windows_Forms_ni+0x902c91
000000d5`aa80c4a0 00007ffb`78e11cf8 System_Windows_Forms_ni+0x90024e
000000d5`aa80c4e0 00007ffb`802950fa System_ni+0x291cf8
000000d5`aa80c510 00007ffb`80296d32 vmconnect_ni!COM+_Entry_Point <PERF> (vmconnect_ni+0xc50fa)
000000d5`aa80c5a0 00007ffb`7cb84113 vmconnect_ni!COM+_Entry_Point <PERF> (vmconnect_ni+0xc6d32)
000000d5`aa80c670 00007ffb`7cb83fde clr!CallDescrWorkerInternal+0x83
000000d5`aa80c6b0 00007ffb`7caeee66 clr!CallDescrWorkerWithHandler+0x4a
000000d5`aa80c6f0 00007ffb`7caeeba6 clr!CallDescrWorkerReflectionWrapper+0x1a
000000d5`aa80c740 00007ffb`79c76bac clr!RuntimeMethodHandle::InvokeMethod+0x46a
000000d5`aa80cd40 00007ffb`79c7f3b3 mscorlib_ni+0x486bac
000000d5`aa80cdb0 00007ffb`7cb84113 mscorlib_ni+0x48f3b3
000000d5`aa80ce30 00007ffb`7cb83fde clr!CallDescrWorkerInternal+0x83
000000d5`aa80ce80 00007ffb`7cb889a3 clr!CallDescrWorkerWithHandler+0x4a
000000d5`aa80cec0 00007ffb`7cc53a2e clr!MethodDescCallSite::CallTargetWorker+0x251
000000d5`aa80d080 00007ffb`7cc53596 clr!DispatchInfo::InvokeMemberWorker+0xebe
000000d5`aa80dc30 00007ffb`7cc5332f clr!DispatchInfo::InvokeMemberDebuggerWrapper+0x1c6
000000d5`aa80dd90 00007ffb`7cc52f02 clr!DispatchInfo::InvokeMember+0x461
000000d5`aa80e080 00007ffb`7cc52d6c clr!InternalDispatchImpl_Invoke+0x1ed
000000d5`aa80e1a0 00007ffb`7cc52cae clr!InternalDispatchImpl_Invoke_CallBack+0xb2
000000d5`aa80e200 00007ffb`698af574 clr!InternalDispatchImpl_Invoke_Wrapper+0xf8
000000d5`aa80e2a0 00007ffb`698af771 mstscax!DllUnregisterServer+0x200e08
000000d5`aa80e350 00007ffb`698b27ff mstscax!DllUnregisterServer+0x201005
000000d5`aa80e3a0 00007ffb`699c2f26 mstscax!DllUnregisterServer+0x204093
000000d5`aa80e420 00007ffb`69aa37b5 mstscax!DllUnregisterServer+0x3147ba
000000d5`aa80e450 00007ffb`69aa3fbf mstscax!DllUnregisterServer+0x3f5049
000000d5`aa80e480 00007ffb`69aa3d70 mstscax!DllUnregisterServer+0x3f5853
000000d5`aa80e4e0 00007ffb`69aa388a mstscax!DllUnregisterServer+0x3f5604
000000d5`aa80e540 00007ffb`69aa38dd mstscax!DllUnregisterServer+0x3f511e
000000d5`aa80e580 00007ffb`696e3f05 mstscax!DllUnregisterServer+0x3f5171
000000d5`aa80e5b0 00007ffb`93fe2524 mstscax!DllUnregisterServer+0x35799
000000d5`aa80e5e0 00007ffb`93fe2387 USER32!UserCallWinProcCheckWow+0x140
000000d5`aa80e6a0 00007ffb`770c7170 USER32!DispatchMessageWorker+0x1a7
000000d5`aa80e720 00007ffb`7704b1a1 System_Windows_Forms_ni+0x307170
000000d5`aa80e7f0 00007ffb`7704a97f System_Windows_Forms_ni+0x28b1a1
000000d5`aa80e9f0 00007ffb`7704a33f System_Windows_Forms_ni+0x28a97f
000000d5`aa80eb40 00007ffb`802ab599 System_Windows_Forms_ni+0x28a33f
000000d5`aa80ebd0 00007ffb`7cb84113 vmconnect_ni!COM+_Entry_Point <PERF> (vmconnect_ni+0xdb599)
000000d5`aa80ed30 00007ffb`7cb83fde clr!CallDescrWorkerInternal+0x83
000000d5`aa80ed70 00007ffb`7cb889a3 clr!CallDescrWorkerWithHandler+0x4a
000000d5`aa80edb0 00007ffb`7cc591aa clr!MethodDescCallSite::CallTargetWorker+0x251
000000d5`aa80ef60 00007ffb`7cc5999a clr!RunMain+0x1e7
000000d5`aa80f140 00007ffb`7cc59893 clr!Assembly::ExecuteMainMethod+0xb6
000000d5`aa80f430 00007ffb`7cc59372 clr!SystemDomain::ExecuteMainMethod+0x506
000000d5`aa80fa40 00007ffb`7cc592c6 clr!ExecuteEXE+0x3f
000000d5`aa80fab0 00007ffb`7cc59d84 clr!_CorExeMainInternal+0xae
000000d5`aa80fb40 00007ffb`7e487ced clr!CorExeMain+0x14
000000d5`aa80fb80 00007ffb`84ebea5b mscoreei!CorExeMain+0xe0
000000d5`aa80fbd0 00007ffb`95e815cd MSCOREE!CorExeMain_Exported+0xcb
000000d5`aa80fc00 00007ffb`960743d1 KERNEL32!BaseThreadInitThunk+0xd
000000d5`aa80fc30 00000000`00000000 ntdll!RtlUserThreadStart+0x1d

ということでmstscax.dllが何者かというと

0:016> lmvm mstscax
start             end                 module name
00007ffb`695f0000 00007ffb`69c52000   mstscax    (export symbols)       C:\WINDO
WS\system32\mstscax.dll
    Loaded symbol image file: C:\WINDOWS\system32\mstscax.dll
    Image path: C:\WINDOWS\system32\mstscax.dll
    Image name: mstscax.dll
    Timestamp:        Sat Oct 05 16:36:30 2013 (524FC17E)
    CheckSum:         0066305A
    ImageSize:        00662000
    File version:     6.3.9600.16421
    Product version:  6.3.9600.16421
    File flags:       0 (Mask 3F)
    File OS:          40004 NT Win32
    File type:        1.0 App
    File date:        00000000.00000000
    Translations:     0409.04b0
    CompanyName:      Microsoft Corporation
    ProductName:      MicrosoftR WindowsR Operating System
    InternalName:     mstscax.dll
    OriginalFilename: mstscax.dll
    ProductVersion:   6.3.9600.16421
    FileVersion:      6.3.9600.16421 (winblue_gdr.131004-2100)
    FileDescription:  Remote Desktop Services ActiveX Client
    LegalCopyright:   c Microsoft Corporation. All rights reserved.

Hyper-Vクライアントで使ってるモジュールすね (RDPのやつ)

ハングアップはこのメインスレッド上のウィンドウプロシージャ上でこのActiveXコントロールへの呼び出しが帰ってこないからってことが原因。ただ、たぶんこれが待ってるイベントオブジェクトがなんだって話なんだけど、

0:016> ~9k
Child-SP          RetAddr           Call Site
000000d5`ce28cda8 00007ffb`934312ee ntdll!NtWaitForMultipleObjects+0xa
000000d5`ce28cdb0 00007ffb`93fe2a7f KERNELBASE!WaitForMultipleObjectsEx+0xe1
000000d5`ce28d090 00007ffb`93c81506 USER32!MsgWaitForMultipleObjectsEx+0x13f
000000d5`ce28d140 00007ffb`93caefae combase!CCliModalLoop::BlockFn+0x12a
000000d5`ce28d1a0 00007ffb`93de5cc0 combase!ClassicSTAThreadDispatchCrossApartmentCall+0x1de
000000d5`ce28d210 00007ffb`93c7e930 combase!CRpcChannelBuffer::SendReceive2+0x656
000000d5`ce28d450 00007ffb`93de27a7 combase!CCtxComChnl::SendReceive+0x2e0
000000d5`ce28d630 00007ffb`93c3bf3d combase!NdrExtpProxySendReceive+0x47
000000d5`ce28d660 00007ffb`93de1d2b RPCRT4!NdrpClientCall3+0x374
000000d5`ce28da20 00007ffb`93c71b22 combase!ObjectStublessClient+0x12b
000000d5`ce28dda0 00007ffb`93caf27c combase!ObjectStubless+0x42
000000d5`ce28ddf0 00007ffb`93caf33e combase!CStdMarshal::RemoteAddRef+0xe8
000000d5`ce28de80 00007ffb`93cb6db7 combase!CStdMarshal::ConnectCliIPIDEntry+0xb0d
000000d5`ce28df50 00007ffb`93cb4cf2 combase!CStdMarshal::UnmarshalIPID+0x2f3
000000d5`ce28e050 00007ffb`93cb4f9f combase!CStdMarshal::UnmarshalObjRef+0x142
000000d5`ce28e120 00007ffb`93cb901e combase!UnmarshalObjRef+0x136
000000d5`ce28e1a0 00007ffb`87a4f879 combase!_CoUnmarshalInterface+0xc2
000000d5`ce28e280 00007ffb`87a5290f twinapi_appcore!ValidateStreamAndUnmarshalInterface+0x9d
000000d5`ce28e340 00007ffb`8862cfff twinapi_appcore!CoreQueryWindowService+0x34f
000000d5`ce28e3f0 00007ffb`88632f92 twinapi!CInputPaneEventSource_GetInstance+0x2b
000000d5`ce28e420 00000000`67df484e twinapi!CImmersiveFrameworkInputPane::Unadvise+0xaa
000000d5`ce28e470 00000000`67df48c4 ATOK26TIP!DllInstall+0x13841e
000000d5`ce28e4b0 00000000`67cbee7f ATOK26TIP!DllInstall+0x138494
000000d5`ce28e4e0 00007ffb`95c024cd ATOK26TIP!DllInstall+0x2a4f
000000d5`ce28e520 00007ffb`95c023fb MSCTF!CThreadInputMgr::_DeactivateTip+0xc9
000000d5`ce28e600 00007ffb`95c022b7 MSCTF!CThreadInputMgr::ActivateInputProfile+0x363
000000d5`ce28e6c0 00007ffb`95c02196 MSCTF!CThreadInputMgr::OnCleanupContextsEnded+0xaf
000000d5`ce28e740 00007ffb`95c02159 MSCTF!CCleanupShared::`scalar deleting destructor'+0x26
000000d5`ce28e770 00007ffb`95bff6c5 MSCTF!CCleanupShared::_Release+0x19
000000d5`ce28e7a0 00007ffb`95bfdbc4 MSCTF!CThreadInputMgr::_CleanupContexts+0xd5
000000d5`ce28e7e0 00007ffb`95bfdacf MSCTF!CThreadInputMgr::Suspend+0x74
000000d5`ce28e810 00007ffb`95c00054 MSCTF!CThreadInputMgr::OnActivationChange+0xc6
000000d5`ce28e8a0 00007ffb`95c0123a MSCTF!CThreadInputMgr::Deactivate+0x54
000000d5`ce28e8f0 00007ffb`95c01e81 MSCTF!CicBridge::DeactivateIMMX+0x9b
000000d5`ce28e940 00007ffb`95c01de0 MSCTF!_CtfImeDestroyThreadMgr+0x79
000000d5`ce28e970 00007ffb`95fc43a8 MSCTF!CtfImeDestroyThreadMgr+0x30
000000d5`ce28e9a0 00007ffb`95c01efd IMM32!ActivateOrDeactivateTIM+0x64
000000d5`ce28e9d0 00007ffb`93fe485d MSCTF!TF_Notify+0x207
000000d5`ce28f190 00007ffb`93fe3a85 USER32!CtfHookProcWorker+0x19
000000d5`ce28f1c0 00007ffb`93fe99b2 USER32!CallHookWithSEH+0x25
000000d5`ce28f200 00007ffb`9609838f USER32!_fnHkINDWORD+0x1e
000000d5`ce28f250 00007ffb`93fe129a ntdll!KiUserCallbackDispatcherContinue
000000d5`ce28f2d8 00007ffb`6983593b USER32!NtUserDestroyWindow+0xa
000000d5`ce28f2e0 00007ffb`699bfdbd mstscax!DllUnregisterServer+0x1871cf
000000d5`ce28f320 00007ffb`69aa37b5 mstscax!DllUnregisterServer+0x311651
000000d5`ce28f3a0 00007ffb`69aa3fbf mstscax!DllUnregisterServer+0x3f5049
000000d5`ce28f3d0 00007ffb`69aa3d70 mstscax!DllUnregisterServer+0x3f5853
000000d5`ce28f430 00007ffb`69aa5406 mstscax!DllUnregisterServer+0x3f5604
000000d5`ce28f490 00007ffb`69aa5626 mstscax!DllUnregisterServer+0x3f6c9a
000000d5`ce28f4f0 00007ffb`69aa4c38 mstscax!DllUnregisterServer+0x3f6eba
000000d5`ce28f750 00007ffb`699c5454 mstscax!DllUnregisterServer+0x3f64cc
000000d5`ce28f790 00007ffb`69aa4806 mstscax!DllUnregisterServer+0x316ce8
000000d5`ce28f7f0 00007ffb`698157ed mstscax!DllUnregisterServer+0x3f609a
000000d5`ce28f850 00007ffb`95e815cd mstscax!DllUnregisterServer+0x167081
000000d5`ce28f880 00007ffb`960743d1 KERNEL32!BaseThreadInitThunk+0xd
000000d5`ce28f8b0 00000000`00000000 ntdll!RtlUserThreadStart+0x1d

これがおそらく待ってるスレッド。TSF/CiceroのDeactiveTIPから呼ばれたATOKがUnadvise呼ぶんだけど、こいつがTSFが抱えてるCOMオブジェクトを破棄する際にマーシャラー経由 (別スレッドがオーナーかな?。おそらくメインスレッド) で破棄しようとするんだけど、メインスレッドがこのスレッド待ってるから固まってる。

解決方法はATOK使うの止めろってことか、VMWareに戻せってことですね。ATOK側がUnadviseの呼び方変更すれば直る気がするけどさ。

結局のところCOMを使う時によくあるデッドロックの事例だった。

2013-11-01

WebView Hell

現在の(ちゃんと開発されている)OSってのは、だいたいが組み込みのHTMLレンダリングエンジンを持っていたりする。こういう流れは、Internet Explorer 3以降やAppleのCyberDog (誰も知らないと思うけど) が最初だと記憶してるけどね。iOSのおかげでWebViewという表現がよく使われるのでWebViewって言葉を使って書いてる。

Trident

独禁法の裁判でもOSなのかアプリなのかという点で争ったこともあるけど、現在の判断だとOSという判断で差し控えないと思う。Internet Explorer 4にShell Update (Active Desktopと呼んでたけど) が含まれていた関係上シェルの動作に支障がきたすことがあったが、このShell Updateをインストールしなかったとしてもいろんな問題が生じてた。

例えばOS初回起動時に表示される"ようこそ画面"はHTMLで書かれてて、HTML Component (HTC)を使って動いていたのだけど、これがInternet Explorerのバージョンアップでスクリプトエラーになるとか、OS側でWebViewを使ってるコードは結構問題を引き起こしてた。(Windows 2000以降のExplorerのビューもHTML使っててみたいな話があってだな、動作が変わってしまう機能が存在してた)

OSとWeb Browserは切り離してバージョンアップ可能な仕組みを持ってたのにも関わらず、OSモジュールとしてメンテナンスされている古いバージョンのモジュールを残す仕組みを持っていないためにいろんな問題を引き起こしてた。Windows XP移行は Side-by-Side (SxS) が導入されているので古いバージョンのモジュールを残すことはできるようにはなったけど、Internet Explorerはいまだにこれを利用してない (はず)。

その変わりといってはなんだけど、Shellに関するモジュールだけはInternet Explorer 7以降ではアップデートしないような構造にはなった (IEFRAME.DLLというバカでかいモジュールがその役目)。

レンダリングエンジンが変わってしまうってところに関しては解消されなかったけどね。

そんな感じでOS内蔵のレンダリングエンジンをOSとは別にアップデート可能にするといろんな問題を引き起こすのをMicrosoftは証明したわけだ。

Chrome + blink

Android上で利用できるWebViewはシステム組み込みのものを利用することになっている。これがAndroid 4.4からは独自WebKitベースのものからChromeのBlinkベースに変わりはするけども同じような問題を持つ。標準ブラウザがChromeになるっぽいってことからこれで非互換からおさらばできるって考えてる人が結構いるみたいなんだけど、それは無理だと思う。それはChromeのバージョンアップがシステムのWebViewのバージョンアップを含めることができるかどうかなんだ。

そもそもアプリケーションパッケージのインストール機構でOSのファイルを置換できる仕組みをGoogleは取らないだろうし、一つのアプリケーション (この例でいえばChrome) のバージョンアップでシステムのフラッシュに入ってるモジュールを置換できるような方式をとることができることを許すとなれば、それはある種の脱獄の穴を作ることになる。Playストアからアップデートさせるんじゃなくて、6週間ごとに新バージョンのChromeを含む新しいシステムアップデートが全端末にOTAされるとかって方式になるんだったら、その限りではないけどね!。

また一番重要なのはシステムのWebViewはChromeベースになったとしてもその使ってるコードはおそらくベンダがカスタマイズしたコードでしかなくなる。そのカスタマイズさがフラグメントの理由になるんだ。しかもApache 2とかBSDライセンスだと変更点は公開する必要がないから変更点はベンダしか知らないからブラックボックスでしかない。しかも独自のバグがあってもそれはGoogleがやったことではないからGoogleが直せないんだ。

だからハッピーになるかと言えば、まぁならないんじゃないかな?。回避策はえっと、Android認証のテストツールにBlinkのテストツールをすべてパスするようなことを要求するしかないんじゃない?そうすればマシになると思うよ。

Firefox OS

OSとブラウザが完全統合されている場合で一番いい例がFirefox OSになると思うからそこも最後に書く。

個人的にはFirefox OSはフラグメントはAndroidほどひどいものは起きないと予測してる。なぜかというとGecko部分のソースコードはMPL2ライセンスであるってこと。MPL2だとソースコードの変更点は要求があれば公開しないといけない。各ベンダでカスタマイズってのは今後起きるとは思うけど、変更点がわかる以上ブラックボックス化しないから、どうにか対処可能じゃないかと。

もちろんフラグメントは起きるだろうけど、Androidほどはひどくならないんじゃないかな。まぁ今後はどうなるかは興味ある。