[Memo] 兩年之後

Image Credit

two-years-later

時間過的超快,2015 年的七月也過了一半了,在離開 Mozilla Taiwan 半個月後,覺得要好好寫一篇文章記錄這段兩年的旅程。

還記得兩年前,在剛離開前前公司 Trend Micro 後(現在 Mozilla 已經變成前公司了 xDD),再次陷入了找工作的轟炸期,當時還特別寫了一篇文章記錄那幾個月的心境還有過程,在經過各大公司、團隊的連環面試後,意外的拿到很多間公司給的 offer,其中最感謝的就是讓我來到 Mozilla 的主管 – Timdream,沒有因為我只有 10 個月短短的經歷就刷掉我,讓我加入這個大家庭和每位強者同事學習很多東西,除了技術上的成長之外,也因為公司是跨國的公司,所以很多時候要和外國人還有自己 team 的人一起討論事情,雖然英文還是有待加強,不過也讓我在團隊合作這件事情上面學了很多呀。

在 Mozilla 的這段時間,去了很多國家、城市, 最讓我印象深刻的就是在剛進去的時候,剛好遇到三年(還兩年)一次的 Summit 大會,第一次看到規模如此大的會議(全世界的 Mozilla 員工還有 Contributors)、第一次去了美國的 Portland、第一次和同事出國旅遊。這次的會議真的讓我感受到西方國家的人對於工作還有生活的態度,雖然工作重要,但是工作後的玩樂還有 party 也是不能少的,該放鬆的時候就一定要放鬆,玩的比大家都還要 High 呀。

portland-1

portland-2

portland-3

從 Summit 回來之後不知道過了多久,因為職務調動的關係就被分配到 Settings App team,這個 team 主要就是由人生勝利組的學長 Arthur 帶著其他人一起守住 FxOS 裡面的 Settings app(就是大家手機裡面的「設定」),不得不說這個 app 真的是包山包海包了又包包了再包,有一大堆和電信業者之間的通訊問題要處理、有一大家和系統之間的複雜互動還有一堆各 app 都要進來插一些自己的客製化設定,真的是一個不得小覷的 app!

在這個 team 裡,真的要特別感謝 Arthur、Ian 還有 Fred。感謝 Arthur 教我很多程式設計的一些眉眉角角,我永遠都會記得 Data / UI 分離這個準則的 xD。感謝 Ian 在 Settings app 裡藍芽的貢獻,如果沒有你擋下這些東西我們就屎定了 xD。感謝 Fred 和我一起處理很多 FxOS Tablet 的問題,當時 tune CSS 真的 tune 的很想死。到底是哪個____把 CSS rule 寫這麼死的啦 xD

也因為這個 team,在 FxOS 1.3 -> FxOS 1.4 workweek 的時候,我和 Arthur 一起和國外飛來的同事處理了很多 DSDS 的問題(就是所謂的雙卡雙待),而那是我唯一一次在 Mozilla 辦公室待到超過 11 點的時候,雖然那個時候很累,不過有這些戰友撐過那一週也是一個很特別的體驗!如果沒有這個 workweek,我也沒有機會去 101 頂樓看整片台北市的夜景(雖然裡面的商店都在賣高價商品給陸客有點煩人之外其他都算不錯),真的,很美。

101

之後,和整個 Gaia team 的大家也變得比較熟了,每一季大家都會舉辦 Team Building 出去某個地方玩一整天,大家一起打過桌遊、打過保齡球、玩過密室逃脫、去過淡水、去挑戰過熱血的抱石活動、去日月潭一起環湖騎腳踏車,好多有趣的事情都在這兩年內發生過,我還記得當時的宮博說過一句話,大意是說「在一些日子之後,最讓你印象深刻的不會是在這間公司工作過了什麼、做了哪些事情。反之,是那些曾經一起工作的人、那些回憶,才會讓你永藏於心」。

兩年之後,我覺得這句話說的真的很有道理,以前曾經去過的那些地方、那些景點都不會有太大的改變,變的是陪你再次來到這裡的人。不過想想,如果沒有前前公司的結束,也就不會有前公司的開始,也就不會有這些精彩的回憶了吧?我們不也是這樣從國小、國中、高中到大學這樣走來的嗎?

兩年之後,很高興認識了你們,謝謝你們給我這個機會參與這一段回憶與歷史,中間也許難免有好、有壞、有淚水、有歡笑,不過這也是人生之所以稱作人生的原因不是嗎?

下一段旅程即將開始,
謝謝你們,在兩年之後。

Special thanks to : Ricky, Gary, Greg, Arthur, Evan, Dominic, George, Ian, Rudy, Steve, Jessica, Sylvia, HsinYi, popochess, Yang-Jhu, Tim, Evelyn, Yuren, Edgar, Fred, Alive, Bella, Fang, Carol, Rex, Tzu-Lin, Luke, Clarice, Paul, Peko, Kate, Michelle … etc.

team3

team4

team1

team2

[FxOS] Settings App – Call Settings

Call Panel

Screenshots

F1C9BD08-E0FE-4327-8D41-0289D3357DC9

Call Panel

Introduction

Call Settings is one of the most important panel that can let users highly customize their own call related settings like Call Waiting, Call Forwarding … etc. (We will cover each part later) Based on the screenshot above, you can see that for this panel, it’s more like an entry point for every panel and also it will display some useful information taken from hardware.

But when you navigate from this panel to others and navigate back, you may notice that some menu items are disabled at first and you can’t manipulate that. This is not a bug but also quite a feature. By doing so, we can make sure that each time when displaying them, we will always use latest value from hardware to make sure we won’t display some outdated information to mislead users.

Call Voice Mail Settings Panel (Dialog)

Screenshots

7E8274FF-D506-492F-9457-B42CA6A4C049

Call Voicemail Panel

Introduction

For every simcard, there must be a special number that you can dial to set your voicemail number and this is why we need this dialog in Settings App. When showing this dialog, it will try to get preset voicemail number in mozSettings db and show it at first. Here, you may get confused why it can get the right number from db, this is because in settings/js/panels/call/panel.js, we also need to show voicemail number on the menu item, so when trying to initialize the item, we will check whether there is any provided number from mozVoicemail API and store it into db, so that’s why in this dialog, you can get this value from db.

Call FDN Settings Panel

Screenshots

28B3155B-DB63-4498-9586-101599D1A41A

Call FDN Settings Panel

0B2234D7-091F-4ACA-9497-9FBB3D0AC630

Enable / Disable FDN

Introduction

This panel is also an entry point that we can set settings related to Fixed Dialing Numbers. Here, we provide a toggle that you can enable / disable this feature. When clicking on the toggle, it will trigger DialogService to show SimpinDialog which is responsible for all Simpin related operations. This feature will only be enabled / disabled when you successfully type your PIN2 correctly in the dialog.

Call FDN List Panel

Screenshots

8A1982D3-2ACC-46D7-BC38-05E587BD17D2

Call FDN List Panel

568610E8-C6ED-46F5-B2BB-01F1940DAF78

Popup menu when clicking on FDN number

Introduction

Here, in this panel, we will list down all preset FDN numbers in the list. When clicking on any number, we will show an popup for it and you can decide whether to call, edit and delete or not. Same with enable FDN, if you are going to do any operation I mentioned, we will use DialogService to show SimpinDialog to confirm this operation.

For any FDN number, they will all be stored inside your simcard. Sometime, based on your simcard, you may have an upper bound for the number of FDN numbers, but this depended on operators so the number may vary. So, if you hit an error message when creating a new number, you may go into this situation.

Call FDN List Add Panel (Dialog)

Screenshots

10125634-9757-44FA-82A4-252CF2A3B4E9

Call FDN List Add Panel (add mode)

DFD4AD2B-5B62-472F-BB03-5C5062C98E83

Call FDN List Add Panel (edit mode)

Introduction

When clicking on the Add button in Call FDN List Panel, this dialog will pop up and ask users to input preferred name and number for this set of FDN number. Instead of adding, this dialog is also can be reused for editing. Normally there is no specific validation rules for these two fields in our codes, instead, we will pass wrapped object from FdnContext.createAction and pass it to SimpinDialog, it will directly communicate with operator and if there is any error coming up, we will directly report it and display to users.

Call Forwarding Panel

Screenshots

6964464D-617A-4356-8CC4-5E39FADF56E6

Call Forwarding Panel

Introduction

Honestly, Call Forwarding can be the most complex panel in Call Settings (especially before it was refactored), so let me briefly tell you a story behind this panel.

When users click on any menu item and type number for any Call Forwarding option (For this part, please check Call Forwarding Details section), after submitting, we can get wrapped results from the dialog and use call/call_forwarding.js to help us handle this object. After doing some tests, it seems that it is not able to do multi tasks when interacting with Gecko’s API (This should be the problem in modem). So, in order to make anything works perfect, we create another module called CallSettingsTaskScheduler (call/call_settings_task_scheduler.js) inherited from TaskScheduler (modules/base/task_scheduler.js).

TaskScheduler is obvious responsible for handling different tasks and make sure they are all scheduled and can be executed one by one without conflicting each other. While for CallSettingsTaskScheduler, it is just an extended class with some customized TASK_TYPE and error handling.

So back to topic, because we aren’t able to do more than one request on modem each time, we need the help from task scheduler to achieve this. This operation includes get and set, so they all should be scheduled. If we don’t do this in order, modem will directly throw out errors and our request would be dropped and this would make our state inconsistent with hardware.

In addition to this, there is also another special feature that TaskScheduler provides – if there is another same-type task coming up, we will remove queued same-type task and push the new on in the array. By doing so, we can make sure we won’t send outdated request and would always keep the latest one.

And for UI, when modem is busy on handling our operation, we should disable all UIs while normal, we should make them back. So, in panel, we will observe CallForwarding’s internal _state to lock / unlock UI.

For anything else, please check our script.

Call Forwarding Details Panel (Dialog)

Screenshots

CF3AF5AE-E101-4564-B490-624B24F61061

Call Forwarding Details Panel (Dialog)

Introduction

This is the dialog that you can set any number on each Call Forwarding option. Right now, because we do support 4 different options for Call Forwarding but with the same UI, we will reuse this dialog for all of them instead of duplicating many codes. But basically, there is no much logics hidden in this dialog and all what it does is pass the result back to Call Forwarding Panel (Caller) and the caller will do following operations based on returned values.

For more details about how Call Forwarding works internally, please check Call Forwarding Panel section for more details.

Call Barring Panel

Screenshots

5E57AD2D-F02A-46F9-9647-098B898D4993

Call Barring Panel

Introduction

In this panel, you can restrict certain types of outgoing calls and incoming calls. There are no special logics handled in this panel and this can be treated as a toggle that helps you customize your Call settings.

[FxOS] Settings App – SimCardManager

Simcard Manager

Screenshots

root2

Root panel

SimcardManager2

Simcard Manager

Introduction

After 1.4+, FxOS has started to support DSDS (Dual Sim feature) that you can insert 2 simcards into your FxOS device. By default, because FxOS is a unified OS that should be used in different devices, we will automatically hide this entry point by default if there is no more than one physical simcard slot.

If you check source codes in settings/js/panels/simcard_manager, you would notice that we have sim_ui_model.js and simcard_manager.js. Let me briefly explain the responsibilities of these two different scripts below.

For SimUIModel, this is a abstract interface between hardware information and our UI. Based on UX’s spec, there are so many different scenarios that we have to show / hide some parts of UI like simcard is not inserted, simcard is locked, simcard is blocked …etc. So, that’s why we need SimUIModel to control every sub-states.

While for SimcardManager, it will bridge the internal state of SimUIModel and real UI to make sure what should be hidden and what should be updated. In addition to this, SimcardManager also needs to watch some hardware events (like AirplaneMode, cardstatechange … etc) to update its UI to make sure they do reflect the real status.

In SimcardManager, there are three important select/option called Outgoing Calls, Outgoing Messages and Data. For some apps (like dialer), they will watch these mozSettingsKey to show / hide some hints to users, for example, if you choose Always Ask for outgoing calls, every time when you are trying to dial out a number, it will keep popping up a simcard picker UI so that you can choose which number you are going to use to dial.

But, there is one black magic that you need to keep in mind when you are dealing with these three select/option. In system app, there is one file called sim_settings_helper.js which does lots of works with these three options. Based on UX’s spec, there is a special request that we have to automatically switch options if from 2 simcards to 1 simcard. Interestingly, because from Gaia (including Gecko) aspect, we can’t directly make sure the second card is indeed inserted (We did encountered one edge case that one of colleague’s old simcard is hard to be recognized by our hardware and it takes more than 3 ~ 5 seconds to get its information from Gecko), due to this, sim_settings_helper.js will wait for upcoming event – simslotready from simslot_manager.js to make sure we did wait longer enough for the second card, and we can based on current situation to decided whether to switch option to another card or not.

[FxOS] Settings App – Wifi

Wifi

Flowchart

Wifi-4

Wifi Panel

Screenshot

44890310-4321-4780-B47D-7C55F31C131E

Wifi Panel (A)

208C8D9A-B39D-4A81-A6C3-19DBAEC8259D

Wifi Panel (B)

Introduction

Wifi panel is the main entry point for the other dialogs / panels. As you may see on the screenshot above, in this panel, users can turn on / off Wifi, decide which AP to connect with and manage certificates or whatever settings related to Wifi.

If you check settings/js/panels/wifi/, you will notice a script which is called wifi_network_list.js. This script is so important that we will use it to generate a list of APs that users can interact with. For example, if you click on any listed AP, it will automatically check its own encryption to show which kind of dialog or just connect to that AP directly.

In addition to this, it will also automatically check its current status from Gecko to see whether it should update its signal / wording … etc. By doing so, we encapsulate all logics within this list and caller doesn’t have to know these details when using it.

Wifi WPS Panel (Dialog)

Screenshot

C6FBDCA2-D54B-4D51-90DC-FDEFA73CEE12

Wifi WPS Panel

Introduction

WPS is another way to connect to AP but this needs some special support from it to make the functionality work. If your AP does support this, users can click on Connect with WPS button to select which way to use to connect with WPS.

From Gaia side, there is no much works here and we simply provide a basic UI for users to choose and configure. So for more details, please go check Gecko’s source code for this part.

Wifi Status Panel (Dialog)

Screenshot

C5B6EB09-BA07-4D67-8684-AD4DDC662D62

Wifi Status Panel

Introduction

When clicking on connected AP in Wifi Panel, this dialog would be popped up to tell users all needed information about this AP including Security, Signal strength, IP address and Link Speed. In addition to this, you can also forget this AP by clicking right-up button.

Wifi Auth Panel (Dialog)

Screenshot

A13A9735-54E0-46A8-9002-688E15DC8097

Wifi Auth Panel

Introduction

If users click on non-connected and encrypted AP from Wifi panel, we will pop up Wifi Auth Panel to users. Compared with non-encrypted AP, normally users have to type password or do some extra pre-settings to connect to this AP.

Wifi Manage Networks Panel

Screenshot

AE570F39-07F3-41A8-BC11-5A02C01939A2

Wifi Manage Networks Panel

Introduction

In this panel, we will list down all connected AP here. If users click on the item, the confirm pop-up will be shown to double confirm whether they really want to remove forget connected AP or not. So for this panel’s code, there is no much complex works but only some UI related stuffs.

Wifi Join Hidden Panel (Dialog)

Screenshot

F8F1053A-C63E-4ED6-804A-596755C6F966

Wifi Join Hidden Panel

Introduction

This panel is pretty simple enough and it will transform all user’s input into a recognizable object for WifiManager. But there is one thing that should be noticed. Because there are some shared UI / logics for users to select security, EAP method … etc across panels (Wifi Auth Panel & Wifi Join Hidden Panel), we have to use a shared script to control them.

But, sadly, because there are still some minor difference between these two pages, in shard script, we will check some element’s existence before manipulating. So please remember to double check UI codes and shard script for this part before adding new rules. Otherwise, you may break another panel.

Wifi Manage Certificates Panel

Screenshot

CAF97E29-4E6B-4921-A4E9-D302DD874DC3

Wifi Manage Certificates Panel

Introduction

If users are trying to connect with AP with WPA-EAP encryption, under some special EAP methods, they need users to provide needed Server Certificates and User Certificates for authentications.

So, if users are trying to connect to AP with these EAP methods, they have to go to this panel and import needed certificates first, otherwise, we can’t find out needed certificates when users are trying to join hidden network.

Wifi Select Certificate File Panel

Screenshot

2E3A5B59-0C08-444B-A12F-AEEDAA211886

Wifi Select Certificate File Panel

Introduction

In this panel, we will list down all possible certificates from SD card and present them to users. When clicking on these items, we will redirect them to Wifi Enter Certificate Nickname Panel.

Wifi Enter Certificate Nickname Panel (Dialog)

Screenshot

D1A80F77-1DC3-42E8-AC72-B6FC88C65FA0

Wifi Enter Certificate Nickname Panel

Introduction

After selecting needed certificate from Wifi Select Certificate File Panel, users will be redirected to this dialog. In this dialog, users can decide whether to rename this certificate or not. Interestingly, if you already have one certificate named with the same name, you are not allowed to name it again because Gecko would throw out some error in this special case.

[FxOS] Settings App – AirplaneModeHelper

AirplaneModeHelper

Flowchart

AirplaneModeHelper

Screenshots

root2

 Setting’s root panel

Introduction

For developers, AirplaneMode is a complicated service that has deep relationships between different services like Bluetooth, Wifi and MobileConnections. Because these services are all related to hardwares, there must be some round-trip time that you have to wait. In order to make these operations encapsulated, they are all handled in system/js/airplane_mode.js. and we think the other apps should just use a trigger to tell System app to do following works.

But due to the restriction that we can’t easily communicate across apps easily, we have to use some internal settings key to communicate. But in order to make sure other apps won’t directly manipulate the communication key that would break the other apps, we think the better way is to design an unified helper for everyone to use, and all these details will be hidden within APIs which it exposes and that’s why we need AirplaneModeHelper (its abbreviation would be AMH, and related file would be shared/js/airplane_mode_helper.js).

If you check below flowchart, you can notice that there are some useful API like ready(), setEnabled(), getStatus(), addEventListener() and removeEventListener() that you can use to build up your business logics. Take Settings app for example, there is a toggle in its root panel and users can click on it to enable / disable AirplaneMode, we use AMH to manipulate it and make sure we will block UI when enabling/disabling and unblock UI when enabled/disabled.

So with AMH, you can do whatever you want which relates to AirplaneMode, while for more details, please check its source code and flowchart below.

[FxOS] Settings App – DialogService v.s. DialogManager

Image Credit

settings

DialogService

Flowchart

DialogService-3

DialogService focuses on controlling states between dialogs, it will make sure every time there is only one dialog showing up on the screen and for the others, they will be queued as an internal state and will be executed one by one when current dialog is dismissed.

Right now we support 4 different types of dialogs, AlertDialog, ConfirmDialog, PromptDialog and PanelDialog in DialogService.

For the previous three dialogs, they are used as a substitution of native alert, confirm and prompt API with predefined layout based on UX’s spec. While for PanelDialog, you can define your own dialog with pre-defined interface and DialogService will help you show it with all necessary callbacks are bounded on UI.

While for lifecycle of dialogs, they are all handled in DialogManager and please go check related documentation for this part.

DialogManager

DialogManager-2

DialogManager is a manager that mainly focuses on controlling the whole life cycle of each dialog. It will load panel, initialize panel, use pre-defined transition to show panel when DialogManager.open() is called. While for DialogManager.close(), it will find out which panel is going to be closed, validate the result of onSubmit() or onCancel(), and use pre-defined transition to hide panel.

Basically, this DialogManager will be only used accompanied with DialogService. If you want to know more details about how they are communicated with each other, you can go check settings/js/modules/dialog_service.js for more details.

[FxOS] Settings App – Dialog v.s. Panel

fxos

In Settings app, we have two different concepts – one is Dialog while the other one is Panel. The main difference between them is how they are presented. From UX spec, if we need users to do some actions and then submit, normally they will be presented with Dialog with cancel and submit button. While for Panel, it is just a simple view that focuses on presenting data and basically you can notice that there is always a “<“ backward arrow in the header that can help you navigate back to previous panel.

63BF65E7-D01A-4934-B67B-D396E067C044

Wifi Auth Dialog

C2C748FE-3B37-4CF1-A0B4-C96DE1767C15

Wifi Panel

If you are going to create a dialog, here comes some notes that you need to be aware of at first. Let’s use Wifi Auth Dialog for example :

[Setup]

  1. You have to register one section element in Setting’s index.html.
    1. <section is="wifi-auth" role="region" id="wifi-auth" class="dialog"></section>
    2. remember, you need to add one extra dialog class to make sure the section can be applied with right CSS style
  2. Remember to add one more link element in index.html to make sure related sub-document will be loaded.
    1. <link rel="import" href="/elements/wifi_auth.html">
  3. And then, you can follow scripts under settings/js/panels/* to make sure all dialog needed codes can be loaded.

Take settings/js/panels/wifi_auth/panel.js for example, for Dialog, there are some special API you can use and something that you need to know.

  1. In order to pass data back to caller, you can use onCancel and onSubmit function with resolved data. By doing so, caller can use DialogService.show(‘panelId’).then(function(result) {}); to get needed data.
  2. And also, if you want to programmatically cancel or submit, after Bug 1166495 is landed, you can use this.cancel() and this.submit() to achieve this.

For Panel, you can follow [Setup] part above without adding extra class and everything is done ! Based on our design, they share the same interface and there is no much difference between them, just make sure you won’t use onSubmit(), onCancel() and Dialog related API described above, then you are good !