Monthly Archives: January 2014

[Scheduled release] A new activity stream in Drive shows you what’s changed

Over the next few days, you’ll notice a new activity stream in Drive. When you open Drive, click the “Details and activity” button (ⓘ) on the top right corner and the activity stream will appear, showing you who has taken action on files and folders in My Drive. You’ll see a rundown of what your team has been doing, such as editing and commenting on notes, adding a new spreadsheet, renaming a presentation, etc. If you select a specific file or folder, the stream will change to show you specific information about that item.

Release track:
Scheduled release

Editions included: 
Google Apps for Business, Education, and Government

For more information:
https://support.google.com/drive/answer/3323935
http://googledrive.blogspot.com/2014/01/a-new-activity-stream-in-drive-shows.html

whatsnew.googleapps.com
Get these product update alerts by email
Subscribe to the RSS feed of these updates

Hijacked Chrome extensions cleanup

We have found that some Chrome extensions come bundled with malicious programs that try to hijack your browser settings. To help keep your browser settings under your control we added a “reset browser settings” button to Chrome’s settings page in October.

Despite this, settings hijacking remains our number one user complaint. To make sure the reset option reaches everyone who might need it, Chrome will be prompting Windows users whose settings appear to have been changed if they’d like to restore their browser settings back to factory default. If you’ve been affected by settings hijacking and would like to restore your settings, just click “Reset” on the prompt when it appears.

Note that this will disable any extensions, apps and themes you have installed. If you’d like to reactivate any of your extensions after the reset, you can find and re-enable them by looking in the Chrome menu under “More tools > Extensions.” Apps are automatically re-enabled the next time you use them.

Editions included: 
Google Apps for Business, Education, and Government

For more information:
http://chrome.blogspot.com/2014/01/clean-up-your-hijacked-settings.html
http://chrome.blogspot.com/2013/10/dont-mess-with-my-browser.html

whatsnew.googleapps.com
Get these product update alerts by email
Subscribe to the RSS feed of these updates

Process Stats: Understanding How Your App Uses RAM

Posted by Dianne Hackborn, Android framework team

Android 4.4 KitKat introduced a new system service called procstats that helps you better understand how your app is using the RAM resources on a device. Procstats makes it possible to see how your app is behaving over time — including how long it runs in the background and how much memory it uses during that time. It helps you quickly find inefficiencies and misbehaviors in your app that can affect how it performs, especially when running on low-RAM devices.

You can access procstats data using an adb shell command, but for convenience there is also a new Process Stats developer tool that provides a graphical front-end to that same data. You can find Process Stats in Settings > Developer options > Process Stats.

In this post we’ll first take a look at the Process Stats graphical tool, then dig into the details of the memory data behind it, how it's collected, and why it's so useful to you as you analyze your app.

Process Stats overview of memory used by background processes over time.

Looking at systemwide memory use and background processes

When you open Process Stats, you see a summary of systemwide memory conditions and details on how processes are using memory over time. The image at right gives you an example of what you might see on a typical device.

At the top of the screen we can see that:

  • We are looking at that data collected over the last ~3.5 hours.
  • Currently the device’s RAM is in good shape ("Device memory is currently normal").
  • During that entire time the memory state has been good — this is shown by the green bar. If device memory was getting low, you would see yellow and red regions on the left of the bar representing the amount of total time with low memory.

Below the green bar, we can see an overview of the processes running in the background and the memory load they've put on the system:

  • The percentage numbers on the right indicate the amount of time each process has spent running during the total duration.
  • The blue bars indicate the relative computed memory load of each process. (The memory load is runtime*avg_pss, which we will go into more detail on later.)
  • Some apps may be listed multiple times, since what is being shown is processes (for example, Google Play services runs in two processes). The memory load of these apps is the sum of the load of their individual processes.
  • There are a few processes at the top that have all been running for 100% of the time, but with different weights because of their relative memory use.

Analyzing memory for specific processes

The example shows some interesting data: we have a Clock app with a higher memory weight than Google Keyboard, even though it ran for less than half the time. We can dig into the details of these processes just by tapping on them:

Process Stats memory details for Clock and Keyboard processes over the past 3.5 hours.

The details for these two processes reveal that:

  • The reason that Clock has been running at all is because it is being used as the current screen saver when the device is idle.
  • Even though the Clock process ran for less than half the time of the Keyboard, its ram use was significantly larger (almost 3x), which is why its overall weight is larger.

Essentially, procstats provides a “memory use” gauge that's much like the storage use or data use gauges, showing how much RAM the apps running in the background are using. Unlike with storage or data, though, memory use is much harder to quantify and measure, and procstats uses some tricks to do so. To illustrate the complexity of measuring memory use, consider a related topic: task managers.

Understanding task managers and their memory info

We’ve had a long history of task managers on Android. Android has always deeply supported multitasking, which means the geeky of us will tend to want to have some kind of UI for seeing and controlling this multitasking like the traditional UI we are used to from the desktop. However, multitasking on Android is actually quite a bit more complicated and fundamentally different than on a traditional desktop operating system, as I previously covered in Multitasking the Android Way. This deeply impacts how we can show it to the user.

Multitasking and continuous process management

To get a feel for just how different process management is on Android, you can take a look at the output of an important system service, the activity manager, with adb shell dumpsys activity. The example below shows a snapshot of current application processes on Android 4.4, listing them from most important to least:

ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)
Process LRU list (sorted by oom_adj, 22 total, non-act at 2, non-svc at 2):
  PERS #21: sys   F/ /P  trm: 0 23064:system/1000 (fixed)
  PERS #20: pers  F/ /P  trm: 0 23163:com.android.systemui/u0a12 (fixed)
  PERS #19: pers  F/ /P  trm: 0 23344:com.nuance.xt9.input/u0a77 (fixed)
  PERS #18: pers  F/ /P  trm: 0 23357:com.android.phone/1001 (fixed)
  PERS #17: pers  F/ /P  trm: 0 23371:com.android.nfc/1027 (fixed)
  Proc # 3: fore  F/ /IB trm: 0 13892:com.google.android.apps.magazines/u0a59 (service)
    com.google.android.apps.magazines/com.google.apps.dots.android.app.service.SyncService<=Proc{23064:system/1000}
  Proc # 2: fore  F/ /IB trm: 0 23513:com.google.process.gapps/u0a8 (provider)
    com.google.android.gsf/.gservices.GservicesProvider<=Proc{13892:com.google.android.apps.magazines/u0a59}
  Proc # 0: fore  F/A/T  trm: 0 24811:com.android.settings/1000 (top-activity)
  Proc # 4: vis   F/ /IF trm: 0 23472:com.google.process.location/u0a8 (service)
    com.google.android.backup/.BackupTransportService<=Proc{23064:system/1000}
  Proc #14: prcp  F/ /IF trm: 0 23298:com.google.android.inputmethod.latin/u0a57 (service)
    com.google.android.inputmethod.latin/com.android.inputmethod.latin.LatinIME<=Proc{23064:system/1000}
  Proc # 1: home  B/ /HO trm: 0 23395:com.android.launcher/u0a13 (home)
  Proc #16: cch   B/ /CA trm: 0 23966:com.google.android.deskclock/u0a36 (cch-act)
  Proc # 6: cch   B/ /CE trm: 0 7716:com.google.android.music:main/u0a62 (cch-empty)
  Proc # 5: cch   B/ /CE trm: 0 8644:com.google.android.apps.docs/u0a39 (cch-empty)
  Proc # 8: cch+2 B/ /CE trm: 0 5131:com.google.android.youtube/u0a78 (cch-empty)
  Proc # 7: cch+2 B/ /CE trm: 0 23338:com.google.android.gms/u0a8 (cch-empty)
  Proc #10: cch+4 B/ /CE trm: 0 8937:com.google.android.apps.walletnfcrel/u0a24 (cch-empty)
  Proc # 9: cch+4 B/ /CE trm: 0 24689:com.google.android.apps.plus/u0a70 (cch-empty)
  Proc #15: cch+6 B/ /S  trm: 0 23767:com.google.android.apps.currents/u0a35 (cch-started-services)
  Proc #13: cch+6 B/ /CE trm: 0 9115:com.google.android.gm/u0a44 (cch-empty)
  Proc #12: cch+6 B/ /S  trm: 0 7738:android.process.media/u0a6 (cch-started-services)
  Proc #11: cch+6 B/ /CE trm: 0 8922:com.google.android.setupwizard/u0a19 (cch-empty)

Example output of dumpsys activity command, showing all processes currently running.

There are a few major groups of processes here — persistent system processes, the foreground processes, background processes, and finally cached processes — and the category of a process is extremely important for understanding its impact on the system.

At the same time, processes on this list change all of the time. For example, in the snapshot above we can see that “com.google.android.gm” is currently an important process, but that is because it is doing a background sync, something the user would not generally be aware of or want to manage.

Snapshotting per-process RAM use

The traditional use of a task manager is closely tied to RAM use, and Android provides a tool called meminfo for looking at a snapshot of current per-process RAM use. You can access it with the command adb shell dumpsys meminfo. Here's an example of the output.

Total PSS by OOM adjustment:
    31841 kB: Native
               13173 kB: zygote (pid 23001)
                4372 kB: surfaceflinger (pid 23000)
                3721 kB: mediaserver (pid 126)
                3317 kB: glgps (pid 22993)
                1656 kB: drmserver (pid 125)
                 995 kB: wpa_supplicant (pid 23148)
                 786 kB: netd (pid 121)
                 518 kB: sdcard (pid 132)
                 475 kB: vold (pid 119)
                 458 kB: keystore (pid 128)
                 448 kB: /init (pid 1)
                 412 kB: adbd (pid 134)
                 254 kB: ueventd (pid 108)
                 238 kB: dhcpcd (pid 10617)
                 229 kB: tf_daemon (pid 130)
                 200 kB: installd (pid 127)
                 185 kB: dumpsys (pid 14207)
                 144 kB: healthd (pid 117)
                 139 kB: debuggerd (pid 122)
                 121 kB: servicemanager (pid 118)
    48217 kB: System
               48217 kB: system (pid 23064)
    49095 kB: Persistent
               34012 kB: com.android.systemui (pid 23163 / activities)
                7719 kB: com.android.phone (pid 23357)
                4676 kB: com.android.nfc (pid 23371)
                2688 kB: com.nuance.xt9.input (pid 23344)
    24945 kB: Foreground
               24945 kB: com.android.settings (pid 24811 / activities)
    17136 kB: Visible
               14026 kB: com.google.process.location (pid 23472)
                3110 kB: com.android.defcontainer (pid 13976)
     6911 kB: Perceptible
                6911 kB: com.google.android.inputmethod.latin (pid 23298)
    14277 kB: A Services
               14277 kB: com.google.process.gapps (pid 23513)
    26422 kB: Home
               26422 kB: com.android.launcher (pid 23395 / activities)
    21798 kB: B Services
               16242 kB: com.google.android.apps.currents (pid 23767)
                5556 kB: android.process.media (pid 7738)
   145869 kB: Cached
               41588 kB: com.google.android.apps.plus (pid 24689)
               21417 kB: com.google.android.deskclock (pid 23966 / activities)
               14463 kB: com.google.android.apps.docs (pid 8644)
               14303 kB: com.google.android.gm (pid 9115)
               11014 kB: com.google.android.music:main (pid 7716)
               10688 kB: com.google.android.apps.magazines (pid 13892)
               10240 kB: com.google.android.gms (pid 23338)
                9882 kB: com.google.android.youtube (pid 5131)
                8807 kB: com.google.android.apps.walletnfcrel (pid 8937)
                3467 kB: com.google.android.setupwizard (pid 8922)

Total RAM: 998096 kB
 Free RAM: 574945 kB (145869 cached pss + 393200 cached + 35876 free)
 Used RAM: 392334 kB (240642 used pss + 107196 buffers + 3856 shmem + 40640 slab)
 Lost RAM: 30817 kB
   Tuning: 64 (large 384), oom 122880 kB, restore limit 40960 kB (high-end-gfx)

Example output of dumpsys meminfo command, showing memory currently used by running processes.

We are now looking at the same processes as above, again organized by importance, but now with on their impact on RAM use.

Usually when we measure RAM use in Android, we do this with Linux’s PSS (Proportional Set Size) metric. This is the amount of RAM actually mapped into the process, but weighted by the amount it is shared across processes. So if there is a 4K page of RAM mapped in to two processes, its PSS amount for each process would be 2K.

The nice thing about using PSS is that you can add up this value across all processes to determine the actual total RAM use. This characteristic is used at the end of the meminfo report to compute how much RAM is in use (which comes in part from all non-cached processes), versus how much is "free" (which includes cached processes).

Task-manager style memory info, showing a snapshot of memory used by running apps.

Task manager UI based on PSS snapshot

Given the information we have so far, we can imagine various ways to present this in a somewhat traditional task manager UI. In fact, the UI you see in Settings > Apps > Running is derived from this information. It shows all processes running services (“svc” adjustment in the LRU list) and on behalf of the system (the processes with a “<=Proc{489:system/1000}” dependency), computing the PSS RAM for each of these and any other processes they have dependencies on.

The problem with visualizing memory use in this way is that it gives you the instantaneous state of the apps, without context over time. On Android, users don’t directly control the creation and removal of application processes — they may be kept for future use, removed when the system decides, or run in the background without the user explicitly launching them. So looking only at the instantaneous state of memory use only, you would be missing important information about what is actually going on over time.

For example, in our first look at the process state we see the com.google.android.apps.magazines process running for a sync, but when we collected the RAM use right after that it was no longer running in the background but just being kept around as an old cached process.

To address this problem, the new procstats tool continually monitors the state of all application processes over time, aggregating that information and collecting PSS samples from those processes while doing so. You can view the raw data being collected by procstats with the command adb shell dumpsys procstats.

Seeing memory use over time with procstats

Let’s now go back to procstats and take a look at the context it provides by showing memory use over time. We can use the command adb shell dumpsys procstats --hours 3 to output memory information collected over the last 3 hours. This is the same data as represented graphically in the first Process Stats example.

The output shows all of the processes that have run in the last 3 hours, sorted with the ones running the most first. (Processes in a cached state don’t count for the total time in this sort.) Like the initial graphical representation, we now clearly see a big group of processes that run all of the time, and then some that run occasionally — this includes the Magazines process, which we can now see ran for 3.6% of the time over the last 3 hours.

  * com.google.android.inputmethod.latin / u0a57:
           TOTAL: 100% (6.4MB-6.7MB-6.8MB/5.4MB-5.4MB-5.4MB over 21)
          Imp Fg: 100% (6.4MB-6.7MB-6.8MB/5.4MB-5.4MB-5.4MB over 21)
  * com.google.process.gapps / u0a8:
           TOTAL: 100% (12MB-13MB-14MB/10MB-11MB-12MB over 211)
          Imp Fg: 0.11%
          Imp Bg: 0.83% (13MB-13MB-13MB/11MB-11MB-11MB over 1)
         Service: 99% (12MB-13MB-14MB/10MB-11MB-12MB over 210)
  * com.android.systemui / u0a12:
           TOTAL: 100% (29MB-32MB-34MB/26MB-29MB-30MB over 21)
      Persistent: 100% (29MB-32MB-34MB/26MB-29MB-30MB over 21)
  * com.android.phone / 1001:
           TOTAL: 100% (6.5MB-7.1MB-7.6MB/5.4MB-5.9MB-6.4MB over 21)
      Persistent: 100% (6.5MB-7.1MB-7.6MB/5.4MB-5.9MB-6.4MB over 21)
  * com.nuance.xt9.input / u0a77:
           TOTAL: 100% (2.3MB-2.5MB-2.7MB/1.5MB-1.5MB-1.5MB over 21)
      Persistent: 100% (2.3MB-2.5MB-2.7MB/1.5MB-1.5MB-1.5MB over 21)
  * com.android.nfc / 1027:
           TOTAL: 100% (4.2MB-4.5MB-4.6MB/3.2MB-3.2MB-3.3MB over 21)
      Persistent: 100% (4.2MB-4.5MB-4.6MB/3.2MB-3.2MB-3.3MB over 21)
  * com.google.process.location / u0a8:
           TOTAL: 100% (13MB-13MB-14MB/10MB-11MB-11MB over 21)
          Imp Fg: 100% (13MB-13MB-14MB/10MB-11MB-11MB over 21)
  * system / 1000:
           TOTAL: 100% (42MB-46MB-56MB/39MB-42MB-48MB over 21)
      Persistent: 100% (42MB-46MB-56MB/39MB-42MB-48MB over 21)
  * com.google.android.apps.currents / u0a35:
           TOTAL: 100% (16MB-16MB-16MB/14MB-14MB-14MB over 17)
         Service: 100% (16MB-16MB-16MB/14MB-14MB-14MB over 17)
  * com.android.launcher / u0a13:
           TOTAL: 77% (25MB-26MB-27MB/22MB-23MB-24MB over 73)
             Top: 77% (25MB-26MB-27MB/22MB-23MB-24MB over 73)
          (Home): 23% (25MB-26MB-26MB/23MB-23MB-24MB over 12)
  * android.process.media / u0a6:
           TOTAL: 48% (5.0MB-5.3MB-5.5MB/4.0MB-4.2MB-4.2MB over 11)
          Imp Fg: 0.00%
          Imp Bg: 0.00%
         Service: 48% (5.0MB-5.3MB-5.5MB/4.0MB-4.2MB-4.2MB over 11)
        Receiver: 0.00%
        (Cached): 22% (4.1MB-4.5MB-4.8MB/3.0MB-3.5MB-3.8MB over 8)
  * com.google.android.deskclock / u0a36:
           TOTAL: 42% (20MB-21MB-21MB/18MB-19MB-19MB over 8)
          Imp Fg: 42% (20MB-21MB-21MB/18MB-19MB-19MB over 8)
         Service: 0.00%
        Receiver: 0.01%
        (Cached): 58% (17MB-20MB-21MB/16MB-18MB-19MB over 14)
  * com.android.settings / 1000:
           TOTAL: 23% (19MB-22MB-28MB/15MB-19MB-24MB over 31)
             Top: 23% (19MB-22MB-28MB/15MB-19MB-24MB over 31)
      (Last Act): 77% (9.7MB-14MB-20MB/7.5MB-11MB-18MB over 8)
        (Cached): 0.02%
  * com.google.android.apps.magazines / u0a59:
           TOTAL: 3.6% (10MB-10MB-10MB/8.7MB-9.0MB-9.0MB over 6)
          Imp Bg: 0.03%
         Service: 3.6% (10MB-10MB-10MB/8.7MB-9.0MB-9.0MB over 6)
        (Cached): 17% (9.9MB-10MB-10MB/8.7MB-8.9MB-9.0MB over 5)
  * com.android.defcontainer / u0a5:
           TOTAL: 1.4% (2.7MB-3.0MB-3.0MB/1.9MB-1.9MB-1.9MB over 7)
             Top: 1.2% (3.0MB-3.0MB-3.0MB/1.9MB-1.9MB-1.9MB over 6)
          Imp Fg: 0.19% (2.7MB-2.7MB-2.7MB/1.9MB-1.9MB-1.9MB over 1)
         Service: 0.00%
        (Cached): 15% (2.6MB-2.6MB-2.6MB/1.8MB-1.8MB-1.8MB over 1)
  * com.google.android.youtube / u0a78:
           TOTAL: 1.3% (9.0MB-9.0MB-9.0MB/7.8MB-7.8MB-7.8MB over 1)
          Imp Bg: 1.0% (9.0MB-9.0MB-9.0MB/7.8MB-7.8MB-7.8MB over 1)
         Service: 0.27%
      Service Rs: 0.01%
        Receiver: 0.00%
        (Cached): 99% (9.1MB-9.4MB-9.7MB/7.7MB-7.9MB-8.1MB over 24)
  * com.google.android.gms / u0a8:
           TOTAL: 0.91% (9.2MB-9.2MB-9.2MB/7.6MB-7.6MB-7.6MB over 1)
          Imp Bg: 0.79% (9.2MB-9.2MB-9.2MB/7.6MB-7.6MB-7.6MB over 1)
         Service: 0.11%
        Receiver: 0.00%
        (Cached): 99% (8.2MB-9.4MB-10MB/6.5MB-7.6MB-8.1MB over 25)
  * com.google.android.gm / u0a44:
           TOTAL: 0.56%
          Imp Bg: 0.55%
         Service: 0.01%
        Receiver: 0.00%
        (Cached): 99% (11MB-13MB-14MB/10MB-12MB-13MB over 24)
  * com.google.android.apps.plus / u0a70:
           TOTAL: 0.22%
          Imp Bg: 0.22%
         Service: 0.00%
        Receiver: 0.00%
        (Cached): 100% (38MB-40MB-41MB/36MB-38MB-39MB over 17)
  * com.google.android.apps.docs / u0a39:
           TOTAL: 0.15%
          Imp Bg: 0.09%
         Service: 0.06%
        (Cached): 54% (13MB-14MB-14MB/12MB-12MB-13MB over 17)
  * com.google.android.music:main / u0a62:
           TOTAL: 0.11%
          Imp Bg: 0.04%
         Service: 0.06%
        Receiver: 0.01%
        (Cached): 70% (7.7MB-10MB-11MB/6.4MB-9.0MB-9.3MB over 20)
  * com.google.android.apps.walletnfcrel / u0a24:
           TOTAL: 0.01%
        Receiver: 0.01%
        (Cached): 69% (8.1MB-8.4MB-8.6MB/7.0MB-7.1MB-7.1MB over 13)
  * com.google.android.setupwizard / u0a19:
           TOTAL: 0.00%
        Receiver: 0.00%
        (Cached): 69% (2.7MB-3.2MB-3.4MB/1.8MB-2.0MB-2.2MB over 13)

Run time Stats:
  SOff/Norm: +1h43m29s710ms
  SOn /Norm: +1h37m14s290ms
      TOTAL: +3h20m44s0ms

          Start time: 2013-11-06 07:24:27
  Total elapsed time: +3h42m23s56ms (partial) libdvm.so chromeview

Example output of dumpsys procstats --hours 3 command, showing memory details for processes running in the background over the past ~3 hours.

The percentages tell you how much of the overall time each process has spent in various key states. The memory numbers tell you about memory samples in those states, as minPss-avgPss-maxPss / minUss-avgUss-maxUss. The procstats tool also has a number of command line options to control its output — use adb shell dumpsys procstats -h to see a list of the available options.

Comparing this raw data from procstats with the visualization of its data we previously saw, we can see that it is showing only process run data from a subset of states: Imp Fg, Imp Bg, Service, Service Rs, and Receiver. These are the situations where the process is actively running in the background, for as long as it needs to complete the work it is doing. In terms of device memory use, these are the process states that tend to cause the most trouble: apps running in the background taking RAM from other things.

Getting started with procstats

We have already found the new procstats tool to be invaluable in better understanding the overall memory behavior of Android systems, and it has been a key part of the Project Svelte effort in Android 4.4.

As you develop your own applications, be sure to use procstats and the other tools mentioned here to help understand how your own app is behaving, especially how much it runs in the background and how much RAM it uses during that time.

More information about how to analyze and debug RAM use on Android is available on the developer page Investigating Your RAM Usage.

Building an Enterprise File Server on Google Drive

Editor's note: This is a guest post by Thomas Gerber. Thomas is the CTO of Altirnao, the developer of the AODocs document management app on the Google Apps Marketplace. Thomas tells the story of his application and provides some tips for developers considering integrating with Google Apps and launching on the Marketplace. — Arun Nagarajan


Google Drive is increasingly popular in the enterprise, and many organizations would like to leverage it as a replacement for their existing on-premises file servers. Moving physical file servers to Drive provides many benefits, such as reliability, cost-effectiveness and the ability to access the files from anywhere and any device. However, the storage structure of Google Drive, where files are owned by many different users, is significantly different from the centralized organization of a file server, where everything is under the control of a small number of system administrators.

To address this problem, AODocs uses the Google Drive API to automatically transfer the ownership of files to a system account, and thus create a sort of “managed area” within Google Drive. With the Google Drive API, AODocs has complete control over the folder structure and the permissions of files owned by this system account. AODocs can be deployed in one click from the Google Apps Marketplace, which makes our application visible (and easy to try out!) for every Google Apps administrator in the world.



Companies who want to store their files on Google Drive may be concerned about losing control of their data (e.g. access to files being lost when an employee leaves the company) and controlling sharing permissions.

AODocs uses a single system account (i.e. a Google Apps account belonging to the customer’s domain, but not used by any human person) as a “proxy” to control the files. When a Google Drive files is added to an AODocs library, the ownership of the file is transferred to the AODocs system account and the file’s writersCanShare attribute is set to false, so that only AODocs is able to modify the file’s permissions afterwards.

To change the ownership of the file, we check if the system account can already access the file, and then either insert a new “owner” permission on it or use the Permissions.update method with the transferOwnership flag:

public void changeOwner(String user, String fileId, String newOwner) {
// Find what is the current permission of the new owner on the file
Permission newOwnerPermission = null;
PermissionList permissionList = RetriableTask.execute(new DrivePermissionListTask(drive.permissions().list(fileId)));
newOwnerPermission = findPermission(permissionList, newOwner);

if (newOwnerPermission == null) {
// New owner is not in the list, we need to insert it
newOwnerPermission = new Permission();
newOwnerPermission.setValue(newOwner);
newOwnerPermission.setType("user");
newOwnerPermission.setRole("owner");
Drive.Permissions.Insert insert = drive.permissions().insert(fileId, newOwnerPermission);
RetriableTask.execute(new DrivePermissionInsertTask(insert));
} else {
// New owner is already in the list, update the existing permission
newOwnerPermission.setRole("owner");
Drive.Permissions.Update update = drive.permissions().update(fileId, newOwnerPermission.getId(), newOwnerPermission);
update.setTransferOwnership(true);
RetriableTask.execute(new DrivePermissionUpdateTask(update));
}
}

Since all the files are owned by the system account, AODocs completely controls the lifecycle of the file (how they are created, in which folder they are located, who can change their permissions, who can delete them, etc). AODocs can thus provide higher-level document management features on top of Google Drive, such as configuring the retention time of deleted files, limiting external sharing to a whitelist of “trusted external domains”, or recording an audit log of file modifications.

As illustrated in the code snippet above, AODocs relies on the Google Drive API to perform all the operations on the managed files. The main challenge we had when using the Drive API was to properly handle all the error codes returned by the API calls, and make sure we make the difference between fatal errors that should not be tried again (for example, permission denied on a file) and the temporary errors that should be re-tried later (for example, “rate limit exceeded”). To handle that, we have encapsulated all our Google Drive API calls (we are using the Java client library) into a class named RetriableTask, which is responsible for handling the non-fatal errors and automatically retry the API calls with the proper exponential back-off. Here is a simplified version:

public class RetriableTask implements Callable {
[...]
private final Callable task;

[...]
@Override public T call() {
T result = null;
try {
startTime = System.currentTimeMillis();
result = task.call();
} catch (NonFatalErrorException e) {
if (numberOfTriesLeft > 0) {
// Wait some time, using exponential back-off in case of multiple attempts
Thread.sleep(getWaitTime());

// Try again
result = call();
} else {
// Too many failed attempts: now this is a fatal error
throw new RetryException();
}
} catch (FatalErrorException e) {
// This one should not be retried
Throwables.propagate(e);
}
return result;
}

AODocs is designed to work seamlessly with Google Drive, and our top priority is to leverage all the integration possibilities offered by the Google APIs. We are very excited to see that new features are added very often in the Admin SDK, the Google+ API, the Drive API that will allow AODocs to provide more options to system administrators and improve the experience for our end users.


Thomas Gerber profile

Thomas is the CTO of Altirnao. Before founding Altirnao, Thomas has led a team of senior technologists and architects on High Availability/High Performance implementations of enterprise software.

Driving into our 55th country and updating Russian imagery

With the eyes of winter sports fans turning to Russia, we thought this would be a good time to add more towns, cities and picturesque sights of this sprawling country to Google Maps. From today, Street View is available in Vladivostok, Yakutsk, Irkutsk and, of course, Sochi.

Winter lovers also are treated, for the first time, to images of mountainous Slovenia. This gorgeous Central European country becomes our 55th country to launch Street View.


Map of some of the newly available areas to explore in Russia

In Russia, our drivers reached the far away corners of the world's largest country. Users can take a walk around Yakutsk, the city with the greatest seasonal temperature swings on Earth (the lowest recorded winter temperature was −64.4°C with the highest summer peak hitting 38.4°C).


View Larger Map
Explore the city center of Yakutsk

In total, Street View cars covered 300,000 kilometers in Russia in 2013, an area housing almost 60 percent of the population. We mapped the biggest Russian island of Sakhalin and the Russkiy Bridge, the world's longest cable-stayed bridge. While snapping the M52 highway, also known as Chuya Highway or Chuysky Trakt, Street View drivers met indigenous tribes.

The mapping team faced unusual challenges. When taking imagery of the Tobolsk monastery the drivers spent two days praying with the Monastery Abbot. In order to get to some remote spots, Street View cars were transported in containers on tracks and boats. There was even place for romance: while shooting Sakhalin, one driver met his future wife!


View Larger Map
The Tobolsk Monastery in Tyumen Oblast

We also are launching our imagery in Slovenia. Virtual tourists now can explore cities like Ljubljana, Maribor, Celje, Kranj, and Koper, as well as beautiful places like Bohinj Lake or the sea town of Piran.


View Larger Map
Congress Square, Ljubljana

Enjoy some of these amazing sights on StreetView’s journey eastward through Europe.

Reminder: AdWords API v201306 and Ad Exchange Buyer SOAP API v201306 will sunset on March 31st, 2014

We’d like to remind you that v201306 of the AdWords API and Ad Exchange Buyer SOAP API are scheduled to be sunset on March 31st, 2014. Start your migration to v201309 now to avoid having your API calls fail on the sunset date. If you are still using ClientLogin, we strongly recommend that you also migrate to OAuth2.

The following will help you to migrate to v201309: For migration help, contact us on the AdWords API forum or Ad Exchange Buyer API forum. Our Google+ page is also a great resource for keeping up-to-date with the latest announcements and communicating with us.

Improving Remarketing with Google Analytics: A UI Refresh and List Importing

Last year, we released a new, more powerful version of segmentation, supporting more robust user-centric analysis (recap here).

Now you can achieve the full power of this enhanced segmentation in Remarketing with Google Analytics.

With this overhaul (which is rolling out over the next two weeks), you can more easily create Remarketing lists based on origin, demographics, and behavior to re-engage with your audiences like never before.

New interface under Admin > Remarketing Lists


One of our early users shared their experience so far:

“We have 8 target user segments that we engage with through Eloqua. Google Analytics provides us with a flexible environment to track the behavior of these segments across all incoming traffic channels. Now we can easily import these segments to make our remarketing spend much more effective.” --Oleg Rogynskyy, CEO, Semantria

Got lots of segments that you'd like to act on? No problem. You can now import from your existing segments in the Remarketing list builder. This includes all custom segments you’ve created, plus segments you import from the solutions gallery.


And after importing...


We're excited to release this improvement and make Remarketing with Google Analytics simpler and more powerful.  You can get started by importing the Remarketing Starter pack from the Google Analytics Solutions Gallery.

Stay tuned for more improvements in the coming weeks! 

Posted by Dan Stone, Product Manager, Google Analytics 

Vote for Digital Defender of the Year

For the past 14 years the Index on Censorship Awards have honoured some of the most remarkable fighters for free expression from around the world - from assassinated Russian journalist Anna Politkovskaya to Israeli conductor Daniel Barenboim and Syrian cartoonist Ali Farzat to education activist Malala Yousafzai. Until now, distinguished juries have selected all the winners. But this year, we’re working with Index on an innovation - asking the public to vote for the digital activist award, which honours the person who has done the most to defend online freedom.

Take a look at the nominees and vote here. Voting finishes next Monday, February 3, so please do act fast.

This is the fourth year Google has worked with Index on its annual awards event. Total editorial control remains with Index; they choose the nominees. We are just delighted to support this important organization’s new and important work in defence of online freedom. For a taste of the excitement surrounding the ceremony, watch last year’s highlight video below.



This year’s awards ceremony take place on Thursday March 20, 6.30pm, at the Barbican Centre in London. In addition to the digital defender award, three other awards will be given out, one for journalism, one for advocacy and one for arts. Tickets are available, so please do join us to celebrate free-expression champions and shine a light on their ongoing struggle against censorship around the world.

Ending support for iOS 5 in the IMA SDK

On February 18, 2014, we will stop providing forum support or bug fixes for iOS IMA SDK issues specifically related to iOS 5. This applies to the current beta of the iOS IMA SDK as well as all future releases.

What does this mean if an app is currently targeting iOS 5?

  • There will be no specific SDK change on February 18th that will break compatibility, so the iOS IMA SDK should continue to work with iOS 5 in the short term. However, after that date, the SDK won't be guaranteed to work for iOS 5 apps. 
  • Bugs that only affect iOS 5 will no longer be prioritized. 
  • If a specific iOS IMA SDK release significantly breaks functionality in iOS 5, it will be documented in the release notes
  • This support change will not require you to make any changes to your app specific to the iOS IMA SDK, but you may have to make some changes to your app to set its Deployment Target to iOS 6+. 

What about other iOS versions?

We periodically stop supporting older iOS versions when adoption levels fall below a small threshold. Any time we are preparing to end support for a major iOS release, we will make an early announcement on our blog and release notes page.

If you need any help with iOS IMA SDK issues encountered when targeting your application for iOS 6, or about the iOS IMA SDK in general, let us know on the IMA SDK forum or check out the IMA SDK iOS Quick Start Guide. Follow our Google+ page for other announcements and updates.

The real story behind high-tech jobs

We’ve all heard the damning indictment - technology destroys jobs. While it is true that the digital revolution disrupts the workplace - just as the Industrial Revolution swept away many artisan professions such as weavers - a new report by University of Leuven researchers tells a fascinating story of how the high tech revolution is, surprisingly, creating an explosion in non-high tech jobs in Europe. Indeed, for every one high-tech job created, more than four additional non-high tech jobs are created in the same region.

That’s not the only good news, either. Across the European economy, the high-tech sector is showing impressive signs of growth. The new research shows that high-tech employment grew 20 percent in the EU-27 between 2000-2011, while total employment increased by just eight percent.

Growth in high-tech jobs also has a positive spillover effect in local economies. The presence of high-tech workers in a region is likely to create additional work for a wide range of occupations - from lawyers, doctors and school teachers to taxi drivers, waiters and technicians.

This spillover is not limited to Europe’s biggest economies. While Germany contributed the most to total high-tech employment in Europe, it is relatively unexpected regions in Europe that saw the fastest growth in high-tech jobs. For example, Bratislava, Slovakia is one of the fastest growing regions for high-tech employment, growing at nearly 56 percent from 2000-2011. This contributes to the region’s high level of per-capita income and contrasts with assumptions that high-tech jobs are only in traditional hubs.

Not only is the high-tech sector outperforming other sectors in total employment growth, but its workers enjoy high rates of employment, a substantial wage premium (over 65% in some countries, like Portugual and Romania) and higher wage growth. With many economies struggling with stagnant wages, a vibrant high-tech sector makes a strong contribution to these countries.

So what lessons should we take from these findings?

First, that the EU’s pursuit of high-tech and digital job growth is worthwhile. The Europe 2020 strategy and recent agreements at the European Digital Council provide the opportunity to build on the success of the past ten years to support this vibrant part of the economy.

Second, we know that supporting high-tech jobs will benefit the wider economy. The high-tech sector is generating faster, higher-paying job growth across the EU-27, the knock-on effect of which is positive across the economy.

Third, investing in high-tech and digital skills will pay dividends. The difference in wages between STEM (science, technology, engineering and math) jobs and non-STEM jobs is high right across Europe. And with the high-tech jobs multiplier, supporting skills development in high-tech fields should create benefits beyond traditional high-tech industries.

As these jobs spread across the continent, it is clear that supporting high-tech industries will benefit the whole economy and make a substantial contribution to resolving the unemployment crisis facing many economies.