Tuesday, 16 October 2012

XMPP on Mobile Devices

As with anything, there are no hard and fast rules. If there were, they might look like these. First, for devices:
Transmit no data.
Transmitting costs significant power, and moreover raises the radio state. Not transmitting will allow it to maximize the time spent in the low-cost Idle state.
If you must transmit, then transmit only a small volume.
If there is only a small amount of data transmitted - less than 128 octets typically - the radio will only raise to FACH, which is significantly cheaper than DCH.
If you must transmit, then compress as hard as possible.
Since individual octets have an associate power - and often financial - cost, it's worth maximizing the compression algorithm, even if the volume of traffic will raise to DCH.
If you have transmit a lot, then do a lot
If the radio is raised to DCH anyway, then you may as well go fetch that avatar you were missing, since you're chewing through power anyway.
If you receive, then transmit
If your peer raises the radio state, you may as well use it.
And for servers, similar rules apply:
Send no data.
Sending data will cause the handset to be raised out of Idle. This immediately costs massively higher power.
If you must send, send tiny bits.
Sending small enough data maximizes the likelyhood that the devices radio will only be raised to FACH levels.
If you receive, then send anything you have.
Receiving data indicates that the radio is active - it'll stay active for some time, so sending data doesn't incur the overhead of raising the radio state, and won't increase power drain on the handset.
If you must send when not receiving, send plenty.
Sending data will raise the radio's state - unless you can tell this will only raise it to FACH, it's worth sending as much as possible.

XEP-0286: XMPP on Mobile Devices 
- GSMA: Smart Apps for Smarter Phone

Saturday, 29 September 2012

Move Windows 7 Library folder


  1. create the target Library folder, e.g. D:\music
  2. go to "properties" to make sure the folder is shared (so a network path is showed).
  3. go to "C:/User/xxx/My Music" -> "properties" -> "location", and point it to the target folder created
  4. when asked whether or not the move the folder and everything, confirm with "yes"
  5. now "C:/User/xxx/My Music" will no longer exist, because it's now at the new location; because the target folder is shared already, it can take the network name "My Music" while preserving it's real folder name "D:\music". 

Wednesday, 1 August 2012

REST, SOA

OMG, can't believe people are still debating this in the mid 2011! Move on and get things done, please!

Friday, 27 July 2012

Shiro 1.2 new PasswordService and PasswordMatcher

This becomes super simple and clean.

Here is the summary:

1. Signing-up code:
  // Using the new PasswordService instead
  PasswordService svc = new DefaultPasswordService();

  //e.g. during account signup or password reset:
  String encryptedPassword = svc.encryptPassword(password);
  logger.debug("encryptedPassword: " + encryptedPassword);

  // Salt is not needed to handel separately but encrypted all together within the "password"
  // Example password becomes $shiro1$SHA-256$500000$gTF/EC2mLKxlln2w1CMUAQ==$HvG+0Qe1RONAF41bUy11hjkgqdHrwwf/urEAXeYDt1w=
  User user = new User(username, encryptedPassword, null, email);
  userDao.createUser(user);

 2. INI configuration:
  passwordMatcher = org.apache.shiro.authc.credential.TempFixPasswordMatcher
  # since jdbcRealm is used, the stored password in String needs to be converted to char[]
  # algorithm related configuration comes in default
  passwordService = org.apache.shiro.authc.credential.DefaultPasswordService
  passwordMatcher.passwordService = $passwordService

  realmDS = com.mysql.jdbc.jdbc2.optional.MysqlDataSource
  realmDS.serverName = localhost
  realmDS.user = root
  realmDS.databaseName = test

  jdbcRealm = org.apache.shiro.realm.jdbc.JdbcRealm
  jdbcRealm.credentialsMatcher = $passwordMatcher
  jdbcRealm.authenticationQuery = select password from user where username = ?
  jdbcRealm.dataSource = $realmDS

  securityManager.realm = $jdbcRealm

3. Matcher code
  public class TempFixPasswordMatcher extends PasswordMatcher {

      @Override
      protected Object getStoredPassword(AuthenticationInfo storedAccountInfo) {
          Object stored = super.getStoredPassword(storedAccountInfo);
          if (stored instanceof char[]) {
              return new String((char[])stored);
          }
          return stored;
      }
  }

  source1, source2


Tuesday, 24 July 2012

Shiro @RequiresPermissions not working

@RequiresPermission and other annotations do not work just yet like mentioned in the documentation.

This post gives the solution by explicit configuration of using AOP and cglib.

And don't forget to keep the configuration in the same Spring configuration where MVC annotation scanning is specified. 

Wednesday, 11 July 2012

What's new in Java 7



  • Improved Type Inference for Generic Instance Creation (Diamond)
  • Multi-catch
  • try-with-resources statement
  • Simplified Varargs Method Invocation
  • Strings in switch
  • Polymorphic Methods
  • Miscellaneous

--- source

Tuesday, 10 July 2012

JSON Padding explained

The following is effectively what will happen when using JSON padding in JavaScript.

 <script type="text/javascript">showPrice({symbol: 'IBM', price: 91.42});</script>

  • {...} is the useful JSON data (JavaScript Object formatted) provided by the remote server.
  •  showPrice is the callback function that will need to be defined in the calling script. The padding is also added by the remote server.
  •  In order to achieve all these, the whole lot highlighted will need to be dynamically inserted to the calling script by for example the following:
  <script type="text/javascript">
  // This is our function to be called with JSON data
  function showPrice(data) {
      alert("Symbol: " + data.symbol + ", Price: " + data.price);
  }
  var url = “http://server2.example.com/RetrievePrice?symbol=IBM&jsonp=showPrice”; // URL of the external script
  // this shows dynamic script insertion
  var script = document.createElement('script');
  script.setAttribute('src', url);
 
  // load the script
  document.getElementsByTagName('head')[0].appendChild(script);
  </script>
   
All this is, loosely, due to that JavaScript is not allowed to access foreign domain code, except from within. i.e. "... the domain of the requested URL must be the same as the domain of the current Web page ..." --- source

Monday, 18 June 2012

Getting Sina Weibo (新浪微博) Android demo client to work

The weibo_sdk_source_code_20120307 version uses OAuth 2 to connect to the Weibo platform.

There are commented code for OAuth 1 and xAuth in AuthorizeActivity (and TestActivity accordingly). They are obsolete and don't bother trying to get it to work (at least not OAuth1 as it seems only OAuth 2 is allowed from now on by Sina).  

The OAuth 2 SDK code is very much similar to Facebook's SDK for as much as having been seen. 

The demo itself should just work with only the following change after encountering bizarre behaviors, such as getting "Sorry, the page doesnot exist" after putting down Weibo account login.

    private class WeiboWebViewClient extends WebViewClient {

        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            ...
           
            if (url.startsWith("https://api.weibo.com/oauth2/" + mWeibo.getRedirectUrl())) {
              ...
            }
            ...
        }

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            ...
            if (url.startsWith("https://api.weibo.com/oauth2/" + mWeibo.getRedirectUrl())) {
               ...
            }
            ...
        }

        ...
    } 

Otherwise, mWeibo.getReidrectUrl always returns the callback url and the condition is never ture, so handleRedirectUrl is never called and further callbacks never get back up.

Update: Also the documentation (.docx) of the example authorization steps are again out of date and only compatible with OAuth 1.

Very poorly maintained code and documentation!

Sunday, 18 March 2012

OpenSUSE NetworkManager doesn't switch on

NetworkManager cannot switch on WiFi interface. The switch jumps back to "off" immediately.

But the WiFi is actually working fine manually with wpa_supplicant followed by "dhcpcd wlan0".

Turned out the solution is to:
  • add "blacklist acer-wmi" to /etc/modprobe.d/50-blacklist.conf
  • reboot

Then the NetworkManager works perfectly.

Saturday, 17 March 2012

Remote access to OpenSUSE

ssh

  • enable sshd with Runlevel
  • allow it with Firewall
Samba
  • Allow Samba Server, Client and Netbios with Firewall
  • Configure Samba Server:
    • Start at Boot time
    • Open port in Firewall
    • Allow Users to Share Their Directories
    • Default workgroup: WORKGROUP
    • Not a Domain Controller
  • Add current user to Users group
  • command line: 
    • sudo smbpasswd -a [user]
    • give password
  • e.g. connect from Mac, in Finder, Ctrl+K, smb://[ip]

Video upside down/inverted in Skype, Cheese

libv4l allows controlling the orientation of the image.

The solution is to set the control of the image orientation and load up libv4l for Cheese or Skype.
#!/bin/bash  
export LIBV4LCONTROL_FLAGS=2 
LD_PRELOAD=/usr/lib/libv4l/v4l1compat.so /usr/bin/cheese
2 flips the image horizontally and 3 flips both vertically and horizontally.