Commit Graph

593 Commits

Author SHA1 Message Date
Svetoslav Ganov
0d04e24553 Improving accessibility APIs used for UI automation.
1. UiTestAutomationBridge was accessing the root node in the
   active window by tracking the accessibility event stream
   and keeping the last active window changing event. Now
   the bridge is stateless and the root node is fetched by
   passing special window and view id with the request to
   the system.

2. AccessibilityNodeInfos that are cached were not finished,
   i.e. not sealed, causing exception when trying to access
   their children or rpedecessors.

3. AccessibilityManagerService was not properly restoring its
   state after the UI automation bridge disconnects from it.
   I particular the devices was still in explore by touch mode
   event if no services are enabled and the sutomation bridge
   is disconnected.

4. ViewRootImpl for the focused window now fires accessibility
   events when accessibility is enabled to allow accessibility
   services to determine the current user location.

5. Several missing null checks in ViewRootImpl are fixed since
   there were scenraios in which a NPE can occur.

6. Update the internal window content querying tests.

7. ViewRootImpl was firing one extra focus event.
bug:6009813
bug:6026952

Change-Id: Ib2e058d64538ecc268f9ef7a8f36ead047868a05
2012-02-21 17:09:09 -08:00
Jesse Wilson
18c227ba72 Implement the (hidden) ExtendedResponseCache interface.
Bug: http://code.google.com/p/android/issues/detail?id=25418
Change-Id: I4b20d576bac7036f94e57db7124de44f5b8d75be
2012-02-15 16:53:57 -05:00
Svetoslav Ganov
b36a0ac970 Incorrect behavior of View clear focus v2.0.
The framework tries to have a focused view all the time. For
that purpose when a view's focus is cleared the focus is given
to the first focusable found from the top. The implementation
of this behavior was causing the following issues:

1. If the fist focusable View tries to clear its focus it
   was getting focus but the onFocusChange callbacks were not
   properly invoked. Specifically, the onFocusChange for
   gaining focus was called first and then the same
   callback for clearing focus. Note that the callback
   for clearing focus is called when the View is already
   focused.

2. If not the first focusable View tries to clear focus,
   the focus is given to another one but the callback
   for getting focus was called before the one for clearing,
   so client code may be mislead that there is more than
   one focused view at a time.

3. (Nit) The implementaion of clearFocus and unFocus in ViewGroup
   was calling the super implementaion when there is a
   focused child. Since there could be only one focused View,
   having a focused child means that the group is not focused
   and the call to the super implementation is not needed.

4. Added unit tests that verify the correct behavior, i.e.
   the focus of the first focused view cannot be cleared
   which means that no focus change callbacks are invoked.
   The callbacks should be called in expected order.
   Now the view focus clear precedes the view focus gain
   callback. However, in between is invoked the global
   focus change callback with the correct values. We may
   want to call that one after the View callbacks. If
   needed we can revisit this.

Change-Id: I8cfb141c948141703093cf6fa2037be60861cee0
2012-02-14 17:50:51 -08:00
Amith Yamasani
dd29f8c4e3 Merge "Revert "Incorrect behavior of View clear focus."" 2012-02-14 15:52:17 -08:00
Amith Yamasani
73eb97f628 Revert "Incorrect behavior of View clear focus."
This reverts commit c6fd88e213
2012-02-14 15:45:15 -08:00
Svetoslav Ganov
d36ad9b1ff Merge "Adding a method for retching the root node in UiTestAutomationBridge" 2012-02-07 12:07:23 -08:00
Svetoslav Ganov
b765db590f Adding a method for retching the root node in UiTestAutomationBridge
bug:5974791

Change-Id: I46a8b6a259ba31f27fcd6a71d06dc34efdb4de76
2012-02-07 12:05:16 -08:00
Jeff Sharkey
241dde2306 Unify shorthand for byte-based units.
Change-Id: If990859dee3f0973e1d4c48f05312c84071b3328
2012-02-03 14:50:13 -08:00
Amith Yamasani
742a671273 Multi-user - 1st major checkin
Switching activity stacks
Cache ContentProvider per user
Long-press power to switch users (on phone)

Added ServiceMap for separating services by user
Launch PendingIntents on the correct user's uid
Fix task switching from Recents list
AppWidgetService is mostly working.

Commands added to pm and am to allow creating and switching profiles.

Change-Id: I15810e8cfbe50a04bd3323a7ef5a8ff4230870ed
2012-02-03 12:01:47 -08:00
Svetoslav Ganov
2eecea3b48 Merge "Speedup the accessibility window querying APIs and clean up." 2012-02-01 13:45:24 -08:00
Svetoslav Ganov
c6fd88e213 Incorrect behavior of View clear focus.
The framework tries to have a focused view all the time. For
that purpose when a view's focus is cleared the focus is given
to the first focusable found from the top. The implementation
of this behavior was causing the following issues:

1. If the fist focusable View tries to clear its focus it
   was getting focus but the onFocusChange callbacks were not
   properly invoked. Specifically, the onFocusChange for
   gaining focus was called first and then the same
   callback for clearing focus. Note that the callback
   for clearing focus is called when the View is already
   focused. Also note that at the end the View did not
   clear its focus, hence no focus change callbacks
   should be invoked.

2. If not the first focusable View tries to clear focus,
   the focus is given to another one but the callback
   for getting focus was called before the one for clearing,
   so client code may be mislead that there is more than
   one focused view at a time.

3. (Nit) The implementaion of clearFocus and unFocus in ViewGroup
   was calling the super implementaion when there is a
   focused child. Since there could be only one focused View,
   having a focused child means that the group is not focused
   and the call to the super implementation is not needed.

4. Added unit tests that verify the correct behavior, i.e.
   the focus of the first focused view cannot be cleared
   which means that no focus change callbacks are invoked.
   The callbacks should be called in expected order.
   Now the view focus clear precedes the view focus gain
   callback. However, in between is invoked the global
   focus change callback with the correct values. We may
   want to call that one after the View callbacks. If
   needed we can revisit this.

Change-Id: Iee80baf5c75c82d3cda09679e4949483cad475f1
2012-01-25 23:38:31 -08:00
Svetoslav Ganov
36a561b4ee Fixing failing focus tests
Change-Id: I3df6a72f6340cbf2e42ce4913e28471e9358088b
2012-01-25 17:05:04 -08:00
Svetoslav Ganov
79311c4af8 Speedup the accessibility window querying APIs and clean up.
1. Now when an interrogating client requires an AccessibilibtyNodeInfo
   we aggressively prefetch all the predecessors of that node and its
   descendants. The number of fetched nodes in one call is limited to
   keep the APIs responsive. The prefetched nodes infos are cached in
   the client process. The node info cache is invalidated partially or
   completely based on the fired accessibility events. For example,
   TYPE_WINDOW_STATE_CHANGED event clears the cache while
   TYPE_VIEW_FOCUSED removed the focused node from the cache, etc.
   Note that the cache is only for the currently active window.
   The ViewRootImple also keeps track of only the ids of the node
   infos it has sent to each querying process to avoid duplicating
   work. Usually only one process will query the screen content
   but we support the general case. Also all the caches are
   automatically invalidated so not additional bookkeeping is
   required. This simple strategy leads to 10X improving the
   speed of the querying APIs.

2. The Monkey and UI test automation framework  were registering a
   raw event listener for accessibility events and hence perform
   connection and cache management in similar way to an AccessibilityService.
   This is fragile and requires the implementer to know internal framework
   stuff. Now the functionality required by the Monkey and the UI automation
   is encapsulated in a new UiTestAutomationBridge class. To enable this
   was requited some refactoring of AccessibilityService.

3. Removed the *doSomethiong*InActiveWindow methods from the
   AccessibilityInteractionClient and the AccessibilityInteractionConnection.
   The function of these methods is implemented by the not *InActiveWindow
   version while passing appropriate constants.

4. Updated the internal window Querying tests to use the new
   UiTestAutomationBridge.

5. If the ViewRootImple was not initialized the querying APIs of
   the IAccessibilityInteractionConnection implementation were
   returning immediately without calling the callback with null.
   This was causing the client side to wait until it times out. Now
   the client is notified as soon as the call fails.

6. Added a check to guarantee that Views with AccessibilityNodeProvider
   do not have children.

bug:5879530

Change-Id: I3ee43718748fec6e570992c7073c8f6f1fc269b3
2012-01-23 20:13:58 -08:00
Jeff Sharkey
a27a3e8ad7 Introduce FileRotator.
Utility that rotates files over time, similar to logrotate. There is
a single "active" file, which is periodically rotated into historical
files, and eventually deleted entirely. Files are stored under a
specific directory with a well-known prefix.

Bug: 5386531
Change-Id: I29f821a881247e50ce0f6f73b20bbd020db39e43
2012-01-13 15:27:28 -08:00
Jeff Brown
986f00faf4 Merge "Rewrite SQLite database wrappers." 2012-01-12 15:03:26 -08:00
Jeff Brown
156936975d Merge "Fix indentation and whitespace." 2012-01-12 14:59:30 -08:00
Jeff Brown
18c415c3c8 Merge "Clean up database tests a little bit." 2012-01-12 14:59:11 -08:00
Jeff Brown
e5360fbf3e Rewrite SQLite database wrappers.
The main theme of this change is encapsulation.  This change
preserves all existing functionality but the implementation
is now much cleaner.

Instead of a "database lock", access to the database is treated
as a resource acquisition problem.  If a thread's owns a database
connection, then it can access the database; otherwise, it must
acquire a database connection first, and potentially wait for other
threads to give up theirs.  The SQLiteConnectionPool encapsulates
the details of how connections are created, configured, acquired,
released and disposed.

One new feature is that SQLiteConnectionPool can make scheduling
decisions about which thread should next acquire a database
connection when there is contention among threads.  The factors
considered include wait queue ordering (fairness among peers),
whether the connection is needed for an interactive operation
(unfairness on behalf of the UI), and whether the primary connection
is needed or if any old connection will do.  Thus one goal of the
new SQLiteConnectionPool is to improve the utilization of
database connections.

To emulate some quirks of the old "database lock," we introduce
the concept of the primary database connection.  The primary
database connection is the one that is typically used to perform
write operations to the database.  When a thread holds the primary
database connection, it effectively prevents other threads from
modifying the database (although they can still read).  What's
more, those threads will block when they try to acquire the primary
connection, which provides the same kind of mutual exclusion
features that the old "database lock" had.  (In truth, we
probably don't need to be requiring use of the primary database
connection in as many places as we do now, but we can seek to refine
that behavior in future patches.)

Another significant change is that native sqlite3_stmt objects
(prepared statements) are fully encapsulated by the SQLiteConnection
object that owns them.  This ensures that the connection can
finalize (destroy) all extant statements that belong to a database
connection when the connection is closed.  (In the original code,
this was very complicated because the sqlite3_stmt objects were
managed by SQLiteCompiledSql objects which had different lifetime
from the original SQLiteDatabase that created them.  Worse, the
SQLiteCompiledSql finalizer method couldn't actually destroy the
sqlite3_stmt objects because it ran on the finalizer thread and
therefore could not guarantee that it could acquire the database
lock in order to do the work.  This resulted in some rather
tortured logic involving a list of pending finalizable statements
and a high change of deadlocks or leaks.)

Because sqlite3_stmt objects never escape the confines of the
SQLiteConnection that owns them, we can also greatly simplify
the design of the SQLiteProgram, SQLiteQuery and SQLiteStatement
objects.  They no longer have to wrangle a native sqlite3_stmt
object pointer and manage its lifecycle.  So now all they do
is hold bind arguments and provide a fancy API.

All of the JNI glue related to managing database connections
and performing transactions is now bound to SQLiteConnection
(rather than being scattered everywhere).  This makes sense because
SQLiteConnection owns the native sqlite3 object, so it is the
only class in the system that can interact with the native
SQLite database directly.  Encapsulation for the win.

One particularly tricky part of this change is managing the
ownership of SQLiteConnection objects.  At any given time,
a SQLiteConnection is either owned by a SQLiteConnectionPool
or by a SQLiteSession.  SQLiteConnections should never be leaked,
but we handle that case too (and yell about it with CloseGuard).

A SQLiteSession object is responsible for acquiring and releasing
a SQLiteConnection object on behalf of a single thread as needed.
For example, the session acquires a connection when a transaction
begins and releases it when finished.  If the session cannot
acquire a connection immediately, then the requested operation
blocks until a connection becomes available.

SQLiteSessions are thread-local.  A SQLiteDatabase assigns a
distinct session to each thread that performs database operations.
This is very very important.  First, it prevents two threads
from trying to use the same SQLiteConnection at the same time
(because two threads can't share the same session).
Second, it prevents a single thread from trying to acquire two
SQLiteConnections simultaneously from the same database (because
a single thread can't have two sessions for the same database which,
in addition to being greedy, could result in a deadlock).

There is strict layering between the various database objects,
objects at lower layers are not aware of objects at higher layers.
Moreover, objects at higher layers generally own objects at lower
layers and are responsible for ensuring they are properly disposed
when no longer needed (good for the environment).

API layer: SQLiteDatabase, SQLiteProgram, SQLiteQuery, SQLiteStatement.
Session layer: SQLiteSession.
Connection layer: SQLiteConnectionPool, SQLiteConnection.
Native layer: JNI glue.

By avoiding cyclic dependencies between layers, we make the
architecture much more intelligible, maintainable and robust.

Finally, this change adds a great deal of new debugging information.
It is now possible to view a list of the most recent database
operations including how long they took to run using
"adb shell dumpsys dbinfo".  (Because most of the interesting
work happens in SQLiteConnection, it is easy to add debugging
instrumentation to track all database operations in one place.)

Change-Id: Iffb4ce72d8bcf20b4e087d911da6aa84d2f15297
2012-01-12 14:56:18 -08:00
Jeff Brown
3f11f302c7 Fix indentation and whitespace.
Change-Id: Iccb954fb77f21b230eecb3f06328e11b14611f17
2012-01-12 14:37:58 -08:00
Jeff Brown
5a05c23f3d Clean up database tests a little bit.
Change-Id: Ib05c699bf59187cb51627b5f352c2a15ad2c28bb
2012-01-12 14:37:57 -08:00
Ying Wang
24162fc52c Build all test apks as raw resource in FrameworksCoreTests.
Bug: 5848975
Change-Id: I395013ded1c29e0914f72e03d0abd60bb4a7973a
2012-01-10 15:12:10 -08:00
Fabrice Di Meglio
4c1e00a8c2 Add textDirection="locale"
- also fix and update unit tests
- see bug #5242821

Change-Id: I29e029bab8ade336a430f9a2a5073caaf11b8dda
2012-01-06 11:29:18 -08:00
Jesse Wilson
52cd299eef Move the frameworks/base hostname verifier into libcore. Part 2/2
Bug: http://b/5619726
Change-Id: I165eb3befcef104ff56ffb466c87c60b632f3194
2011-12-27 19:00:56 -05:00
Svetoslav Ganov
786e54dd13 Fixing the build
Change-Id: I125956773dd364b14f8d328e625df3c852001dbf
2011-11-30 19:36:18 -08:00
Svetoslav Ganov
f3b4f3163b resolved conflicts for merge of 26f7a81f to master
Change-Id: I6bf5fd7c0de7945cef84602dbe3a7bbed587700f
2011-11-30 18:34:56 -08:00
Svetoslav Ganov
d116d7c78a Fixing memory leaks in the accessiiblity layer.
1. AccessibilityInteractionConnections were removed from the
   AccessiiblityManagerService but their DeathRecipents were
   not unregistered, thus every removed interaction connection
   was essentially leaking. Such connection is registered in
   the system for every ViewRootImpl when accessiiblity is
   enabled and inregistered when disabled.

2. Every AccessibilityEvent and AccessiilbityEventInfo obtained
   from a widnow content querying accessibility service had a
   handle to a binder proxy over which to make queries. Hoewever,
   holding a proxy to a remote binder prevents the latter from
   being garbage collected. Therefore, now the events and infos
   have a connection id insteand and the hindden singleton
   AccessiiblityInteaction client via which queries are made
   has a registry with the connections. This class looks up
   the connection given its id before making an IPC. Now the
   connection is stored in one place and when an accessibility
   service is disconnected the system sets the connection to
   null so the binder object in the system process can be GCed.
   Note that before this change a bad implemented accessibility
   service could cache events or infos causing a leak in the
   system process. This should never happen.

3. SparseArray was not clearing the reference to the last moved
   element while garbage collecting thus causing a leak.

bug:5664337

Change-Id: Id397f614b026d43bd7b57bb7f8186bca5cdfcff9
2011-11-29 18:51:30 -08:00
Jeff Sharkey
5898991075 am bc03c74c: am d968670d: Merge "Conservatively trim data usage stats." into ics-mr1
* commit 'bc03c74c485669695805944a655795a6f9890956':
  Conservatively trim data usage stats.
2011-11-15 11:30:34 -08:00
Jeff Sharkey
7ee8658453 Conservatively trim data usage stats.
Instead of trusting NTP time alone, use the most-conservative of
system clock and NTP.

Bug: 5584564
Change-Id: I5dd87fc009959b1cf0a7d660e385a0b1a8be238b
2011-11-14 20:11:38 -08:00
Jeff Sharkey
c592a57f3f am 489b4312: am 4c48d2ff: Merge "Make operation counts monotonically increase." into ics-mr1
* commit '489b431273500db81d35ed43440915187c238f92':
  Make operation counts monotonically increase.
2011-11-09 21:51:38 +00:00
Jeff Sharkey
4abb1b8ef6 Make operation counts monotonically increase.
Bug: 5585704
Change-Id: I5247a68acdb209a4ef0f5aac18944595c295e6ca
2011-11-08 17:35:28 -08:00
Jeff Sharkey
4d81191dd3 am 808ee95d: Merge "Correct proc file reader, optimizations." into ics-mr1
* commit '808ee95dd4244da6ae767d3ddd003ed7b48937d0':
  Correct proc file reader, optimizations.
2011-11-03 07:36:03 +00:00
Jeff Sharkey
163e6443f2 Correct proc file reader, optimizations.
Moved away from BufferedReader, which only reads the first 8KB of
some proc files because it aggresively fills its buffer.  Optimized
proc parsing, now double the speed.  Tests to cover.

Log when NetworkStats counters roll backwards when subtracting, and
optimizations around findIndex().  When system removes UID, also
remove from last stats snapshot to avoid xt counters from rolling
backwards.

Bug: 5472949, 5458380
Change-Id: I07c08fe5233156fac2b84450f6291868bf9bfaf2
2011-11-02 15:14:11 -07:00
Jesse Wilson
0f28af209a Interpret '+' as a space char in the URL query params.
This changes Uri.decode() to use libcore's implementation
of the same behavior.

Bug: http://code.google.com/p/android/issues/detail?id=21064
Change-Id: If81005492b12d3aaecc745471e0a28679544a391
2011-10-28 18:31:52 -04:00
Svetoslav Ganov
021078554b Adding APIs to enable reporting virtual view hierarchies to accessibility serivces.
Added an interface that is the contract for a client to expose a virtual
view hierarchy to accessibility services. Clients impement this interface
and set it in the View that is the root of the virtual sub-tree. Adding
this finctionality via compostion as opposed to inheritance enables apps
to maintain backwards compatibility by setting the accessibility virtual
hierarchy provider on the View only if the API version is high enough.

bug:5382859

Change-Id: I7e3927b71a5517943c6cb071be2e87fba23132bf
2011-10-21 11:45:44 -07:00
Steve Block
136b1637f8 Fix use of WebView.loadData() to avoid passing invalid encoding
No change in behavior, as invalid encodings have always been ignored.

Bug: 5125738
Change-Id: I23f21ca65a6b14501c74dc2189a55643f1e33c33
2011-10-17 15:11:33 +01:00
Jeff Brown
c755ae3b58 Use MatrixCursor instead of ArrayListCursor.
ArrayListCursor is deprecated, and a duplicate private copy of it
is doubly so.

Delete some tests that are duplicated in the CTS package.

Change-Id: Ib5837b12e39dadba57595906ad621b1feb0d2c0d
2011-10-13 14:24:28 -07:00
Jeff Sharkey
1059c3c30a Move battery stats to xt_qtaguid for data stats.
Replace TrafficStats calls by reading values from xt_qtaguid kernel
module. To keep BatteryStatsImpl changes lightweight, cache recently
parsed stats. Tracks mobile ifaces from ConnectivityService.

Refactor xt_qtaguid parsing into factory outside of NMS. Add stats
grouping based on UID, and total based on limiting filters like iface
prefix and UID.

Bug: 4902271
Change-Id: I533f116c434b77f93355bf95b839e7478528505b
2011-10-09 13:49:08 -07:00
Jeff Brown
270928bd4a Merge changes Idbfeb3cc,I03e8e2e7,Iff9eed78
* changes:
  Fix regression in CursorWindow.getString() Bug: 5332296
  Clean up CursorWindow lifetime. Bug: 5332296
  Fix regression in CursorWindow.copyStingToBuffer. Bug: 5332296
2011-10-07 15:08:24 -07:00
Jeff Brown
7ce745248d Clean up CursorWindow lifetime.
Bug: 5332296

Removed dead code in SQLiteCursor related to the use of a background
query thread.  This code could result in CursorWindows being modified
concurrently or used after free.  This code is broken, unused and
is just in the way.

Added comments to explain how CursorWindow ownership is
supposed to work for AbstractWindowedCursors.  (There are still cases
where cursor windows get dropped on the floor without being closed.
Those will be taken care of in a subsequent patch.)

Cleaned up SQLiteQuery.fillWindow to eliminate duplicate code and
remove bits that were only needed for background loading, like
returning -1.

Change-Id: I03e8e2e73ff0c11df76d63f57df4c5ada06ae1cb
2011-10-07 13:31:00 -07:00
Svetoslav Ganov
b6eca6e669 Accessibility test automation API not working.
1. Due to a previous change that disabled accessibility if not enabled
   and installed serivces are present the automation APIs stopped working
   since they use fake automation service that is not installed.

2. Added clean up of death recipients when binders die.

bug:5374662
bug:5239044

Change-Id: I1f3c8cd1d1c79753a4a64e2b8b2963025abb2939
2011-10-06 14:16:03 -07:00
Jeff Sharkey
905b5891d2 Track xtables summary, move tether stats, time.
Begin tracking xtables summary of data usage to compare with values
reported from /proc/net/dev.  Roll tethering directly into UID stats
to trigger UID stats persisting when crossing threshold.

Include xtables summary and authoritative time in samples.

Bug: 5373561, 5397882, 5381980
Change-Id: Ib7945522caadfbe0864fdf391582dc820f4f371e
2011-10-03 17:21:05 -07:00
Jesse Wilson
de5d7d2508 Test to demonstrate NPE in DefaultRequestDirector
When the HTTP client encountered a server failure while
talking through a proxy, it fails with an NullPointerException
and not an IOException.

Change-Id: I4b287105bf78b832d034557e37e74ce576c7894d
Bug: http://b/5372438
2011-09-27 19:28:32 -04:00
Kenny Root
05ca4c9064 Allow non-required package verifiers
* Verifiers can be specified in the AndroidManifest.xml

* Those verifiers can respond to the new Intent action

* PackageManager API for those verifiers: verifyPendingInstall

Change-Id: I4892bce2e6984871e6e93c60a1ca0dae145f5df5
2011-09-23 16:03:03 -07:00
Kenny Root
04b08bdf19 Merge "Be more forgiving in parsing verifier IDs" 2011-09-15 09:33:06 -07:00
Svetoslav Ganov
ea515aeafa Update the public APIs for finding views by text to optionally use content description.
1. Added flags to the search method to specify whether to match text or
   content description or both.

2. Added test case for the seach by content description.

3. Updated the code in AccessibilityManager service to reflect the latest
   changes there so test automation service works - this is the fake
   service used for UI automation.

Change-Id: I14a6779a920ff0430e78947ea5aaf876c2e66076
2011-09-14 19:40:33 -07:00
Kenny Root
a0f264e1af Be more forgiving in parsing verifier IDs
RFC 4648's Base32 is made to be forgiving for users doing manual entry
of the digits. For this reason we want to be able to parse lowercase
letters as uppercase and number 0 (zero) as letter O along with number
1 (one) as letter I.

Change-Id: Ide760aff84f97c3e06af8bf8d006f36c74033a41
2011-09-14 10:08:19 -07:00
Kenny Root
c924fbd693 Merge "Add verifier device identity" 2011-09-13 17:51:08 -07:00
Kenny Root
0aaa0d9317 Add verifier device identity
This adds a special device identifier that is usable only for device
validation. The user will be presented with this number encoded in
easily-transcribable Base32 in the Developer options of Settings.

Change-Id: I4843f55ee90d689a51d0269b22454ca04c1be7ec
2011-09-13 16:02:43 -07:00
Jeff Sharkey
e44365b539 Merge "Data usage structure optimizations." 2011-09-12 16:50:34 -07:00
Jeff Sharkey
69b0f63af2 Data usage structure optimizations.
Driven by traceview hotspots found in Settings UI.

Change-Id: I614a049523c526b7fcd12fffdf53a3e4723623e4
2011-09-12 16:13:20 -07:00