Wednesday, November 16, 2016

Windows 10 Anniversary Update on ASUS R2H - "End of the Road"

    I remember I started this blog almost exactly 10 years ago all excited by the advent of mini-tablets in the form or UMPCs, with a first post from the actual device.

    My ASUS R2H came with Windows XP Tablet Edition, qualifying for a free upgrade to Windows Vista, followed by quite a number of pre-release, preview, trial and final versions of Windows 7, Windows 8 and 8.1, and finally Windows 10. In spite of the fact that the actual support from ASUS and Intel ended with Windows Vista, it has been possible to run for much longer thanks to Windows support for legacy devices from Microsoft.

    It is finally time to declare End of the Road for Windows with so appropriately release named: Windows 10 Anniversay Update (version 1607, build 14393.447)


    ASUS R2H-BG059T


    Windows 10 Anniversary Update
    version 1607, build 14393.447


     ➤  Graphics 


           Graphics performance of the old Intel GMA 900 is quite poor with Microsoft Basic Display Adapter driver (v10.0.14393.0, 21 Jun 2006).

           ASUS graphics driver for Windows Vista (v6.14.10.4764, 15 Mar 2007) will not install anymore, XPDM (XP Display Model) drivers are not supported starting with Windows 8.

    ➤  Touch screen


          Calibrate using Digitiser Calibration Tool (tabcal.exe)

    ➤  Audio

     
          ASUS audio driver for Windows Vista (v6.10.1.6030, 15 Mar 2007)

    ➤  Webcam


         ASUS camera driver for Windows Vista (for Bison v6.32.0.04.2, 10 Sep 2007 or otherwise choose your own from the driver download page)

    ➤  Thumbstick


         ASUS touchpad driver for Windows Vista (v9.1.5.0, 25 Jan 2007)

    ➤  Fingerprint


           Works fine with Windows (AuthenTec) driver (v3.4.4.84, 11 Oct 2012). Enrol your fingerprint(s) in Settings > Accounts > Sign-In Options. Fingerprint Set Up button might be disabled if you haven't configured a text password yet - should do that first and then come back to it.

     

    ➤  Bluetooth


         Works fine with generic Microsoft driver (10.0.14393.351, 21 Jun 2006). ASUS Bluetooth driver for Windows Vista (v5.10.02, 12 Feb 2007) would not install.

     

    ➤  WiFi


         Works with Windows (Atheros) provided driver (v2.2.0.27, 29 Jul 2008). You can install ASUS Wireless driver for Windows Vista (v2.0.0.130, 17 Aug 2007) but after installing ASUS Wireless Console (v2.0.8, 7 Mar 2007)

     

    ➤  Ethernet


         Works with Windows (Realtek) provided driver (v10.9.422.2016, 22 Apr 2016). You may try to install the ASUS LAN driver for Windows Vista (V6.190.115.2007, 24 Jul 2007).


    ➤  GPS


         Enable GPS receiver (NMEA 0183 on COM1, 4800 baud) with device_switch.exe part of ASUS Device Switch (v1.0.0.1, 25 Jul 2007) or the open source eqivalent gpsCtrl.exe (dandar3/ASUS-R2H-gpsCtrl on GitHub).

    Tested with GPSDirect (Sensor Driver > Install, followed by Tests > Sensor Explorer On) and MTTTY Serial Terminal (COM1, 4800, 8-N-1, followed by File > Connect).





      Saturday, November 5, 2016

      Eclipse: Integrate Firebase Analytics into your Android app

      With official support moving away from Eclipse towards Android Studio and Gradle, new things like Firebase Analytics have become unavailable to developers wanting to continue using Eclipse for their app development. In this post, I will go through the libraries and the configuration required so you can integrate it in your Eclipse project.


      Firebase Analytics libraries

       

      dandar3/android-google-firebase-README project (GitHub) gives you an overview of the available Firebase libraires ready to use with your Eclipse project. Have a look at the two YouTube videos at the end covering the installation of the Subversive plugin and the steps to easily import an entire project set like Firebase Analytics into your workspace.

      You will observe compile errors like Tag ... attribute name has invalid character '$' after importing libraries like android-google-firebase-iid or android-google-firebase-common. To resolve the issue you will have to manually replace ${applicationId} with your application id (Java package) in all AndroidManifest.xml files (use CTRL+H > File Search >  Replace...


      Importing google-services.json

       

      There is no Eclipse plugin to do the work that the Google Services Gradle plugin does for Android Studio (I have started working on one, but I can't say when this will be available), so you would have to read the Firebase documentation and follow the Processing the JSON File information to manually create your own values.xml.

      If you're having trouble with getting this right you could use Android Studio to import firebase/quickstart-android GitHub project, deploy your google-services.json into it and then copy the generated values.xml out.
       
      You can also try the web conversion tool I wrote, the conversion is done in your browser through JavaScript like you would do it manually. You need to download your google-services.json from Firebase Console, then use the tool to open it and will generate your values.xml just like you would manually do it.
      <?xml version="1.0" encoding="utf-8"?>
      <resources>
          <string name="default_web_client_id" translatable="false">{YOUR_CLIENT}/oauth_client/[first client_type 3]</string>
          <string name="gcm_defaultSenderId"   translatable="false">project_info/project_number</string>
          <string name="firebase_database_url" translatable="false">project_info/firebase_url</string>
          <string name="google_app_id"         translatable="false">{YOUR_CLIENT}/client_info/mobilesdk_app_id</string>
          <string name="google_api_key"        translatable="false">{YOUR_CLIENT}/services/api_key/current_key</string>
          <string name="google_storage_bucket" translatable="false">project_info/storage_bucket</string>
      </resources>


      AndroidManifest.xml changes


      This is the undocumented part that can only be observed by looking at the AndroidManifest.xml generated by Google Services Gradle plugin (app\intermediates\manifests\full\debug\AndroidManifest.xml).
      <?xml version="1.0" encoding="utf-8"?>
      <manifest>
          [...]
      
          <!-- Required permission for App measurement to run. -->
          <uses-permission android:name="android.permission.INTERNET" />
          <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
          <uses-permission android:name="android.permission.WAKE_LOCK" />
          <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
          <permission
              android:name="${applicationId}.permission.C2D_MESSAGE"
              android:protectionLevel="signature" />
          <uses-permission android:name="${applicationId}.permission.C2D_MESSAGE" /> 
       
          <application>
              [...]
       
              <receiver
                  android:name="com.google.android.gms.measurement.AppMeasurementReceiver"
                  android:enabled="true"
                  android:exported="false" >
              </receiver> 
      
              <receiver
                  android:name="com.google.android.gms.measurement.AppMeasurementInstallReferrerReceiver"
                  android:enabled="true"
                  android:permission="android.permission.INSTALL_PACKAGES" >
                  <intent-filter>
                      <action android:name="com.android.vending.INSTALL_REFERRER" />
                  </intent-filter>
              </receiver>
      
              <service
                  android:name="com.google.android.gms.measurement.AppMeasurementService"
                  android:enabled="true"
                  android:exported="false" />
      
              <meta-data
                  android:name="com.google.android.gms.version"
                  android:value="@integer/google_play_services_version" />
      
              <provider
                  android:name="com.google.firebase.provider.FirebaseInitProvider"
                  android:authorities="${applicationId}.firebaseinitprovider"
                  android:exported="false"
                  android:initOrder="100" />
      
              <receiver
                  android:name="com.google.firebase.iid.FirebaseInstanceIdReceiver"
                  android:exported="true"
                  android:permission="com.google.android.c2dm.permission.SEND" >
                  <intent-filter>
                      <action android:name="com.google.android.c2dm.intent.RECEIVE" />
                      <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
      
                      <category android:name="${applicationId}" />
                  </intent-filter>
              </receiver>
      
              <!--
                  Internal (not exported) receiver used by the app to start its own exported services
                  without risk of being spoofed.
                -->
              <receiver
                  android:name="com.google.firebase.iid.FirebaseInstanceIdInternalReceiver"
                  android:exported="false" /> 
      
              <!-- 
                  FirebaseInstanceIdService performs security checks at runtime,
                  no need for explicit permissions despite exported="true"
                -->
              <service
                  android:name="com.google.firebase.iid.FirebaseInstanceIdService"
                  android:exported="true" >
                  <intent-filter android:priority="-500" >
                      <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
                  </intent-filter>
              </service>
          </application>
      </manifest>

      Without these changes you would get all sorts of errors in logcat when running your app, some of them listed  below:
      11-04 15:56:22.970 E/FA      ( 1539): AppMeasurementReceiver not registered/enabled
      11-04 15:56:22.971 E/FA      ( 1539): AppMeasurementService not registered/enabled
      ...
      11-04 16:01:23.188 W/FA      ( 1694): Failed to retrieve Firebase Instance Id
      ...
      11-04 16:01:36.391 E AndroidRuntime: Process: com.google.firebase.quickstart.analytics, PID: 1718
      11-04 16:01:36.391 E AndroidRuntime: java.lang.RuntimeException: Unable to start receiver com.google.android.gms.measurement.AppMeasurementReceiver: 
                                           java.lang.SecurityException: Neither user 10067 nor current process has android.permission.WAKE_LOCK.


      Testing

       

      Enable verbose / debug logging for Firebase Analytics (docs):
      adb logcat -c 
      adb shell setprop log.tag.FA VERBOSE
      adb shell setprop log.tag.FA-SVC VERBOSE
      adb logcat -v time -s FA FA-SVC

      If everything looks fine you may notice the upload scheduling is nothing close to Google Analytics (1h to 12h) - Steve Ganem, Product Manager at Firebase Analytics, confirms on StackOverflow he is aware of the need for quicker reporting.
      11-05 21:01:21.560 V/FA      ( 1418): Upload scheduled in approximately ms: 3599998

      One way to trigger the initial upload found by Yapaxi user on the same thread, is to Clear data for your app. That will not make the information immediately on the Firebase Console web app, it could take up to an hour or more before the reports are made available.
      --------- beginning of system
      --------- beginning of main
      11-05 21:25:17.413 I/FA      ( 1761): App measurement is starting up, version: 9877
      11-05 21:25:17.413 I/FA      ( 1761): To enable debug logging run: adb shell setprop log.tag.FA VERBOSE
      11-05 21:25:17.413 D/FA      ( 1761): Debug-level message logging enabled
      11-05 21:25:17.413 D/FA      ( 1761): AppMeasurement singleton hash: 96720111
      11-05 21:25:17.418 V/FA      ( 1761): Collection enabled
      11-05 21:25:17.418 V/FA      ( 1761): App package, google app id: com.google.firebase.quickstart.analytics, 1:348775509088:android:a9b2141120408d37
      [...]
      11-05 21:25:27.931 V/FA      ( 1761): Uploading data. app, uncompressed size, data: com.google.firebase.quickstart.analytics, 445,
      11-05 21:25:27.931 V/FA      ( 1761): batch {
      11-05 21:25:27.931 V/FA      ( 1761):   bundle {
      11-05 21:25:27.931 V/FA      ( 1761):     protocol_version: 1
      11-05 21:25:27.931 V/FA      ( 1761):     platform: android
      11-05 21:25:27.931 V/FA      ( 1761):     gmp_version: 9877
      11-05 21:25:27.931 V/FA      ( 1761):     uploading_gmp_version: 9877
      11-05 21:25:27.931 V/FA      ( 1761):     config_version: 1477992761690000
      11-05 21:25:27.931 V/FA      ( 1761):     gmp_app_id: 1:348775509088:android:a9b2141120408d37
      11-05 21:25:27.931 V/FA      ( 1761):     app_id: com.google.firebase.quickstart.analytics
                                                [...]
      11-05 21:25:27.931 V/FA      ( 1761):   }
      11-05 21:25:27.931 V/FA      ( 1761): }
      11-05 21:25:27.931 V/FA      ( 1761): Uploading data. size: 431
      11-05 21:25:28.039 V/FA      ( 1761): Upload scheduled in approximately ms: 3599999
      11-05 21:25:28.042 V/FA      ( 1761): Successful upload. Got network response. code, size: 204, 0
      

      That's it - check your data up on Firebase Console an hour or so later.