CP3108B: Final Report

My initial proposal consists of 3 bug fixes:
1. Bug 472483 – Make use of activity manager for calendar operations.
2. Bug 260121 – Make datepicker and timepicker keyboard accessible.
3. Bug 242112 – Make calendar keyboard accessible.

However, due to the complexity of the task and lack of experience working in the open source community, I was unable to complete the proposed items. Nonetheless, I have strived to pick up as much as I can over the semester and accomplish whatever I can.

During the course of the semester, I have made 4 bug fixes (1 is resolved and 3 of them are still waiting for review) and the 5th one is currently in progress.

Despite not being able to complete the proposed tasks, I look forward to working on them after the semester and contribute more to the community.

1. Bug 729526 – suite/browser/nsBrowserContentHandler.js contains unnecessary constant

Work done:
Removed a line of code from /suite/browser/nsBrowserContentHandler.js.

Lessons learnt:
Despite being an easy bug fix, I had learnt quite a bit on how to contribute in the Mozilla community. For instance, it is after working on this bug that I understood the patch submission process – upload patch file and get it reviewed. I also received feedback on how I should be creating a patch with the necessary metadata for check-in. Coming from a Git background, I was under the impression that a git diff -p -U8 would generate the necessary patch file. However, since Mozilla build is managed using Mercurial, I had to find an equivalent command for doing that. I was fortunate enough to receive some help from my mentor and he helped me out by finding the appropriate command to perform the task.

Personally, this task has helped me to gain confidence working on subsequent bugs as I had a hard time trying to resolve another bug – 472483 earlier.

Status:
Resolved and fixed.

2. Bug 734134 – test_simpleThread.html is() calls miss message parameter

Work done:
Added message parameters to test assertion calls.

Code sample:

var worker = new Worker("simpleThread_worker.js");

worker.addEventListener("message", function(event) {
  is(event.target, worker, "Expected event target for message");
  switch (event.data) {
    case "no-op":
      break;
    case "started":
      is(gotErrors, 2, "Number of errors received before 'started' message");
      worker.postMessage("no-op");
      worker.postMessage("stop");
      break;
    case "stopped":
      worker.postMessage("no-op");
      SimpleTest.finish();
      break;
    default:
      ok(false, "Unexpected message: " + event.data);
      SimpleTest.finish();
  }
}, false);

var gotErrors = 0;
worker. function(event) {
  event.preventDefault();
  is(event.target, worker, "Expected event target for 1st error");
  is(event.message, "uncaught exception: Bad message: asdf", "Expected 1st error");
  ++gotErrors;

  worker. function(otherEvent) {
    otherEvent.preventDefault();
    is(otherEvent.target, worker, "Expected event target for 2nd error");
    is(otherEvent.message, "Components is not defined", "Expected 2nd error");
    ++gotErrors;

    worker. function(oneMoreEvent) {
      ok(false, "Worker had an unexpected 3rd error: " + oneMoreEvent.message);
      SimpleTest.finish();
    };
  };
};

Lessons learnt:
This involves refactoring the existing code and adding additional messages to the code. This bug fix is also trivial. However, this gave me the opportunity to dabble in writing tests for SeaMonkey and understand how the backend infrastructure works.

Status:
Waiting for review from mentor.

3. Bug 735333 – Use Services.prefs instead of preferences-service / gPrefService, in SeaMonkey code

Work done:
Deprecated getService calls and replace them with Service.prefs.

Code sample:

/*
 * Code sample truncated due to its sheer size – 100 lines changed.
 */
function AddDirectoryServerObserver(flag) {
  if (flag) {
    Services.prefs.addObserver("ldap_2.autoComplete.useDirectory",
                               directoryServerObserver, false);
    Services.prefs.addObserver("ldap_2.autoComplete.directoryServer",
                               directoryServerObserver, false);
  }
  else {
    var prefstring = "mail.identity." + gCurrentIdentity.key + ".overrideGlobal_Pref";
    Services.prefs.addObserver(prefstring, directoryServerObserver, false);
    prefstring = "mail.identity." + gCurrentIdentity.key + ".directoryServer";
    Services.prefs.addObserver(prefstring, directoryServerObserver, false);
  }
}

Lessons learnt:
This bug is not trivial as it sounds. Besides replacing the function calls, I have to read through the code and find out the available libraries that can be called using Services.prefs. After speaking to my mentor regarding this bug, I have also learnt how both approaches differ from each other. Previously, the only way to use Services is to specify one particular service and instantiate immediately using getService. However, this behavior may not be desired for most cases as the service may not be required throughout program runtime. As such, Services.prefs provides the “lazy-getter” approach by allocating the service when needed.

In addition to this, I have also read up on how XPCOM works. XPCOM is a cross platform component object model that forms the core components of Mozilla products. It allows developers to implement features in various different languages using JavaScript, Python and C++. Initially, I was curious as to how we can make simple JavaScript calls to manipulate UI elements in Thunderbird and I understood now that this is possible due to XPCOM.

Status:
Waiting for feedback from mentor.

4.Bug 741019 – a trailing slash in a CSP source host causes it to be ignored (per spec), this should be logged with a CSPWarning()

Work done:
Added conditional statement to check for trailing slash in hosts string. Added additional test case for this check.

Code sample:

/*
 * In content/base/src/CSPUtils.jsm:
 */
CSPHost.fromString = function(aStr) {

// truncated

// host string must be LDH with dots and stars.
var invalidChar = aStr.match(/[^a-zA-Z0-9\-\.\*]/);
if (invalidChar) {
  // host string with a trailing slash is a possible common error,
  // do an additional warning in this case
  if (invalidChar == '/' && aStr.indexOf(invalidChar) == aStr.length - 1) {
    CSPWarning(aStr + " will be ignored due to trailing slash");
    return null;
  }
  CSPdebug("Invalid character '" + invalidChar + "' in host " + aStr);
  return null;
}

/*
 * In content/base/test/unit/test_csputils.js:
 */
h = CSPHost.fromString("foobar.com/");
do_check_eq(null, h); // "trailing slash in hosts should fail"

Lessons learnt:
This bug is tougher than the previous ones. I had to refresh my memory on regular expressions and understand what the code is trying to do. After some discussion with the mentor, I also had to implement a test for the fix I worked on. This requires some reading up on xpcshell tests and how to run them. Overall, this was a great learning experience for me.

Status:
Waiting for review from mentor.

5.Bug 472483 – Make use of activity manager for calendar operations

Requirements:
Display calendar operations (i.e. add/delete/modify events, to-do items) in the Activity Manager interface (see picture below) in Thunderbird.
Activity Manager

Work done:
Understood the code architecture for Thunderbird Calendar extension. Read up on how event notification is integrated in the code. Came up with skeleton code for the new framework.

Lessons learnt:
Personally, I was stuck at this bug for quite some time. Since this was the first one that I worked on, it was a daunting task. Nonetheless, I spoke to the mentor and learnt quite substantially on the code base. The initial plan is to add activity manager code at places where calendar operations take place. However, my mentor commented that this is undesirable as this would introduce coupling and violate the MVC pattern. Instead, he proposed creating an API class for activity manager to handle calendar operations separately. It should also observe calendar operations for changes.

I hope to continue working on this after the semester given that I have a better picture on how to implement this.

Status:
In progress.

Conclusion

My semester has been really fruitful after taking up this module. Open source contribution has been something that I have wanted to do for some time and I am glad that I took up this module. In addition to learning how the open source community works, I have also learnt the code base of Thunderbird’s Calendar extension, understood how XPCOM powers Mozilla components and applied some of the concepts that I have learnt in school such as observer and MVC patterns.

Looking forward, I hope to apply what I have learnt here and work on bigger projects in future.

CP3108B: My contributions thus far

What I am doing - Thunderbird Calendar extension

I was partly influenced by Mohit, who presented on Calendar during one of our classes and I thought it would be really cool to work on a smaller scale project as compared to Firefox. By doing so, I would be able to take on bigger responsibilities and make more significant impact on the community.

Why fix bugs

I have always been fascinated by how the open source community works. How do people from different parts of the world work together to deliver a product? Working on bugs would give me the opportunity to peek into this and subsequently, be part of this team.

Fixing bugs is my way of giving back to the software world. I am a strong advocate of free software and the only way for that to happen is to have developers working on it 24/7 out of altruism.

What I proposed

These are the bugs which I have proposed for this module:

Bug 472483: Make use of activity manager for calendar operations

Bug 242112: Make calendar keyboard accessible

Bug 260121: Make datepicker and timepicker keyboard accessible

What I have done

Fixed one bug in SeaMonkey - bug 729526. This was really trivial and it only involved deleting a single line of code.

Fixing another one - bug 472483. This is a real headache, but I am really fortunate to have Mohit and Philipp who have helped me along the way. It looked really easy at first glance - add activity manager code for calendar operations and display them in the UI. However, there's more to it. The previous implementation would introduce numerous code duplication in the program and a better way of tackling it would be to have an activity manager connector that will observe calendar operations. This is much more elegant and improves code maintainability.

What I have learnt

Don't hesitate to ask for help: The folks in IRC are really helpful. I was really intimidated initially because there wasn't much activity going on in the channel.

More JavaScript: I learnt the difference between let and var, which I didn't come across previously. I later learnt that this is something that is unique to Mozilla.

Code structure in Calendar: I wouldn't boast that I know how the different components interact with each other, but I definitely have a better understanding of a small portion of it. I believe my knowledge of the codebase would increase as I fix more bugs.

Patch submission: I was told by Philip (from SeaMonkey) that using hg export instead of hg diff would be easier for the person to check in the code. For those who use git like me, here's the git equivalent of hg export (thank you Philip for providing this link!).

What I plan to do next

Week 8-9: Finish up activity manager feature.

Week 9-10: Make calendar keyboard accessible.

Week 10-11: Make datepicker and timepicker keyboard accessible.

Conclusion

I hope to accomplish more for the second half of the semester and better manage my time to achieve that. My goal would be to finish two of the proposed bugs :)

 

Thoughts on Singapore River: Mobile

Yesterday concludes the final chapter of our project: Singapore River.

For those who do not know what it is, it is an iPhone app that brings the user on the Singapore River trail and at the same time, showcases information and content in an interactive manner. You can check out the demo video done by Joshua over here. Kudos to Joshua for working on it :)

It was a bumpy ride for this assignment. We started off with what was left behind by the previous team who worked on the web app. Initially, there wasn't much direction as to what we wanted the app to be, but we agreed to continue building on it. A list of to-dos was collated and the developers went on to improve the system.

It was until we met up with Prof. Ben that we started to think about what our vision for the app would be. Suggestions then started to flow in - guided audio tours, mini-games, etc. We decided to head down to Singapore River (heeding Prof. Ben's advice) and experience for ourselves the problem we are trying to solve in our app. While we brainstormed on what features we wanted to implement, we were somewhat restricted by the limited capabilities of a web app. It was only then that we decided to work on a native app and as they say, the rest is history.

To be honest, I took a huge gamble when I proposed to the team that we should develop natively. First and foremost, we did not have any experienced iOS programmers. And lastly, we had to discard what we have and start from scratch. I replayed the numerous possible outcomes and scenarios in my head, and in the end, I decided to give it a shot. Looking back, I am still unsure what made me take the plunge.

Perhaps it is the same sudden rush of energy and confidence that I had when I chose to take up this module (despite the fact that I'm not doing this to fulfill my course requirements). Perhaps I was still hungover from my experience in Silicon Valley. Perhaps...

It still remains a mystery to me and I'm still trying to figure out how best I can harness it. But I digress.

It was a risky decision and Prof. Ben tried to dissuade us (twice, actually) from doing it. Nevertheless we went ahead and never looked back. Personally, I feel that it is this belief that we have in the team that kept us (at least for me) going despite the numerous setbacks we had after that. It is that day when we chose to take the leap of faith and push our limits. And boy I'm glad we did it.

All these would not have been possible if not for the following people pulling all-nighters.

Zhenling has been nothing short of awesome. She picked up Objective-C from scratch in spite of not having a personal Mac to work with. Moreover, she did this together with her FYP. Remarkable woman indeed.

Joshua has been the ideas guy, coming up with (sometimes wacky) suggestions on how best to improve our app. His digital multimedia skills were put to the test towards the later stages and you can see it for yourself from the demo video posted earlier. I also admire him for displaying such enthusiasm as our mascot during Poster Session Day. You can watch him here.

Kenneth is the unsung hero of the team - tying up the loose ends for the team. He is the guy responsible for delivering the reports and designing the poster. With him around, we can put our mind at ease.

David plays the role of the motivator in the team. Treating us to dinners (from U-town canteen) and bubble teas (from Koi) are just some of the stuff he does to ensure that the engine doesn't stop running. You can also count on him with his (sometimes dark) humour to loosen the tension that we have during our meetings. An indispensable member of the team.

With that, it's back to hitting the books.

P.S. I would be maintaining the blog after this module ends. I find it a good way to gather my thoughts on a particular subject that interests me. Thanks for reading!

EDIT: I meant to say that I took up CS3216 not to fulfill my academic requirements (see comments below). Thanks Joshua for bringing this up!

Thank you CS3216!

And we have finally come to an end of the semester. CS3216 has been a love-hate relationship for me. I love how I can work with other like-minded people and spend our time trying to solve real world problems. I love how I can pick up new things and apply these skills immediately. But I hate it for taking up so much of my time from other modules (I was avoiding my CS2106 lecturer when he was walking around the booths on Poster Session Day :s ).

But I have no regrets. I have accomplished most of the things which I have listed down at the start of the semester - learning new programming languages and finding out more about the local entrepreneurship and technology scene. I'm not sure if I managed to overcome my habit of not completing projects. Time will tell if I did and I definitely have to plan my time during the holidays to work on meaningful projects.

In addition to what I have set out to do, I have also learnt many unexpected things as well. I have learnt people have vastly different working habits. Some choose to work alone, while others prefer to work in groups. One has to recognise this and wield it to his/her advantage. I don't proclaim I have mastered this, but I think it's a start, isn't it?

I have the habit of taking up too much responsibility and overwhelm myself while at it. I have become more aware with this module and CS3246 as well. In future, I would strive to balance between what I can do and what I want to do.

It is a real pity that this would be the last time that CS3216 is offered. I was sitting outside the venue where the Poster Session was held (as I was busy preparing my cheat sheet for my Physics test) and it is heartening to hear that majority of the students are aware of this marquee event of our module. It is definitely a sight to behold as it is only during this week of the semester, where our building is bustling with noise and activity. Obviously beats the sight of students hogging the tables with their laptops and books.

Lastly, I would like to salute all those who have taken this module. It requires a certain amount of courage to sign up for it. But it needs a tremendous amount of grit and faith to survive through it. I'm glad that I have done this with all of them. We are the square pegs in round holes.

And this would not have been possible without our awesome lecturer, Prof. Ben Leong and his dedicated TA, Kok Wee. Their contributions to this course have not gone unnoticed :)

Thank you CS3216!

Thoughts on education

I've previously promised to blog about what I feel about education. And I finally have the time to do it. So here it is.

Since young, I've been taught that education is the solution for poverty and the way for a country to progress. People will then be able to enjoy higher standards of living. This probably explains why most student-initiated overseas community involvment programmes involve constructing libraries, teaching English and so on. We feel a need to help people who are less fortunate elsewhere to enjoy what we have right now. Isn't that wonderful?

Despite our good intentions, I feel that the way our current education system is structured is flawed. Institutionalised education has trained us to think, write and speak the same way. We are disciplined if we do not belong to the norm. Do you remember how our teachers used to fine us (50 cents) if we do not speak English in class? This ideology has been ingrained in us when we were kids and it has definitely changed the way we think at present.

Well, then what is wrong with this? Most of us are fortunate enough to receive college education. We are the ones that have performed well in our education system. But what about those who are left behind? What happens to those who did not pass their tests to enjoy higher education? They are deemed as failures as they find themselves to be of no value in our society. Education prepares us for the real world - be it engineers, doctors or lawyers. If you do not study hard enough to be one of these, you have failed.

This poses a serious problem. When people find themselves to be of no use to the society, they turn to other means to feed themselves and their families. Prostitution and drug peddling are just some of the things they do to make money. They are the ones who have fallen through the cracks in our current education system. They have been labelled failures because they do not think, speak or write the way we do. We embrace uniformity and conformity, while condemning diversity and uniqueness. And as a result, they are left to fend for themselves, while the society progresses.

Well, I'm not sure if our education has really benefited everyone in the society. And I don't think I wish to impose this system onto others when it has caused us so much problems. I will certainly think twice before I head overseas to build another library for village kids.

P.S. You should watch this movie if you are still not convinced of our current plight. It's only $5 if you are a student or having economic difficulties. And the money goes out to non-profit organisations. I can assure you that the five dollars you spent is going to be the most valuable investment you have made so far.

 

Showcasing [filter]+

Note: This posting was supposed to be made on Nov 8, 2011 (although I'm only posting it on Nov 10). Changing the display date to reflect that.

Today marks the end of our second assignment for CS3246. The demo session was somewhat disappointing as the TA wasn't impressed with how we chose to do it on iOS instead of HTML 5. Well, I did clarify this with him earlier, and his reply was that we can choose to do it on whichever platform, as long as it fulfills the requirements. But I suppose there isn't any point arguing any further when he has the final say in our grades.

I would like to take this opportunity to introduce to you our app - [filter]+, which is an image processing (think Instagram) app. You can choose from your Facebook photos, your own photo library (in the phone) or camera and experiment with the filters (made by us!). And finally, you can share it on Twitter and Facebook. For the latter, you can choose to tag your friends in it too.

Our designer, Ryan, came up with the entire app interface and design. I would say that a good designer is critical in presenting your product to the world. It doesn't matter whether you have used the most sophisticated or state-of-the-art technology to do it. But if it does not appeal to the user in the first 5 seconds, you have failed.

(download)

We have included an empty data set screen (second image in the gallery) to subtly notify the user that he/she needs to set up their social media accounts to retrieve photos. I find this a much elegant and unobtrusive way of alerting the user, instead of using the traditional alert popups. Kudos to Ryan again for coming up with the patterns for our background :)

(download)

One of my favourite filters in our app because I came up with it (first and second image in the gallery)! Basically, you can turn any photo into an artistic painting. It works for high contrast photos and has really nice effects for close-up shots too. Shao Hong gets the props for coming up with the other filters. Check out his work (last two images in the gallery)!

(download)

Twitter (with iOS 5 integration) and Facebook sharing pages.

I made use of Facebook's iOS SDK to enable the gallery and sharing features of our app. It wasn't a pleasant experience (again!) as Facebook's documentation is really poor. I was spending hours trying to figure out the POST parameters required to send to Facebook's Graph API when you are uploading a photo with tags. If you are stumped, the parameters to send to "me/photos" are "tag_uid" (the tagged person's user id), "x" (the x-coordinate of the tag as a percentage of the image's width) and "y" (the y-coordinate in percentage of image's height). 

And the remaining time was spent trying to figure out why the JSON parser provided by Facebook SDK refuses to parse NSArray and NSDictionary to JSON. In the end, I had to format my own string with braces and parentheses with the key-value pairs before sending to Facebook. 

Overall, I am still impressed with how I managed to come up with the app in one weekend, considering I picked up iOS three weeks ago? And this is only my second app. There's still room for improvement though in terms of software engineering practices for iOS.

Maybe CS3217 for next semester? :s

Punk'd by Apple.

Two days into creating (another!) iPhone app for my module and I realized that CIGaussianBlur is not working.

I was frantically looking at the SDK Documentation for an hour, but to no avail. In the end, I stepped through the code and used the debugger console to check my code. To my surprise, creating a gaussian blur filter returned nil. 

In case anyone fell into the same trap, here's the list of filters (both image and video) that are supported in iOS 5 SDK:

<__NSArrayI 0x3e8230>( CIAdditionCompositing, CIAffineTransform, CICheckerboardGenerator, CIColorBlendMode, CIColorBurnBlendMode, CIColorControls, CIColorCube, CIColorDodgeBlendMode, CIColorInvert, CIColorMatrix, CIColorMonochrome, CIConstantColorGenerator, CICrop, CIDarkenBlendMode, CIDifferenceBlendMode, CIExclusionBlendMode, CIExposureAdjust, CIFalseColor, CIGammaAdjust, CIGaussianGradient, CIHardLightBlendMode, CIHighlightShadowAdjust, CIHueAdjust, CIHueBlendMode, CILightenBlendMode, CILinearGradient, CILuminosityBlendMode, CIMaximumCompositing, CIMinimumCompositing, CIMultiplyBlendMode, CIMultiplyCompositing, CIOverlayBlendMode, CIRadialGradient, CISaturationBlendMode, CIScreenBlendMode, CISepiaTone, CISoftLightBlendMode, CISourceAtopCompositing, CISourceInCompositing, CISourceOutCompositing, CISourceOverCompositing, CIStraightenFilter, CIStripesGenerator, CITemperatureAndTint, CIToneCurve, CIVibrance, CIVignette, CIWhitePointAdjust )

A note for Apple: update your iOS Documentation! The header clearly stated, "iOS Developer Library". Then why am I still seeing filters limited to Mac OS X?!

And it seems like I'm not the only one in the world that faces this problem. Well, at least there are options.

But I'd still need an Objective-C implementation of HDR processing to meet the project requirements... And time is running out :(

If you are an educator, you should watch this.

My headache is killing me right now. I will supplement this with a subsequent blog post.

But if you have 18 minutes, you should watch this video:

http://www.brainpickings.org/index.php/2011/10/27/alistair-smith-do-lectures/

"In times of change, learners inherit the earth, while the learned find themselves beautifully equipped to deal with a world that no longer exists."

- Eric Hoffer (1902-83)

Single founders.

For last week's lecture, we were fortunate to have some local entrepreneurs to share their thoughts and lessons learnt from taking the path less travelled. It was a refreshing experience as I got to hear from people who are doing non-technical startups.

To be honest, I was really surprised by the number of startups (present that day) founded by a single person. Some of the speakers stated personality differences, while others just simply chose to go solo. Entrepreneurship is certainly not an easy thing - long working hours, irregular sleep cycles, skipped meals and add that to a list of sacrifices and broken promises. I'm going through most of these right now and one may wonder why a sane human being would choose such a lifestyle. And let alone doing this all by him/herself.

Having a co-founder will ease some of the responsibility and stress faced by a single person. It is also easier for both to bounce ideas off one another and spot fallacies in each other's postulations. Chin Leng (who started SingaporeBrides.com) shared with us how he usually chats with his wife to gain a different perspective on his business. Working together with a partner serves as a motivation for oneself to push him/herself to the limit too (this is especially so if your co-founder works really hard). Paul Graham blogged on this and lists single co-founder as one of the reasons why startups fail.

If you are running a startup single-handedly, I would like to hear your side of the story and why you chose to do it :)

It has been a difficult week

Mid-terms results

Well, even though I have learnt to place less emphasis on my academic grades, somehow you will still be affected by the grades. My Operating Systems test was the only one that I was confident of scoring but it turned out that I had failed, quite badly. I refuse to blame my performance on the heavy workload of CS3216 because I haven't been doing my tutorials diligently since the start of the semester. Nonetheless, I have to overcome a huge deficit to make sure I don't flunk this module.

Project

Progress hasn't been quite up to what I have expected. I'm trying to refrain from benchmarking against other teams' progress but focus on developing our product. There has been some shifts in our product focus and hopefully, we can get something up and running by next week.

Personally, I had spent two full days trying to improve our iPhone app's memory management. It is not an easy task - even my peers who have done the iPad course said so too. Watching your app fall from grace midway through browsing the image gallery is definitely not something you would want. After browsing through tens of StackOverflow posts and numerous lines of code, I am proud to say that our app is performing rather well and there isn't any memory leaks, for now.

With that hurdle cleared, it is time to work on the fun stuff - augmented reality.