Tuesday, February 17, 2015

Enterprise Management: User-Agent Switcher for Chrome

When I first wrote the User-Agent Switcher for Chrome, I imagined that it would be useful for administrators who wanted their users to use Chrome, but hack around legacy web apps that expected and required ancient browser versions.  Anyone using the steaming turd that is Outlook Web Access knows what I'm talking about.

However, Chrome didn't offer a way to manage extensions' settings -- only policies for managing itself...until recently.  With policy for extensions, Chrome now allows administrators to send policy settings directly to extensions -- not only can you deploy this extension, you could also deploy all the user-agents and permanent spoofs.

Setting policy for extensions is similar to setting policy for other applications on the target OS: the registry on Windows, a protected directory on Linux, Workgroup Manager on Mac, etc.  Chrome looks for these policies and then applies them to the extension (but only if they are crafted correctly -- more on that later.)

In version ~1.0.38, I added support for policy in the extension: I added the ability to set the user-agents, permanent spoofs, and a few of the other settings...and I hope to add more controls in the future.

To take advantage of this, you'll need to follow the steps below.  Unfortunately, every OS has its own format and own way of handling admin policies, so you may have to follow several of these to get coverage on your entire fleet.

Side note: I often found that any misspelling, or slightly-off structure of JSON or XML would cause policy to silently fail (*cough* broken user journey *cough*), so be sure your structure is correct.  Some debugging tips are at the very end of this post.

What Policies Are Supported

I added support for the most typical things an admin would change -- if you peek down at some of the sample policy files below, the structure should make some sense.  The policies currently supported include:
  • UserAgents -- a list of user-agent strings available for the user.  This is a List of Dictionaries/Hashes that contain the following values:
    • title [string] - the name of the user-agent ("Chrome 41")
    • ua_string [string] - the value of the user-agent string
    • vendor [string] - the value of the "navigator.vendor" field
    • badge [string] - the couple of letters that show up over the icon when spoofing
    • append [boolean]- whether the ua_string value should be appended to Chrome's user-agent (false means replace it)
  • PermanentSpoofs -- a list of permanent spoofs.  This is a List of Dictionaries/Hashes that contain the following values:
    • domain - [string] the domain regular expression to match.
    • user_agent - [dictionary] - this is a full UserAgent object (see above).  This is the user-agent to use with the permanent spoof.
  • EditRights -- several one-off settings for defining what users can edit.  This is a Dictionary.  Regardless of what you set here, users cannot modify user-agents or spoofs provided via policy.
    • user_agents [boolean] - whether the user can edit/add/delete user_agent strings.
    • permanent_spoofs [boolean] - whether the user can edit/add/delete permanent spoofs.
  • Other Settings -- more one-off settings representing the "Other Settings" section in the options screen.  This is a Dictionary of values.
    • hotlist_enabled [boolean] - Whether the user can switch the spoofed user-agent on the fly.
    • spoof_override [boolean] - Whether the on-the-fly spoof user-agent overrides permanent spoofs.
    • spoof_per_tab [boolean] - Whether the on-the-fly spoof applies only to the current tab.

Setup on Chrome OS / Google-managed Chrome

The Admin console has a place to manage extensions' settings (more info here.)  When you find the part of the admin console for setting extensions' policies, you can use JSON of this form:

{ "UserAgents": { "Value": [ {"title": "1", "ua_string": "ua_1", "vendor": "v_1", "badge": "A1", "append" : false}, {"title": "2", "ua_string": "ua_2", "vendor": "v_2", "badge": "A2", "append" : false}, {"title": "3", "ua_string": "ua_3", "vendor": "v_3", "badge": "A3", "append" : true} ] }, "PermanentSpoofs": { "Value": [ {"domain" : "foo.com", "user_agent": {"title": "4", "ua_string": "ua_4", "vendor": "v_4", "badge": "A4", "append" : false}}, {"domain" : "bar.com", "user_agent": {"title": "5", "ua_string": "ua_5", "vendor": "v_5", "badge": "A5", "append" : true}} ] }, "EditRights": { "Value": [ {"user_agents" : false, "permanent_spoofs": false} ] }, "OtherSettings": { "Value": { "hotlist_enabled" : false, "spoof_override": true, "spoof_per_tab": false } } }


Setup on Windows

Full disclosure: I haven't tested this at all, since I don't have any Windows machines to work on anymore, but I *think* this is the right structure.  Feedback is greatly appreciated on whether this works or not.


[HKEY_LOCAL_MACHINE\Software\Policies\Google\Chrome\3rdparty\extensions\jhefaickifmkaeoijafmdniimnjfohef\policy\UserAgents\1
"title"="Test"
"ua_string"="Test UA 1"
"vendor"="Testing"
"badge"="aaa"
"append"=false

[HKEY_LOCAL_MACHINE\Software\Policies\Google\Chrome\3rdparty\extensions\jhefaickifmkaeoijafmdniimnjfohef\policy\PermanentSpoofs\1
"domain"="foo.com"

[HKEY_LOCAL_MACHINE\Software\Policies\Google\Chrome\3rdparty\extensions\jhefaickifmkaeoijafmdniimnjfohef\policy\PermanentSpoofs\1\user_agent
"title"="Test 2"
"ua_string"="Test UA 2"
"vendor"="Testing 2"
"badge"="bbb"
"append"=true

[HKEY_LOCAL_MACHINE\Software\Policies\Google\Chrome\3rdparty\extensions\jhefaickifmkaeoijafmdniimnjfohef\policy\EditRights
"user_agents"=false
"permanent_spoofs"=false

[HKEY_LOCAL_MACHINE\Software\Policies\Google\Chrome\3rdparty\extensions\jhefaickifmkaeoijafmdniimnjfohef\policy\EditRights
"hotlist_enabled"=false
"spoof_override"=false
"spoof_per_tab"=false

Again, I'm not totally sure this is exactly right since I don't have a good way to test it, but please post in the comments if it does.


Setup on Mac

Mac devices use "plist" (policy list?) files to distribute settings -- these are glorified xml text files.  The format for this extension looks like this:


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>com.google.Chrome.extensions.jhefaickifmkaeoijafmdniimnjfohef</key>
  <dict>
    <key>UserAgents</key>
    <dict>
      <key>state</key>
      <string>always</string>
      <key>value</key>
      <array>
        <dict>
          <key>title</key>
          <string>mac_plist_1</string>
          <key>ua_string</key>
          <string>mac plist 1</string>
          <key>vendor</key>
          <string>mac vendor 1</string>
          <key>badge</key>
          <string>aaa</string>
          <key>append</key>
          <false/>
        </dict>
        <dict>
          <key>title</key>
          <string>mac_plist_2</string>
          <key>ua_string</key>
          <string>mac plist 2</string>
          <key>vendor</key>
          <string>mac vendor 2</string>
          <key>badge</key>
          <string>bbb</string>
          <key>append</key>
          <true/>
        </dict>
      </array>
    </dict>
    <key>PermanentSpoofs</key>
    <dict>
      <key>state</key>
      <string>always</string>
      <key>value</key>
      <array>
        <dict>
          <key>domain</key>
          <string>www.foo1.com</string>
          <key>user_agent</key>
          <dict>
            <key>title</key>
            <string>mac_plist_3</string>
            <key>ua_string</key>
            <string>mac plist 3</string>
            <key>vendor</key>
            <string>mac vendor 3</string>
            <key>badge</key>
            <string>ccc</string>
            <key>append</key>
            <true/>
          </dict>
        </dict>
        <dict>
          <key>domain</key>
          <string>whatsmyuseragent.com</string>
          <key>user_agent</key>
          <dict>
            <key>title</key>
            <string>mac_plist_4</string>
            <key>ua_string</key>
            <string>mac plist 4</string>
            <key>vendor</key>
            <string>mac vendor 4</string>
            <key>badge</key>
            <string>ddd</string>
            <key>append</key>
            <false/>
          </dict>
        </dict>
      </array>
    </dict>
    <key>EditRights</key>
    <dict>
      <key>state</key>
      <string>always</string>
      <key>value</key>
      <dict>
        <key>user_agents</key>
        <true/>
        <key>permanent_spoofs</key>
        <true/>
      </dict>
    </dict>
    <key>OtherSettings</key>
    <dict>
      <key>state</key>
      <string>always</string>
      <key>value</key>
      <dict>
        <key>hotlist_enabled</key>
        <true/>
        <key>spoof_override</key>
        <true/>
        <key>spoof_per_tab</key>
        <false/>
        <key>send_errors</key>
        <false/>
      </dict>
    </dict>
  </dict>
</dict>
</plist>



Take this content, save it in a file with a name like "abc.plist".  You'll obviously want to update this to adjust to the settings you want -- these are just my test settings.  Mac administrators can deploy this file via Workgroup Manager, with some guidance on how to do this on the Chromium site.


Setup on Linux

I've never tested this on Linux myself, but I surmise that if you use JSON of the same structure as the Chrome OS policy, and put it in a JSON file in the right location (some basic instructions here.)


Why Isn't It Working / Debugging 

In my development and testing, I found it very common for the policies I was trying to set to not appear at all.  Here's a couple of tricks I used to debug issues with getting policies picked up:


  • http://about:policy is a huge help: it shows if the browser is picking up policies for extensions.  If it's not appearing here, it's not getting to the browser.
  • Any misspelling, missing comma (JSON), using true instead of , etc. will make the OS and the browser just ignore the policy.  If the policy isn't appearing in about:policy, or in the OS's policy viewer, there is a good chance the structure is off.
  • When encountering #2, I found it helpful to get just one *very* basic policy working, then build up the other necessary policies one at a time.


Final Thoughts


I'm hoping that some admins out there who are trying to hack around some legacy systems' problems will find this useful.  Not every setting has a corresponding policy, so there's more work for me to do.  I also need to test on more systems, but I think this should work.

Feedback is greatly appreciated -- feel free to leave it here, or on my G+ page.

Tuesday, January 27, 2015

The Web's Death has been Greatly Exaggerated

Over the past several years, developers and pundits started buzzing about users' shift from mobile to desktop.  And they have good reason to think this way: smartphone shipments are hundreds of millions of units per quarter, a majority of the world's population has access to one, and mobile now accounts for more web usage than desktop.  With both the potential upsize of getting a smartphone in billions of new hands over the next few years, and the rapid overtaking of desktop web usage and PC shipments, how could observers not think that "Mobile is eating the world"?

Many believe this to be a troubling trend for the "open web": users are spending 86% of their time in native apps, and only 14% in mobile web.  Native apps are considered "walled gardens" in that they can't typically be crawled by third parties, like search applications, and the data you generate in them is not typically discoverable outside of the app.  The app developer has complete control over the data they generate and access to that data.  Good luck Googling on your phone for your Instagram photos or your Uber history -- it even sounds silly.

Simultaneously, there's been a rush for developers to make all kinds of apps.  These are developers that could have been out developing innovative web applications but chose to make mobile apps instead.  Many theories persist as to why they choose to make mobile apps instead of web apps, all of which may have a grain of truth:

  • Mobile apps have a built-in monetization method (users are 'conditioned' to pay for apps)
  • Mobile apps have native UI toolkits that make them look much slicker
  • IDEs and tooling around web application development are sub-par compared to Xcode 
  • Javascript and CSS are really hard.  Objective-C, C/++ and Java are easier (related to #3)

This is also very concerning to the "open web": if fewer developers are developing compelling things on the web because they're making walled garden native apps, won't the web wither and die from a lack of innovation?  Isn't the web dying because of the fundamental shift to mobile, and more specifically, mobile apps?

What Are Users Doing In Apps That Is So Valuable?

Let's look at the data to see if the web is really dying.  First, what apps are users using?  Per Flurry's analysis, this is where they spend their time:



Let's break it down in terms of where developers are spending their time:

  • Games.  There's enough to talk about in games, it has its own section below.
  • Facebook --  There are only so many developers working on this app, and they all work at Facebook.  It would be great if the data were open, but it's not a stretch to imagine why it is not.
  • Social Messaging -- people texting each other, sending each other short videos or self-destructing images.  Maybe these could have been developed on the web...as valuable as it is for the open web to have access to everyone's "lol"s and poop emojis.
  • Twitter, YouTube, News -- almost all have web equivalents that are "open".  Except in Spain
  • Utilities -- Flashlights and data usage counters.  Web equivalents of these probably don't make sense to build in the first place, but never say never.

Is there anything that the web is really missing here?  It's possible that instead of spending time making web access points for data really shine, developers are spending time making the mobile apps shine.  However, that's not where users are spending their time.

Maybe that was just a misleading chart.  Instead of looking at people's time spent, look at the top Apps by users in the US:



  • 15 of the top 25 apps are owned by four companies.  (Oh, Snapchat -- maybe you could have been #16.)   8 of the apps are provided by the platform owners Google and Apple.
  • 21 of the top 25 apps have web equivalents that are just another face on the same set of underlying data -- data which is arguably the value to the user, not the app "shell" itself.
  • 24 of the top 25 apps are free.  Technically, the Netflix app is free but really requires a subscription, so I didn't count it as free.  It's totally worth it though -- if you haven't seen House of Cards, it's worth every single cent of your subscription.
Most of the top apps, and apps where users spend the most time, are just another view of data already available on the web in some form.  Moreover, most of the top apps are built and controlled by a small number of large tech companies -- those companies developing these apps is not likely to present an opportunity cost to the web, because they also have a large number of developers also working on web applications.  Perhaps those efforts could have been focused on really making the web version better, but are any of them in a terrible state of disrepair?  


Every one of these apps is free, which flies in the face of the conventional thinking that users are ok paying for apps.  When taken by time used, games, Facebook, social messaging (mostly), YouTube,  Twitter, and news apps are all free (with ads) or make their money off of freemium models.  Users are spending all of their time in free apps!  Guess what else is mostly free, freemium, or ad-supported?  The web.

What About Games?

Games, which constitute the largest chunk of mobile users' time, are obviously a draw for app developers.  Of the roughly 1 million live apps in the App Store, 21% are games.  What's up with so many games, and why do so many get created every month?

A few hypotheses:

  • Games are fun for developers to make, more so than another calculator app.
  • Several high profile mobile game companies got popular fast and had very large exits -- get a few hundred thousand users and then get bought out.
  • People love wasting time on their phone, as evidenced by spending 32% of their time doing so.
Most games are freemium -- very few are paid up front.  They often rely on addictive progression, coupled with social sharing components to get "whales" addicted and shelling out big bucks to get ahead.  In the meantime, the other 98.5% of users get advertising, commonly a very effective kind of advertising called "cost per install" (CPI) advertising.  In CPI, app creator A pays app creator B for every user who clicks one of their ads and installs their app.  CPI is known to be very financially beneficial for the publisher (but only so-so for the advertiser) because even though they set their own install price target, the users they get this way don't stick around and become whales.  So the advertiser has to cram in more ads into their own app to increase lifetime customer value and make the install price worth it.

What does this lead to?  Free games that have CPI ads for other free games -- that have CPI ads for other free games -- etc.  A bunch of money going around in a circle.

Regardless of how un-sustainable that monetization model sounds, how big of a loss is it that the information contained within these games isn't openly accessible?  Arguably, the data within games has some tiny smidgeon of value, and it would be great if the open web could find and discover that.  However, does not having your high scores in Angry Birds be searchable online going to be the nail in the coffin of the web?

Picks and Shovels

There is a famous investing adage that, during the California gold rush of 1849, none of the prospectors who went hunting for gold got rich.  However, people who sold them picks, shovels, blue jeans, and chocolate did get rich.

Mobile apps are having their gold rush -- if a relatively simple flashlight utility app becomes the top popular install, the developer could put a bunch of ads on it and make a decent amount of money.  However, there's only going to be one most popular flashlight app, and one most popular calculator, and one Facebook.  It's reasonable to think that there are some innovative, unique app opportunities not already taken -- but many of the opportunities are.   The marketplaces are entirely owned and controlled by large tech companies: they are the pick and shovel makers, who also happen to be putting big bets on the web.

The shift to mobile is a fundamental change in how users access information, communicate, and spend their spare brain cycles.  Its rise has been meteoric, and anyone who does not respond will certainly be lapped by competitors.  However, the rise of mobile usage has not been to the detriment of desktop usage.

Declaring the web as "dying" is silly -- developers are making free apps for convenience or to fill time, and take advantage of being anywhere -- not replacing what people normally do on laptops or desktops (try to write a book on a phone.)  Once the gold rush of app development is over, the smoke will clear and valuations of mobile apps will come back to Earth.  Would it be better for the open web for all developers to be developing web apps and not mobile apps?  Of course.  But the mobile apps they are building are not apps that make sense for the web, and often have data that isn't that useful or is already available on the web.

Maybe mobile will kill the web at some point in the future -- never say never -- but it hasn't killed it yet.




































Monday, September 15, 2014

Innovate on Experience, Not Features

A lot of hubbub has been circulating around the recently announced iPhone 6 and its feature set.  Firstly, most analysts point out how its not so innovative.  Second, seeing as there were 4 million pre-orders, at a measly $240 profit per phone (40% margin on a $600 unsubsidized price), that stands to net Apple a cool $1 billion in profit....on predorders.  It literally has not shipped yet but already made a billion dollars.

Here's where I think things get interesting: there's chatter about how there's nothing really all that new about what the iPhone 6 does: it has all of the features that Samsung phones do from two years ago.  And it's absolutely true: NFC has existed for 10+ years, so there's nothing new here.  Call it the Android fanboy in me that sees that on paper, it's a hilarious 1:1 match for a Samsung Galaxy Note...from 2012.

However, the innovation is not in features, it's not in specs.  Apple innovates on user experiences.  Did no one learn anything about Mac specs always being slightly behind PCs?  It wasn't about how many gigahertz the processor was clocked at, or how much RAM it sported, it was "how pleasant is this thing to use?", "how much of my time does it take to maintain?", or "what apps all come for free?"

I think the same applies to the iPhone 6:  it's not about how Android phones had NFC years ago -- they did, as did many other implementations a decade ago -- but rather the user experience sucked because no merchants really invested in accepting it.  How useful is an NFC feature if no store takes it?  Apple's innovation here is getting merchants to lean in and finally do it -- because if their competitor "works with Apple" to adopt NFC and they don't, they look terrible.  Simply by making NFC relevant again, Apple uses their bodyweight and momentum to get others to play ball....innovation without even a drop of technology.

The same goes for the other numerous "copycat" features: larger screen, messaging, apps, photos: they didn't invent this stuff, each feature has already been done, sometimes better, by another competitor.  However, the innovation isn't on the feature: it's on the software experience, and that's what competitors miss.  Messaging is simple and no where near the awfulness that is Hangouts.  Photos are easily taken and easily sync'ed (modulo being hacked) rather than depending on Google+, that you may not want.  I already mentioned NFC.  No bloatware added by the OEM.  And so on and so forth.  The features aren't new, a non-shitty software user experience is.  And that is something that competitors haven't understood for 20 years, even longer than NFC has existed.  (Affectionately known as "it just works")

I won't be buying an iPhone 6 myself -- it costs more for a phone than a laptop for crying out loud, and I live in the Google ecosystem.  But I will attest that Apple is pushing the user experience innovation forward.


Elder Scrolls Online Review

I've been a bit quiet on the blog for a while, and it's mainly because I got my hands on Elder Scrolls Online (an MMO, like World of Warcraft) for the last month or so.  But I'm now done with it.  Since it's on me to catch up on a month-plus of blogging, I'll at least start with my own personal review of ESO.

I feel like reviewing ESO is almost cliche now, since it has been reviewed a gazillion times by a gazillion people.  But I feel like I have to give an on-the-ground view of what the game is like for someone who has limited time to play:  If you can only play when your kids are asleep, is it worth it?  (perhaps I should make a series out of this kind of review?)

First, since I started up after the game launched, I did not have any of the pre-signup issues that people complained about.   That said, I had the "premium" version that let me play a Breton in the Aldmeri Dominion (Elf-land).  After creating my character and stumbling through the intro/training area,  I started hunting around and doing quests in the starting area.

First, I'm glad the quests were not of the typical MMO variety ("kill 10 bears"), which grow boring quickly.  However, quests are still mind-numbingly empty:  simply click through all the discussion-tree options, and then follow the marker on the map to whatever you need to kill or examine.  The story behind every quest is completely inconsequential -- just click through the options and you're done, who cares what they say or what the background of the problem is?  Wash, rinse, repeat.  They could fix this by simply removing the "goal marker" on the map and forcing people to read what they say.  Even those quest choices that make you choose a permanent choice (usually "do you kill this person or not") have little to no difference on results and rewards.

The options for customizing a character through the skill tree are awesome: the options go far, far beyond just what is available to your class, so you can create a bow-wielding battle-mage or a magic-wielding, mace-favoring assassin regardless of what class choice you made.  Seriously, every MMO should let you customize your character this way, rather than forcing you into 2-3 builds that work for your class.  However, having played Skyrim, I wanted a customization tree that was as deep and customizable like Skyrim's.

Crafting is ok, but confusing.  There are a lot of options, and you pick up a lot of crafting ingredients to do every craft.   But it's not clear which one you should do.  It's almost like I felt I had to do all of them because I had so many crafting ingredients.  I ended up creating a lot of my own equipment, but I also just bought a bunch from vendors.  Do I need to do this to max out my character?  Yes?  Maybe?  No?

Which brings me to one of my biggest gripes: no game-wide auction house.  I had a slew of junk that would be useful to someone else that was worthless to me.  But you have to join guilds and then sell only to guildmates who want to buy your stuff.  This is completely worthless, and provides absolutely no value to the game.  I joined guilds just to get access to sell things in their stores, not to socialize or join a group.  I ended up accumulating a stack of gold that I couldn't use to buy anything, and a stack of [crafting] items I couldn't use.  There is no need for this crap in the game, and the designers should simply do away with it.

And speaking of crap, there are bots, and many of them.  This is all over tons of articles, but it was never a big problem for me.  It was annoying getting gold-spam, but at the same time, the spam was for selling me gold I couldn't use because there was no auction house.  Why did botters/spammers choose this game to automate?  Pretty dumb.  It was fun to steal their kills, though.

I didn't get to level 50 before I started trying out PvP, but the game scales up your level.   I was lucky to choose a "campaign" of PvP where my side was winning -- I would jump into the PvP area, try to find a group, and then run to where everyone was fighting.   I liked that PvP was a viable way to earn skill points, stat points, and experience, which is rare for MMOs.  You could just not do the usual PvE experience and still get to 50.  However, I spent most, if not all, of my time in PvP running from a friendly-owned keep to a contested keep.  Die, run back to battle for 10 minutes, die, repeat. Maybe there was some point to getting lots of PvP points, but I got nothing from it, so it was lost on me.  Why would I spend my time on this?  I guess to try to gamble on more items, but what a waste of time.

There also seemed to be few people around.  I tried to do one of the earliest "group" dungeons, and I just couldn't find another living soul who wanted to do it...and I wasn't on a backwater server.   Did the entire world already level up and skip this dungeon?  It seemed so odd, considering in other MMOs (WoW) how the first group dungeon is packed and run by teams repeatedly.  I guess ESO is just a ghost town.

Beyond that, there were "little bugs" that made it hard to play.  Some characters that wouldn't follow or show up.  Switching quickslot actions sometimes wouldn't work.  Rewards for PvP were randomly worthless.  It exposes rough edges that other MMOs have smoothed out.

I didn't renew my subscription to ESO.  I don't care what happens to any of the characters in the story, and PvP is a repetitive grind at best.  There are some cool ideas within: customizing specialization paths, but under the surface, it's not all that unique of an MMO.







Thursday, July 31, 2014

First Try With Google Domains

So I got an invite to use Google Domains, which is Google's new domain registrar service.  I have to say that I'm impressed with how smooth and easy the transaction was.  I realize that it probably sounds biased coming from me, but you may want to check it out for yourself.

The search mechanism was quick and pretty straightforward -- you enter in the site name you want, and it checks the availability...very similar to other registrars.  It makes other suggestions of available names too, nothing shocking there.  I liked some .us domains, but found that you can't register them anonymously, so I went with another that seemed ok -- glennwilson.info.

However, the benefit comes from checking out.  It was smooth to just say "yep, that's it, I'm done" and put in contact/credit card info, and *poof* done.  None of the sneaky upsells or additional charges you normally see with registrars.

Then switching my blog from the standard *.blogspot.com domain over to my new domain was pretty easy too -- I just went to the blog settings, added my new domain under "Blog Address", and then went to my domain account and set up a new CNAME record.  This part was kind of awkward and I had to dig for it in the blogger documentation, and stumbled through creating an arcane DNS thingy, but it didn't take more than a few minutes to do.

Next, I might try to get an app engine instance running on the new domain to see how that works.  In the meantime, kudos to the Google Domains team for a nice product so far.

Saturday, April 26, 2014

All In on a Mac

I thought this day would never come.  After decades of swearing I hated Macs and would never own one, I finally took the plunge and got my own Macbook Pro 15".   For the majority of my lifetime, I swore I would only use "open" and easy-to-hack on (like Windows!  ha ha) systems.   At some point along the way, the value proposition changed, and a Mac became a better choice for coding, gaming, and cost of maintenance.



It wasn't like I didn't try to look at other systems.  Of course, I went straight to Chromebooks first, but knew that I would have to wipe / dualboot it to even get Linux on it, and even then, the modest computing power wouldn't be able to handle heavier applications.  On my way to the Mac counter at Best Buy, I even stopped over at the Windows laptops.  There were dozens of them, all happily running their Windows 8 kiosk-style and not another soul in sight around them -- when I touched one to try to launch the big "weather" app from Metro mode, it then went into "edit your Metro tiles" mode.  Huh?  I just wanted the weather, and clicking on this thing makes me edit my tiles.  Nope, I'm out.

Instead, I plunked down several thousand bucks and walked out with a small, thin white box.  Giddy.

One week in, I have to admit that I'm happier than ever, and I've been extremely surprised by the experience:
  • Finding applications that run on Mac is easy.  Everything I wanted to run, including IDEs I've used before, and games I was playing on my Windows Doorstop all have Mac versions.
  • It had all the "power" of Linux already in it.  I fired up a terminal and checked the version of git.  It was all ready to go out of the box.
  • Navigating around the OS was not a problem.  I always thought "I know where to find everything on a Windows/Linux machine, but not on a Mac." -- turns out, it's just a matter of running the Finder or Launcher. 
  • I was able to easily install Hearthstone and battle.net, and they ran smoothly without even making the fan run.
Even so, there have been a couple of rough edges.  The first thing I did was to reverse the two-finger inverted scroll nonsense.  The App Store concept was weird -- do I buy apps from Apple's store thingy, or just download them from somewhere else?  The number and quality of apps is questionable.  I wanted an IDE to be there, but the closest one was like $70.  Huh?   And the "app still running until you go to Menu -> Quit" is still bizarre to me.  

Anyways, it's been a helluva purchase, and it's helped me get a couple of broken-then-fixed versions of my extension out.  I'm considering my all-in bet a pretty good one so far.

Sunday, April 6, 2014

Back in the Saddle

My next 30 day challenge hasn't gone so well.  It turns out that sometimes it's easier to commit to something larger and execute on it than commit to something smaller that's easily forgotten.  Oh well, I guess I'll just hit the reset button and try something else.

In the meantime, I found out from a friend who uses my spoofer extension that it completely stopped working with Chrome 35 (dev channel).  This usually happens when Chrome changes APIs that extensions can use to do certain things, and indeed, this is what happened.  Looking through all of the chrome.* APIs I was calling, half of them were deprecated and replaced with something else.  So much for a stable development platform.

So this pushed me a bit on releasing my half-baked 1.0.30 version, that was a significant rewrite from 1.0.26.  Thanks to some very cool and helpful G+ commenters, I isolated a couple of bugs in the 1.0.30 version and knew I needed to get back on the horse and start hacking again.

But, there were several problems:  One, all of my source code was on a 5-year-old laptop that is one power supply away from being a doorstop.  Second, none of the source code is under source control.  And last, I had no error reporting in the extension at all -- it could be failing horribly and I would never know.  I set out to change that and learn new stuff along the way.

First, I set up a bitbucket account, where I could have multiple projects for free.  Usually for open-source stuff, people pick github, but I went otherwise because of (a) all of that weird BS going on around github in general, and (b) bitbucket is free.  I also started using git, and tracking / tagging / etc. the source, so that's good.  Second, I polished off an old CodeEnvy account I had and started and connected it to my bitbucket repos and started hacking online (on my Chromebook, naturally)


CodeEnvy has been surprisingly responsive and usable.  I can deploy an app engine app right from the IDE, push and pull from bitbucket, and can edit multiple languages.  I'm impressed with it so far....I daresay it might be something I'd pay for.

Lastly, I started fixing up the bugs in 1.0.30 and implemented a weak (but workable) error reporting system.  It's anonymous, and just reports how often an error occurs.  I don't have it sending anything back yet, but it's a good start.

Also, I think I made a decision on upgrading my workstation to a Macbook Pro 15".  Now, if I can just get the guts to spend $1900 on it...