From d4d04def2cad706894098f6e0c779b173e95892c Mon Sep 17 00:00:00 2001 From: Eric Fischer Date: Tue, 27 Oct 2009 18:55:57 -0700 Subject: [PATCH 01/10] Fix a race that kept the locale picker from working under heavy CPU load. The locale picker and the activity transition would both change the configuration, and depending upon the timing, the activity transition would undo what the locale picker had just done. Usually it worked right, but would often fail if the user changed locales just after a data wipe, when the media scanner was working hard in the background to index the contents of the SD card. http://b/issue?id=2216298 --- .../server/am/ActivityManagerService.java | 30 +++++++++++++++---- 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index ad1926e20aa69..56270f48b45ab 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -2705,13 +2705,31 @@ public final class ActivityManagerService extends ActivityManagerNative implemen // Have the window manager re-evaluate the orientation of // the screen based on the new activity order. - Configuration config = mWindowManager.updateOrientationFromAppTokens( - mConfiguration, - next.mayFreezeScreenLocked(next.app) ? next : null); - if (config != null) { - next.frozenBeforeDestroy = true; + boolean updated; + synchronized (this) { + Configuration config = mWindowManager.updateOrientationFromAppTokens( + mConfiguration, + next.mayFreezeScreenLocked(next.app) ? next : null); + if (config != null) { + /* + * Explicitly restore the locale to the one from the + * old configuration, since the one that comes back from + * the window manager has the default (boot) locale. + * + * It looks like previously the locale picker only worked + * by coincidence: usually it would do its setting of + * the locale after the activity transition, so it didn't + * matter that this lost it. With the synchronized + * block now keeping them from happening at the same time, + * this one always would happen second and undo what the + * locale picker had just done. + */ + config.locale = mConfiguration.locale; + next.frozenBeforeDestroy = true; + } + updated = updateConfigurationLocked(config, next); } - if (!updateConfigurationLocked(config, next)) { + if (!updated) { // The configuration update wasn't able to keep the existing // instance of the activity, and instead started a new one. // We should be all done, but let's just make sure our activity From 00dc5756b1bf0a4cfd7a0b314b87ed12a3ced244 Mon Sep 17 00:00:00 2001 From: Dirk Dougherty Date: Tue, 27 Oct 2009 18:02:29 -0700 Subject: [PATCH 02/10] doc change: some fixes for online sdk docs. update "testing" section of screens support doc. Bug: 2160782 Change-Id: Ib80db9231f91a36f503db487982378b252c0fcd8 --- docs/html/guide/appendix/api-levels.jd | 18 ++-- docs/html/guide/practices/screens_support.jd | 96 +++++++++++------- .../images/screens_support/avd-density.png | Bin 0 -> 54188 bytes docs/html/sdk/android-1.5.jd | 1 - docs/html/sdk/android-1.6.jd | 1 - docs/html/sdk/api_diff/3/changes.html | 10 +- docs/html/sdk/api_diff/3/stylesheet-jdiff.css | 3 +- docs/html/sdk/api_diff/4/changes.html | 10 +- docs/html/sdk/api_diff/4/stylesheet-jdiff.css | 3 +- docs/html/sdk/api_diff/5/changes.html | 10 +- docs/html/sdk/api_diff/5/stylesheet-jdiff.css | 3 +- 11 files changed, 89 insertions(+), 66 deletions(-) create mode 100644 docs/html/images/screens_support/avd-density.png diff --git a/docs/html/guide/appendix/api-levels.jd b/docs/html/guide/appendix/api-levels.jd index b3b6371d97370..083003236a25b 100644 --- a/docs/html/guide/appendix/api-levels.jd +++ b/docs/html/guide/appendix/api-levels.jd @@ -324,22 +324,24 @@ control to show documentation only for parts of the API that are actually accessible to your application, based on the API Level that it specifies in the android:minSdkVersion attribute of its manifest file.

-

To use filtering, set the control to the same API Level as that specified -by your application. Notice that APIs introduced in a later API Level are -then grayed out and their content is masked, since they would not be -accessible to your application.

+

To use filtering, select the checkbox to enable filtering, just below the +page search box. Then set the "Filter by API Level" control to the same API +Level as specified by your application. Notice that APIs introduced in a later +API Level are then grayed out and their content is masked, since they would not +be accessible to your application.

Filtering by API Level in the documentation does not provide a view of what is new or introduced in each API Level — it simply provides a way to view the entire API associated with a given API Level, while excluding API elements introduced in later API Levels.

-

By default, API Level filtering is enabled and set to show the latest API -Level. If you do not want to use filtering reference documentation, -simply select the highest available API Level.

+

If you decide that you don't want to filter the API documentation, just +disable the feature using the checkbox. By default, API Level filtering is +disabled, so that you can view the full framework API, regardless of API Level. +

Also note that the reference documentation for individual API elements -specifies the API Level at which the elements were introduced. The API Level +specifies the API Level at which each element was introduced. The API Level for packages and classes is specified as "Since <api level>" at the top-right corner of the content area on each documentation page. The API Level for class members is specified in their detailed description headers, diff --git a/docs/html/guide/practices/screens_support.jd b/docs/html/guide/practices/screens_support.jd index 1d16d886f960c..88975f8c09283 100644 --- a/docs/html/guide/practices/screens_support.jd +++ b/docs/html/guide/practices/screens_support.jd @@ -1069,28 +1069,29 @@ not. Once you've tested your application and found that it displays properly on various screen sizes, you should make sure to add the corresponding size attribute(s) to your application's manifest. --> +

+ +

Figure 3. + A typical set of AVDs for testing screens support.

+
+

As a test environment for your applications, set up a series of AVDs that emulate the screen sizes and densities you want to support. The Android SDK -includes four emulator skins to get you started. You can use the Android AVD +includes six emulator skins to get you started. You can use the Android AVD Manager or the android tool to create AVDs that use the various emulator skins and you can also set up custom AVDs to test densities other than the defaults. For general information about working with AVDs, see Android Virtual Devices.

-

The Android 1.6 and higher platforms in the SDK include these emulator skins, -which represent the primary screen configurations that your should test:

+

The Android SDK provides a set of default emulator skins that you can use for +testing. The skins are included as part of each Android platform that you can +install in your SDK. The Android 1.6 platform offers these default skins:

+

The Android 2.0 platform offers all of the Android 1.6 default skins, +above, plus:

+ + +

If you are using the android tool command line to create your AVDs, here's an example of how to specify the skin you want to use:

@@ -1130,6 +1143,12 @@ monitor. Using the default densities, the emulator skins included in the Android
  • QVGA, low density: 3.3"
  • +
  • + WQVGA, low density: 3.9" +
  • +
  • + WQVGA432, low density: 4.1" +
  • HVGA, medium density: 3.6"
  • @@ -1141,6 +1160,12 @@ monitor. Using the default densities, the emulator skins included in the Android +
    + +

    Figure 4. + Resolution and density options that you can use, when creating an AVD using the AVD Manager.

    +
    +

    You should also make sure to test your application on different physical screen sizes within a single size-density configuration. For example, according to Table 1, the minimum supported diagonal of QVGA is 2.8". @@ -1150,21 +1175,35 @@ To display this is on a 30" monitor you will need to adjust the value passed to

    emulator -avd <name> -scale 0.6
    -

    If you would like to test your application on a screen not supported by the -built-in skins, you can either adjust an existing skin, or create a custom -resolution.

    +

    If you would like to test your application on a screen that uses a resolution +or density not supported by the built-in skins, you can either adjust an +existing skin, or create an AVD +that uses a custom resolution or density.

    -

    For example, to test on a large WVGA800 screen with medium density:

    +

    In the AVD Manager, you can specify a custom skin resolution or density in +the Create New AVD dialog, as shown in Figure 4, at right.

    + +

    In the android tool, follow these steps to create an AVD with a +custom resolution or density:

      -
    1. Create an AVD based on the WVGA800 skin (using the android -tool's command line.)
    2. -
    3. Answer "yes" when asked about using custom hardware
    4. -
    5. enter "160" when asked about the value for hw.lcd.density -(120-low, 160-medium, 240-high).
    6. +
    7. Use the create avd command to create a new AVD, specifying +the --skin option with a value that references either a default +skin name (such as "WVGA800") or a custom skin resolution (such as 240x432). +Here's an example: +
      android create avd -n <name> -t <targetID> --skin WVGA800
      +
    8. +
    9. To specify a custom density for the skin, answer "yes" when asked whether +you want to create a custom hardware profile for the new AVD.
    10. +
    11. Continue through the various profile settings until the tool asks you to +specify "Abstracted LCD density" (hw.lcd.density). Consult Table 1, earlier in this document, and enter the appropriate +value. For example, enter "160" to use medium density for the WVGA800 screen.
    12. +
    13. Set any other hardware options and complete the AVD creation.
    -

    When running this AVD, the emulator will emulate a 5.8" WVGA screen.

    +

    In the example above (WVGA medium density), the new AVD will emulate a 5.8" +WVGA screen.

    As an alternative to adjusting the emulator skin configuration, you can use the emulator skin's default density and add the -dpi-device option @@ -1172,25 +1211,6 @@ to the emulator command line when starting the AVD. For example,

    emulator -avd WVGA800 -scale 96dpi -dpi-device 160
    -

    If you would like to test your application with a resolution not supported by -the provided skins, you can use the desired resolution in place of the skin -name. For instance, for FWQVGA you would use:

    - -
    android create avd ... --skin 240x432
    - -

    Next, you would need to set the proper density for the screen. When asked by -the tool whether you want to create a custom hardware profile for the new AVD, -enter "yes". Continue through the various profile settings until the tools asks -you to specify "Abstracted LCD density". Consult Table 1, -earlier in this document, and enter the appropriate value. For the FWQVGA -screen, the density should be "160", or medium.

    - -
    - -

    Figure 3. - A typical set of AVDs for testing screens support.

    -
    -

    Screen-Compatibility Examples

    diff --git a/docs/html/images/screens_support/avd-density.png b/docs/html/images/screens_support/avd-density.png new file mode 100644 index 0000000000000000000000000000000000000000..e3fc36ec5c692b89879ff203d33a057b6faeb096 GIT binary patch literal 54188 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 literal 0 HcmV?d00001 diff --git a/docs/html/sdk/android-1.5.jd b/docs/html/sdk/android-1.5.jd index 15d19383b7c73..46126820410e2 100644 --- a/docs/html/sdk/android-1.5.jd +++ b/docs/html/sdk/android-1.5.jd @@ -16,7 +16,6 @@ sdk.platform.deployableDate=May 2009

  • Built-in Applications
  • Locales
  • Emulator Skins
  • -
  • Other Notes
  • Framework API
    1. API level
    2. diff --git a/docs/html/sdk/android-1.6.jd b/docs/html/sdk/android-1.6.jd index 38112b547376e..4b659a1af62f5 100644 --- a/docs/html/sdk/android-1.6.jd +++ b/docs/html/sdk/android-1.6.jd @@ -16,7 +16,6 @@ sdk.platform.deployableDate=October 2009
    3. Built-in Applications
    4. Locales
    5. Emulator Skins
    6. -
    7. Other Notes
    8. Framework API
      1. API level
      2. diff --git a/docs/html/sdk/api_diff/3/changes.html b/docs/html/sdk/api_diff/3/changes.html index bc0f8791013c1..9bc67b987711d 100644 --- a/docs/html/sdk/api_diff/3/changes.html +++ b/docs/html/sdk/api_diff/3/changes.html @@ -26,12 +26,12 @@ body{overflow:auto;} body{background-image:url();padding:12px;} - - - - + + + + - + <H2> diff --git a/docs/html/sdk/api_diff/3/stylesheet-jdiff.css b/docs/html/sdk/api_diff/3/stylesheet-jdiff.css index b3c1b9af86b9a..abc4dd5eb80bf 100644 --- a/docs/html/sdk/api_diff/3/stylesheet-jdiff.css +++ b/docs/html/sdk/api_diff/3/stylesheet-jdiff.css @@ -3,6 +3,7 @@ div.and-diff-id {border: 1px solid #eee;position:relative;float:right;clear:both;padding:0px;} table.diffspectable {border:1px;padding:0px;margin:0px;} +table.jdiffIndex {margin-bottom:.5em;} .diffspechead {background-color:#eee;} .diffspectable tr {border:0px;padding:0px;} .diffspectable td {background-color:eee;border:0px;font-size:90%;font-weight:normal;padding:0px;padding-left:1px;padding-right:1px;text-align:center;color:777;} @@ -29,7 +30,7 @@ tt {font-size:11pt;font-family:monospace;} } .hiddenlink { font-size:96%; - line-height:.8em; +/* line-height:.8em; */ text-decoration:none;} a { text-decoration:none;} diff --git a/docs/html/sdk/api_diff/4/changes.html b/docs/html/sdk/api_diff/4/changes.html index c1b66a1ef24ff..9cfdc24173d64 100644 --- a/docs/html/sdk/api_diff/4/changes.html +++ b/docs/html/sdk/api_diff/4/changes.html @@ -25,12 +25,12 @@ body{overflow:auto;} <style type="text/css"> </style> </HEAD> -<FRAMESET COLS="242,**" frameborder="1" border="7" xframespacing="20" bordercolor="#e9e9e9"> -<frameset rows="164,**" frameborder="1" border="7" xframespacing="20" resizable="yes"> - <FRAME SRC="changes/jdiff_topleftframe.html" SCROLLING="no" NAME="topleftframe" xframeborder="1" xborder="6" xframespacing="0"> - <FRAME SRC="changes/alldiffs_index_all.html" SCROLLING="auto" NAME="bottomleftframe" xframeborder="1" xborder="1" xframespacing="0"> +<FRAMESET COLS="242,**" framespacing="1" frameborder="yes" border="1" bordercolor="#e9e9e9"> +<frameset rows="174,**" framespacing="1" frameborder="yes" border="1" bordercolor="#e9e9e9"> + <FRAME SRC="changes/jdiff_topleftframe.html" SCROLLING="no" NAME="topleftframe" frameborder="1"> + <FRAME SRC="changes/alldiffs_index_all.html" SCROLLING="auto" NAME="bottomleftframe" frameborder="1"> </FRAMESET> - <FRAME SRC="changes/changes-summary.html" SCROLLING="auto" NAME="rightframe" xframeborder="1" xborder="1" xframespacing="0"> + <FRAME SRC="changes/changes-summary.html" SCROLLING="auto" NAME="rightframe" frameborder="1"> </FRAMESET> <NOFRAMES> <H2> diff --git a/docs/html/sdk/api_diff/4/stylesheet-jdiff.css b/docs/html/sdk/api_diff/4/stylesheet-jdiff.css index b3c1b9af86b9a..824b3df4c1661 100644 --- a/docs/html/sdk/api_diff/4/stylesheet-jdiff.css +++ b/docs/html/sdk/api_diff/4/stylesheet-jdiff.css @@ -3,6 +3,7 @@ div.and-diff-id {border: 1px solid #eee;position:relative;float:right;clear:both;padding:0px;} table.diffspectable {border:1px;padding:0px;margin:0px;} +table.jdiffIndex {margin-bottom:.5em;} .diffspechead {background-color:#eee;} .diffspectable tr {border:0px;padding:0px;} .diffspectable td {background-color:eee;border:0px;font-size:90%;font-weight:normal;padding:0px;padding-left:1px;padding-right:1px;text-align:center;color:777;} @@ -29,7 +30,7 @@ tt {font-size:11pt;font-family:monospace;} } .hiddenlink { font-size:96%; - line-height:.8em; +/* line-height:.8em; */ text-decoration:none;} a { text-decoration:none;} diff --git a/docs/html/sdk/api_diff/5/changes.html b/docs/html/sdk/api_diff/5/changes.html index dc3f7cb515613..671e89069f54c 100644 --- a/docs/html/sdk/api_diff/5/changes.html +++ b/docs/html/sdk/api_diff/5/changes.html @@ -25,12 +25,12 @@ body{overflow:auto;} <style type="text/css"> </style> </HEAD> -<FRAMESET COLS="242,**" frameborder="1" border="7" xframespacing="20" bordercolor="#e9e9e9"> -<frameset rows="164,**" frameborder="1" border="7" xframespacing="20" resizable="yes"> - <FRAME SRC="changes/jdiff_topleftframe.html" SCROLLING="no" NAME="topleftframe" xframeborder="1" xborder="6" xframespacing="0"> - <FRAME SRC="changes/alldiffs_index_all.html" SCROLLING="auto" NAME="bottomleftframe" xframeborder="1" xborder="1" xframespacing="0"> +<FRAMESET COLS="242,**" framespacing="1" frameborder="yes" border="1" bordercolor="#e9e9e9"> +<frameset rows="174,**" framespacing="1" frameborder="yes" border="1" bordercolor="#e9e9e9"> + <FRAME SRC="changes/jdiff_topleftframe.html" SCROLLING="no" NAME="topleftframe" frameborder="1"> + <FRAME SRC="changes/alldiffs_index_all.html" SCROLLING="auto" NAME="bottomleftframe" frameborder="1"> </FRAMESET> - <FRAME SRC="changes/changes-summary.html" SCROLLING="auto" NAME="rightframe" xframeborder="1" xborder="1" xframespacing="0"> + <FRAME SRC="changes/changes-summary.html" SCROLLING="auto" NAME="rightframe" frameborder="1"> </FRAMESET> <NOFRAMES> <H2> diff --git a/docs/html/sdk/api_diff/5/stylesheet-jdiff.css b/docs/html/sdk/api_diff/5/stylesheet-jdiff.css index b3c1b9af86b9a..abc4dd5eb80bf 100644 --- a/docs/html/sdk/api_diff/5/stylesheet-jdiff.css +++ b/docs/html/sdk/api_diff/5/stylesheet-jdiff.css @@ -3,6 +3,7 @@ div.and-diff-id {border: 1px solid #eee;position:relative;float:right;clear:both;padding:0px;} table.diffspectable {border:1px;padding:0px;margin:0px;} +table.jdiffIndex {margin-bottom:.5em;} .diffspechead {background-color:#eee;} .diffspectable tr {border:0px;padding:0px;} .diffspectable td {background-color:eee;border:0px;font-size:90%;font-weight:normal;padding:0px;padding-left:1px;padding-right:1px;text-align:center;color:777;} @@ -29,7 +30,7 @@ tt {font-size:11pt;font-family:monospace;} } .hiddenlink { font-size:96%; - line-height:.8em; +/* line-height:.8em; */ text-decoration:none;} a { text-decoration:none;} From 3141c707b8e8fa0fea6d66d6dd8a6a8e901a03b7 Mon Sep 17 00:00:00 2001 From: Scott Main <smain@google.com> Date: Wed, 28 Oct 2009 11:12:58 -0700 Subject: [PATCH 03/10] docs: add 2.0 video to developer site feature videos --- docs/html/videos/index.jd | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/html/videos/index.jd b/docs/html/videos/index.jd index ddb9f861fae2e..4e53aac2991c9 100644 --- a/docs/html/videos/index.jd +++ b/docs/html/videos/index.jd @@ -37,12 +37,10 @@ var playlistsWithTitleInDescription = "734A052F802C96B9"; * Each playlist ID is paired with a custom video description. */ var featured = { -// Android 1.6 Release - 'MBRFkLKRwFw' : "The Android 1.6 release includes new features and improvements to the Android platform. Here's an introduction to what's new in Android 1.6.", +// Android 2.0 Release + 'opZ69P-0Jbc' : "The Android 2.0 platform adds exciting new user features and developer APIs. Here's an introduction to what's new.", // How to Make your Android UI Fast.. 'N6YdwzAvwOA' : "Make your user interface fast, with more efficient AdapterViews, better bitmap scaling, faster redrawing, ViewStub layouts, fewer Views, and more.", -// Coding for Life: Battery Life -// 'OUemfrKe65c' : "Learn what kinds of operations consume the most battery and how you can reduce your usage, with tips for parsing and zipping data, using wakelocks, and running a Service.", // How Do I Code Thee? 'GARMe7Km_gk' : "If you'd like to augment your Android applications with pieces written in JavaScript or native code, watch this video." }; From 405d0898630a1c35e8e5ece072d8703fd68aca3b Mon Sep 17 00:00:00 2001 From: Christopher Tate <ctate@android.com> Date: Tue, 27 Oct 2009 20:23:28 -0700 Subject: [PATCH 04/10] DO NOT MERGE: Fix loss of focus after wakeup into incall screen Because of the asynchronous behavior of keyguard, and incall explicitly disabling keyguard, sometimes the window manager would wind up in a state in which the "correct" app and activity window were shown, but focus was recalculated "too soon," at a time when keyguard was just about gone but not quite, and incall was not yet fully shown. In this case there was no currently valid event target, but the final show of the incall window would not prompt a focus recalculation, so that "no current focus" state would incorrectly persist, resulting in spurious ANRs until some other phone activity forced a focus update. We now detect the problematic case when windows are shown, and make sure to recalculate focus explicitly thereafter. This change does *not* fix the underlying race conditions that have been resulting in mismatched state within the window manager, but it does force a validation pass that puts things in order so that normal operation can continue. Change-Id: I8e7f5f0795f0042a0da074aeed385e3fbc210360 --- .../java/com/android/server/WindowManagerService.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java index cd6a3712a8bf3..6418901915c1a 100644 --- a/services/java/com/android/server/WindowManagerService.java +++ b/services/java/com/android/server/WindowManagerService.java @@ -9303,6 +9303,15 @@ public class WindowManagerService extends IWindowManager.Stub & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) { wallpaperMayChange = true; } + if (changed && !forceHiding + && (mCurrentFocus == null) + && (mFocusedApp != null)) { + // It's possible that the last focus recalculation left no + // current focused window even though the app has come to the + // foreground already. In this case, we make sure to recalculate + // focus when we show a window. + focusMayChange = true; + } } mPolicy.animatingWindowLw(w, attrs); From c03d28b9e96f667d29ec6e480bed171bbd07169d Mon Sep 17 00:00:00 2001 From: Suchi Amalapurapu <asuchitra@google.com> Date: Wed, 28 Oct 2009 14:32:05 -0700 Subject: [PATCH 05/10] Check that the window which wants to force hide is visible before setting the flag forceHiding to true. If we do layout the surfaces again this flag gets set no matter what since the keyguard window is always present in the list of tokens and this hides the window which would have become visible since the keyguard just got dismissed. This causes unnecessary focus changes due to changes in visibility of current window. This will resolve issues related to current focus and time outs when dispatching key events. --- services/java/com/android/server/WindowManagerService.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java index 6418901915c1a..94667ebbac3ef 100644 --- a/services/java/com/android/server/WindowManagerService.java +++ b/services/java/com/android/server/WindowManagerService.java @@ -9653,7 +9653,8 @@ public class WindowManagerService extends IWindowManager.Stub WindowState w = (WindowState)mWindows.get(i); if (w.mSurface != null) { final WindowManager.LayoutParams attrs = w.mAttrs; - if (mPolicy.doesForceHide(w, attrs)) { + if (mPolicy.doesForceHide(w, attrs) && w.isVisibleLw()) { + if (DEBUG_FOCUS) Log.i(TAG, "win=" + w + " force hides other windows"); forceHiding = true; } else if (mPolicy.canBeForceHidden(w, attrs)) { if (!w.mAnimating) { From 85ade33edcc7d9be462ad7b8455d27f6654aca5e Mon Sep 17 00:00:00 2001 From: Mathias Agopian <mathias@google.com> Date: Tue, 27 Oct 2009 23:33:48 -0700 Subject: [PATCH 06/10] fix [2071412] work around mdp 32-bits fade limitation in the case where we fade a 32-bits surface (ie: GL_MODULATE w/ a,a,a,a + blending), we first make a copy of the background into a RGB buffer, then we blend the 32-bits surface as usual (without the alpha component), and finally blend the copy of the background on top with 1-a. This uses a lot of bandwidth, but no CPU time. --- opengl/libagl/copybit.cpp | 79 +++++++++++++++++++++++++++++++++------ 1 file changed, 68 insertions(+), 11 deletions(-) diff --git a/opengl/libagl/copybit.cpp b/opengl/libagl/copybit.cpp index 0c3d0eef5cdc6..4b9e59b7c885f 100644 --- a/opengl/libagl/copybit.cpp +++ b/opengl/libagl/copybit.cpp @@ -154,6 +154,8 @@ static bool copybit(GLint x, GLint y, int transform, ogles_context_t* c) { + status_t err = NO_ERROR; + // We assume checkContext has already been called and has already // returned true. @@ -200,6 +202,7 @@ static bool copybit(GLint x, GLint y, const uint32_t enables = c->rasterizer.state.enables; int planeAlpha = 255; + bool alphaPlaneWorkaround = false; static const int tmu = 0; texture_t& tev(c->rasterizer.state.texture[tmu]); int32_t opFormat = textureObject->surface.format; @@ -259,9 +262,10 @@ static bool copybit(GLint x, GLint y, if (c->currentColorClamped.r == c->currentColorClamped.a && c->currentColorClamped.g == c->currentColorClamped.a && c->currentColorClamped.b == c->currentColorClamped.a) { - // TODO: Need to emulate: RGBA source, color={a,a,a,a} / premult - // and RGBA source, color={1,1,1,a} / regular-blending - // (both are equivalent) + // TODO: RGBA source, color={1,1,1,a} / regular-blending + // is equivalent + alphaPlaneWorkaround = true; + break; } } LOGD_IF(DEBUG_COPYBIT, "GGL_MODULATE"); @@ -331,13 +335,13 @@ static bool copybit(GLint x, GLint y, tmp_w, tmp_h, src.format, GraphicBuffer::USAGE_HW_2D); - status_t err = tempBitmap->initCheck(); + err = tempBitmap->initCheck(); if (err == NO_ERROR) { copybit_image_t tmp_dst; copybit_rect_t tmp_rect; tmp_dst.w = tmp_w; tmp_dst.h = tmp_h; - tmp_dst.format = src.format; + tmp_dst.format = tempBitmap->format; tmp_dst.handle = (native_handle_t*)tempBitmap->getNativeBuffer()->handle; tmp_rect.l = 0; tmp_rect.t = 0; @@ -359,13 +363,66 @@ static bool copybit(GLint x, GLint y, textureToCopyBitImage(&cbSurface, cbSurface.format, target_hnd, &dst); copybit_rect_t drect = {x, y, x+w, y+h}; - copybit->set_parameter(copybit, COPYBIT_TRANSFORM, transform); - copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, planeAlpha); - copybit->set_parameter(copybit, COPYBIT_DITHER, - (enables & GGL_ENABLE_DITHER) ? COPYBIT_ENABLE : COPYBIT_DISABLE); - clipRectRegion it(c); - status_t err = copybit->stretch(copybit, &dst, &src, &drect, &srect, &it); + /* and now the alpha-plane hack. This handles the "Fade" case of a + * texture with an alpha channel. + */ + if (alphaPlaneWorkaround) { + sp<GraphicBuffer> tempCb = new GraphicBuffer( + w, h, COPYBIT_FORMAT_RGB_565, + GraphicBuffer::USAGE_HW_2D); + + err = tempCb->initCheck(); + + copybit_image_t tmpCbImg; + copybit_rect_t tmpCbRect; + tmpCbImg.w = w; + tmpCbImg.h = h; + tmpCbImg.format = tempCb->format; + tmpCbImg.handle = (native_handle_t*)tempCb->getNativeBuffer()->handle; + tmpCbRect.l = 0; + tmpCbRect.t = 0; + tmpCbRect.r = w; + tmpCbRect.b = h; + + if (!err) { + // first make a copy of the destination buffer + region_iterator tmp_it(Region(Rect(w, h))); + copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0); + copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF); + copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_DISABLE); + err = copybit->stretch(copybit, + &tmpCbImg, &dst, &tmpCbRect, &drect, &tmp_it); + } + if (!err) { + // then proceed as usual, but without the alpha plane + copybit->set_parameter(copybit, COPYBIT_TRANSFORM, transform); + copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF); + copybit->set_parameter(copybit, COPYBIT_DITHER, + (enables & GGL_ENABLE_DITHER) ? + COPYBIT_ENABLE : COPYBIT_DISABLE); + clipRectRegion it(c); + err = copybit->stretch(copybit, &dst, &src, &drect, &srect, &it); + } + if (!err) { + // finally copy back the destination on top with 1-alphaplane + int invPlaneAlpha = 0xFF - fixedToByte(c->currentColorClamped.a); + clipRectRegion it(c); + copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0); + copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, invPlaneAlpha); + copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_ENABLE); + err = copybit->stretch(copybit, + &dst, &tmpCbImg, &drect, &tmpCbRect, &it); + } + } else { + copybit->set_parameter(copybit, COPYBIT_TRANSFORM, transform); + copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, planeAlpha); + copybit->set_parameter(copybit, COPYBIT_DITHER, + (enables & GGL_ENABLE_DITHER) ? + COPYBIT_ENABLE : COPYBIT_DISABLE); + clipRectRegion it(c); + err = copybit->stretch(copybit, &dst, &src, &drect, &srect, &it); + } if (err != NO_ERROR) { c->textures.tmu[0].texture->try_copybit = false; } From cb41faa285ad0c00bcdc8815d4bf83219552007d Mon Sep 17 00:00:00 2001 From: Fred Quintana <fredq@google.com> Date: Wed, 28 Oct 2009 12:29:15 -0700 Subject: [PATCH 07/10] don't throw an exception when we can't find a pending sync operation in the database --- core/java/android/content/SyncManager.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java index 9757ef68bdaaa..ba186159680d5 100644 --- a/core/java/android/content/SyncManager.java +++ b/core/java/android/content/SyncManager.java @@ -2294,8 +2294,8 @@ class SyncManager implements OnAccountsUpdateListener { } if (!mSyncStorageEngine.deleteFromPending(operationToRemove.pendingOperation)) { - throw new IllegalStateException("unable to find pending row for " - + operationToRemove); + final String errorMessage = "unable to find pending row for " + operationToRemove; + Log.e(TAG, errorMessage, new IllegalStateException(errorMessage)); } if (DEBUG_CHECK_DATA_CONSISTENCY) debugCheckDataStructures(true /* check the DB */); @@ -2314,7 +2314,8 @@ class SyncManager implements OnAccountsUpdateListener { } if (!mSyncStorageEngine.deleteFromPending(operation.pendingOperation)) { - throw new IllegalStateException("unable to find pending row for " + operation); + final String errorMessage = "unable to find pending row for " + operation; + Log.e(TAG, errorMessage, new IllegalStateException(errorMessage)); } if (DEBUG_CHECK_DATA_CONSISTENCY) debugCheckDataStructures(true /* check the DB */); @@ -2336,8 +2337,8 @@ class SyncManager implements OnAccountsUpdateListener { } if (!mSyncStorageEngine.deleteFromPending(syncOperation.pendingOperation)) { - throw new IllegalStateException("unable to find pending row for " - + syncOperation); + final String errorMessage = "unable to find pending row for " + syncOperation; + Log.e(TAG, errorMessage, new IllegalStateException(errorMessage)); } if (DEBUG_CHECK_DATA_CONSISTENCY) debugCheckDataStructures(true /* check the DB */); From 911458a081e098b7b289ed7135e1719733d7e12d Mon Sep 17 00:00:00 2001 From: Marco Nelissen <marcone@google.com> Date: Wed, 28 Oct 2009 15:10:56 -0700 Subject: [PATCH 08/10] Fix x offset for boxed textures --- libs/rs/rsAllocation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/rs/rsAllocation.cpp b/libs/rs/rsAllocation.cpp index 8ac9c26a2f37f..b7d1297feddf1 100644 --- a/libs/rs/rsAllocation.cpp +++ b/libs/rs/rsAllocation.cpp @@ -405,7 +405,7 @@ RsAllocation rsi_AllocationCreateFromBitmapBoxed(Context *rsc, uint32_t w, uint3 const uint8_t * src = static_cast<const uint8_t *>(data); for (uint32_t y = 0; y < h; y++) { uint8_t * ydst = &tmp[(y + ((h2 - h) >> 1)) * w2 * bpp]; - memcpy(&ydst[(w2 - w) >> 1], src, w * bpp); + memcpy(&ydst[((w2 - w) >> 1) * bpp], src, w * bpp); src += w * bpp; } From 31957f1badbb900bbfe211317e1ea992d650a72d Mon Sep 17 00:00:00 2001 From: Fred Quintana <fredq@google.com> Date: Wed, 21 Oct 2009 13:43:10 -0700 Subject: [PATCH 09/10] - add javadoc for the account manager - add some checks to the AccountManagerService to keep it from crashing when a null is passed in - cleaned up the API a bit --- api/current.xml | 16 ++- .../AbstractAccountAuthenticator.java | 96 ++++++-------- .../AccountAuthenticatorActivity.java | 23 +--- .../java/android/accounts/AccountManager.java | 45 +++++-- .../accounts/AccountManagerService.java | 119 +++++++++++++++--- 5 files changed, 186 insertions(+), 113 deletions(-) diff --git a/api/current.xml b/api/current.xml index 47dc08ae48bf3..936e67e05ddb8 100644 --- a/api/current.xml +++ b/api/current.xml @@ -13804,6 +13804,8 @@ </parameter> <parameter name="options" type="android.os.Bundle"> </parameter> +<exception name="NetworkErrorException" type="android.accounts.NetworkErrorException"> +</exception> </method> <method name="editProperties" return="android.os.Bundle" @@ -13853,7 +13855,7 @@ </parameter> <parameter name="authTokenType" type="java.lang.String"> </parameter> -<parameter name="loginOptions" type="android.os.Bundle"> +<parameter name="options" type="android.os.Bundle"> </parameter> <exception name="NetworkErrorException" type="android.accounts.NetworkErrorException"> </exception> @@ -13917,8 +13919,10 @@ </parameter> <parameter name="authTokenType" type="java.lang.String"> </parameter> -<parameter name="loginOptions" type="android.os.Bundle"> +<parameter name="options" type="android.os.Bundle"> </parameter> +<exception name="NetworkErrorException" type="android.accounts.NetworkErrorException"> +</exception> </method> </class> <class name="Account" @@ -14183,7 +14187,7 @@ </parameter> <parameter name="password" type="java.lang.String"> </parameter> -<parameter name="extras" type="android.os.Bundle"> +<parameter name="userdata" type="android.os.Bundle"> </parameter> </method> <method name="addOnAccountsUpdatedListener" @@ -14349,7 +14353,7 @@ </parameter> <parameter name="authTokenType" type="java.lang.String"> </parameter> -<parameter name="loginOptions" type="android.os.Bundle"> +<parameter name="options" type="android.os.Bundle"> </parameter> <parameter name="activity" type="android.app.Activity"> </parameter> @@ -14399,7 +14403,7 @@ </parameter> <parameter name="addAccountOptions" type="android.os.Bundle"> </parameter> -<parameter name="loginOptions" type="android.os.Bundle"> +<parameter name="getAuthTokenOptions" type="android.os.Bundle"> </parameter> <parameter name="callback" type="android.accounts.AccountManagerCallback&lt;android.os.Bundle&gt;"> </parameter> @@ -14568,7 +14572,7 @@ </parameter> <parameter name="authTokenType" type="java.lang.String"> </parameter> -<parameter name="loginOptions" type="android.os.Bundle"> +<parameter name="options" type="android.os.Bundle"> </parameter> <parameter name="activity" type="android.app.Activity"> </parameter> diff --git a/core/java/android/accounts/AbstractAccountAuthenticator.java b/core/java/android/accounts/AbstractAccountAuthenticator.java index ee6d748ac6862..0efeb1d36a91b 100644 --- a/core/java/android/accounts/AbstractAccountAuthenticator.java +++ b/core/java/android/accounts/AbstractAccountAuthenticator.java @@ -87,6 +87,9 @@ import android.Manifest; * the {@link AccountAuthenticatorResponse} as {@link AccountManager#KEY_ACCOUNT_MANAGER_RESPONSE}. * The activity must then call {@link AccountAuthenticatorResponse#onResult} or * {@link AccountAuthenticatorResponse#onError} when it is complete. + * <li> If the authenticator cannot synchronously process the request and return a result then it + * may choose to return null and then use the {@link AccountManagerResponse} to send the result + * when it has completed the request. * </ul> * <p> * The following descriptions of each of the abstract authenticator methods will not describe the @@ -111,44 +114,35 @@ public abstract class AbstractAccountAuthenticator { String authTokenType, String[] requiredFeatures, Bundle options) throws RemoteException { checkBinderPermission(); - final Bundle result; try { - result = AbstractAccountAuthenticator.this.addAccount( + final Bundle result = AbstractAccountAuthenticator.this.addAccount( new AccountAuthenticatorResponse(response), accountType, authTokenType, requiredFeatures, options); + if (result != null) { + response.onResult(result); + } } catch (NetworkErrorException e) { response.onError(AccountManager.ERROR_CODE_NETWORK_ERROR, e.getMessage()); - return; } catch (UnsupportedOperationException e) { response.onError(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION, "addAccount not supported"); - return; - } - if (result != null) { - response.onResult(result); - } else { - response.onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, - "no response from the authenticator"); } } public void confirmCredentials(IAccountAuthenticatorResponse response, Account account, Bundle options) throws RemoteException { checkBinderPermission(); - final Bundle result; try { - result = AbstractAccountAuthenticator.this.confirmCredentials( + final Bundle result = AbstractAccountAuthenticator.this.confirmCredentials( new AccountAuthenticatorResponse(response), account, options); + if (result != null) { + response.onResult(result); + } + } catch (NetworkErrorException e) { + response.onError(AccountManager.ERROR_CODE_NETWORK_ERROR, e.getMessage()); } catch (UnsupportedOperationException e) { response.onError(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION, "confirmCredentials not supported"); - return; - } - if (result != null) { - response.onResult(result); - } else { - response.onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, - "no response from the authenticator"); } } @@ -180,9 +174,6 @@ public abstract class AbstractAccountAuthenticator { authTokenType, loginOptions); if (result != null) { response.onResult(result); - } else { - response.onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, - "no response from the authenticator"); } } catch (UnsupportedOperationException e) { response.onError(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION, @@ -195,64 +186,50 @@ public abstract class AbstractAccountAuthenticator { public void updateCredentials(IAccountAuthenticatorResponse response, Account account, String authTokenType, Bundle loginOptions) throws RemoteException { checkBinderPermission(); - final Bundle result; try { - result = AbstractAccountAuthenticator.this.updateCredentials( + final Bundle result = AbstractAccountAuthenticator.this.updateCredentials( new AccountAuthenticatorResponse(response), account, authTokenType, loginOptions); + if (result != null) { + response.onResult(result); + } + } catch (NetworkErrorException e) { + response.onError(AccountManager.ERROR_CODE_NETWORK_ERROR, e.getMessage()); } catch (UnsupportedOperationException e) { response.onError(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION, "updateCredentials not supported"); - return; - } - if (result != null) { - response.onResult(result); - } else { - response.onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, - "no response from the authenticator"); } } public void editProperties(IAccountAuthenticatorResponse response, String accountType) throws RemoteException { checkBinderPermission(); - final Bundle result; try { - result = AbstractAccountAuthenticator.this.editProperties( + final Bundle result = AbstractAccountAuthenticator.this.editProperties( new AccountAuthenticatorResponse(response), accountType); + if (result != null) { + response.onResult(result); + } } catch (UnsupportedOperationException e) { response.onError(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION, "editProperties not supported"); - return; - } - if (result != null) { - response.onResult(result); - } else { - response.onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, - "no response from the authenticator"); } } public void hasFeatures(IAccountAuthenticatorResponse response, Account account, String[] features) throws RemoteException { checkBinderPermission(); - final Bundle result; try { - result = AbstractAccountAuthenticator.this.hasFeatures( + final Bundle result = AbstractAccountAuthenticator.this.hasFeatures( new AccountAuthenticatorResponse(response), account, features); + if (result != null) { + response.onResult(result); + } } catch (UnsupportedOperationException e) { response.onError(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION, "hasFeatures not supported"); - return; } catch (NetworkErrorException e) { response.onError(AccountManager.ERROR_CODE_NETWORK_ERROR, e.getMessage()); - return; - } - if (result != null) { - response.onResult(result); - } else { - response.onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, - "no response from the authenticator"); } } @@ -264,9 +241,6 @@ public abstract class AbstractAccountAuthenticator { new AccountAuthenticatorResponse(response), account); if (result != null) { response.onResult(result); - } else { - response.onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, - "no response from the authenticator"); } } catch (UnsupportedOperationException e) { response.onError(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION, @@ -347,16 +321,18 @@ public abstract class AbstractAccountAuthenticator { * <li> {@link AccountManager#KEY_ERROR_CODE} and {@link AccountManager#KEY_ERROR_MESSAGE} to * indicate an error * </ul> + * @throws NetworkErrorException if the authenticator could not honor the request due to a + * network error */ public abstract Bundle confirmCredentials(AccountAuthenticatorResponse response, - Account account, Bundle options); - + Account account, Bundle options) + throws NetworkErrorException; /** * Gets the authtoken for an account. * @param response to send the result back to the AccountManager, will never be null * @param account the account whose credentials are to be retrieved, will never be null * @param authTokenType the type of auth token to retrieve, will never be null - * @param loginOptions a Bundle of authenticator-specific options, may be null + * @param options a Bundle of authenticator-specific options, may be null * @return a Bundle result or null if the result is to be returned via the response. The result * will contain either: * <ul> @@ -370,7 +346,7 @@ public abstract class AbstractAccountAuthenticator { * network error */ public abstract Bundle getAuthToken(AccountAuthenticatorResponse response, - Account account, String authTokenType, Bundle loginOptions) + Account account, String authTokenType, Bundle options) throws NetworkErrorException; /** @@ -386,7 +362,7 @@ public abstract class AbstractAccountAuthenticator { * @param account the account whose credentials are to be updated, will never be null * @param authTokenType the type of auth token to retrieve after updating the credentials, * may be null - * @param loginOptions a Bundle of authenticator-specific options, may be null + * @param options a Bundle of authenticator-specific options, may be null * @return a Bundle result or null if the result is to be returned via the response. The result * will contain either: * <ul> @@ -397,9 +373,11 @@ public abstract class AbstractAccountAuthenticator { * <li> {@link AccountManager#KEY_ERROR_CODE} and {@link AccountManager#KEY_ERROR_MESSAGE} to * indicate an error * </ul> + * @throws NetworkErrorException if the authenticator could not honor the request due to a + * network error */ public abstract Bundle updateCredentials(AccountAuthenticatorResponse response, - Account account, String authTokenType, Bundle loginOptions); + Account account, String authTokenType, Bundle options) throws NetworkErrorException; /** * Checks if the account supports all the specified authenticator specific features. diff --git a/core/java/android/accounts/AccountAuthenticatorActivity.java b/core/java/android/accounts/AccountAuthenticatorActivity.java index 3d7be481c75d6..5cce6da6d0ca6 100644 --- a/core/java/android/accounts/AccountAuthenticatorActivity.java +++ b/core/java/android/accounts/AccountAuthenticatorActivity.java @@ -56,30 +56,14 @@ public class AccountAuthenticatorActivity extends Activity { protected void onCreate(Bundle icicle) { super.onCreate(icicle); - if (icicle == null) { - Intent intent = getIntent(); - mAccountAuthenticatorResponse = - intent.getParcelableExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE); - } else { - mAccountAuthenticatorResponse = - icicle.getParcelable(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE); - } + mAccountAuthenticatorResponse = + getIntent().getParcelableExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE); if (mAccountAuthenticatorResponse != null) { mAccountAuthenticatorResponse.onRequestContinued(); } } - /** - * Saves the AccountAuthenticatorResponse in the instance state. - * @param outState where to store any instance data - */ - protected void onSaveInstanceState(Bundle outState) { - outState.putParcelable(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, - mAccountAuthenticatorResponse); - super.onSaveInstanceState(outState); - } - /** * Sends the result or a Constants.ERROR_CODE_CANCELED error if a result isn't present. */ @@ -89,7 +73,8 @@ public class AccountAuthenticatorActivity extends Activity { if (mResultBundle != null) { mAccountAuthenticatorResponse.onResult(mResultBundle); } else { - mAccountAuthenticatorResponse.onError(AccountManager.ERROR_CODE_CANCELED, "canceled"); + mAccountAuthenticatorResponse.onError(AccountManager.ERROR_CODE_CANCELED, + "canceled"); } mAccountAuthenticatorResponse = null; } diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java index 153d95f559b44..46dc895a826e8 100644 --- a/core/java/android/accounts/AccountManager.java +++ b/core/java/android/accounts/AccountManager.java @@ -237,13 +237,13 @@ public class AccountManager { * with the same UID as the Authenticator for the account. * @param account The account to add * @param password The password to associate with the account. May be null. - * @param extras A bundle of key/value pairs to set as the account's userdata. May be null. + * @param userdata A bundle of key/value pairs to set as the account's userdata. May be null. * @return true if the account was sucessfully added, false otherwise, for example, * if the account already exists or if the account is null */ - public boolean addAccountExplicitly(Account account, String password, Bundle extras) { + public boolean addAccountExplicitly(Account account, String password, Bundle userdata) { try { - return mService.addAccount(account, password, extras); + return mService.addAccount(account, password, userdata); } catch (RemoteException e) { // won't ever happen throw new RuntimeException(e); @@ -320,6 +320,12 @@ public class AccountManager { * AccountManager, null otherwise. */ public String peekAuthToken(final Account account, final String authTokenType) { + if (account == null) { + throw new IllegalArgumentException("the account must not be null"); + } + if (authTokenType == null) { + return null; + } try { return mService.peekAuthToken(account, authTokenType); } catch (RemoteException e) { @@ -339,6 +345,9 @@ public class AccountManager { * @param password the password to set for the account. May be null. */ public void setPassword(final Account account, final String password) { + if (account == null) { + throw new IllegalArgumentException("the account must not be null"); + } try { mService.setPassword(account, password); } catch (RemoteException e) { @@ -355,6 +364,9 @@ public class AccountManager { * @param account the account whose password is to be cleared. Must not be null. */ public void clearPassword(final Account account) { + if (account == null) { + throw new IllegalArgumentException("the account must not be null"); + } try { mService.clearPassword(account); } catch (RemoteException e) { @@ -375,6 +387,12 @@ public class AccountManager { * @param value the value to set. May be null. */ public void setUserData(final Account account, final String key, final String value) { + if (account == null) { + throw new IllegalArgumentException("the account must not be null"); + } + if (key == null) { + throw new IllegalArgumentException("the key must not be null"); + } try { mService.setUserData(account, key, value); } catch (RemoteException e) { @@ -458,7 +476,7 @@ public class AccountManager { * @param account The account whose credentials are to be updated. * @param authTokenType the auth token to retrieve as part of updating the credentials. * May be null. - * @param loginOptions authenticator specific options for the request + * @param options authenticator specific options for the request * @param activity If the authenticator returns a {@link #KEY_INTENT} in the result then * the intent will be started with this activity. If activity is null then the result will * be returned as-is. @@ -474,7 +492,7 @@ public class AccountManager { * If the user presses "back" then the request will be canceled. */ public AccountManagerFuture<Bundle> getAuthToken( - final Account account, final String authTokenType, final Bundle loginOptions, + final Account account, final String authTokenType, final Bundle options, final Activity activity, AccountManagerCallback<Bundle> callback, Handler handler) { if (activity == null) throw new IllegalArgumentException("activity is null"); if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null"); @@ -482,7 +500,7 @@ public class AccountManager { public void doWork() throws RemoteException { mService.getAuthToken(mResponse, account, authTokenType, false /* notifyOnAuthFailure */, true /* expectActivityLaunch */, - loginOptions); + options); } }.start(); } @@ -584,6 +602,9 @@ public class AccountManager { final String authTokenType, final String[] requiredFeatures, final Bundle addAccountOptions, final Activity activity, AccountManagerCallback<Bundle> callback, Handler handler) { + if (accountType == null) { + throw new IllegalArgumentException(); + } return new AmsTask(activity, handler, callback) { public void doWork() throws RemoteException { mService.addAcount(mResponse, accountType, authTokenType, @@ -683,7 +704,7 @@ public class AccountManager { * @param account The account whose credentials are to be updated. * @param authTokenType the auth token to retrieve as part of updating the credentials. * May be null. - * @param loginOptions authenticator specific options for the request + * @param options authenticator specific options for the request * @param activity If the authenticator returns a {@link #KEY_INTENT} in the result then * the intent will be started with this activity. If activity is null then the result will * be returned as-is. @@ -702,13 +723,13 @@ public class AccountManager { */ public AccountManagerFuture<Bundle> updateCredentials(final Account account, final String authTokenType, - final Bundle loginOptions, final Activity activity, + final Bundle options, final Activity activity, final AccountManagerCallback<Bundle> callback, final Handler handler) { return new AmsTask(activity, handler, callback) { public void doWork() throws RemoteException { mService.updateCredentials(mResponse, account, authTokenType, activity != null, - loginOptions); + options); } }.start(); } @@ -1214,7 +1235,7 @@ public class AccountManager { * @param activityForPrompting The activity used to start any account management * activities that are required to fulfill this request. This may be null. * @param addAccountOptions authenticator-specific options used if an account needs to be added - * @param loginOptions authenticator-specific options passed to getAuthToken + * @param getAuthTokenOptions authenticator-specific options passed to getAuthToken * @param callback A callback to invoke when the request completes. If null then * no callback is invoked. * @param handler The {@link Handler} to use to invoke the callback. If null then the @@ -1232,13 +1253,13 @@ public class AccountManager { public AccountManagerFuture<Bundle> getAuthTokenByFeatures( final String accountType, final String authTokenType, final String[] features, final Activity activityForPrompting, final Bundle addAccountOptions, - final Bundle loginOptions, + final Bundle getAuthTokenOptions, final AccountManagerCallback<Bundle> callback, final Handler handler) { if (accountType == null) throw new IllegalArgumentException("account type is null"); if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null"); final GetAuthTokenByTypeAndFeaturesTask task = new GetAuthTokenByTypeAndFeaturesTask(accountType, authTokenType, features, - activityForPrompting, addAccountOptions, loginOptions, callback, handler); + activityForPrompting, addAccountOptions, getAuthTokenOptions, callback, handler); task.start(); return task; } diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java index 3a11cb337b376..9c60141336e63 100644 --- a/core/java/android/accounts/AccountManagerService.java +++ b/core/java/android/accounts/AccountManagerService.java @@ -154,6 +154,7 @@ public class AccountManagerService private static final boolean isDebuggableMonkeyBuild = SystemProperties.getBoolean("ro.monkey", false) && SystemProperties.getBoolean("ro.debuggable", false); + private static final Account[] EMPTY_ACCOUNT_ARRAY = new Account[]{}; static { ACCOUNTS_CHANGED_INTENT = new Intent(AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION); @@ -268,6 +269,10 @@ public class AccountManagerService } private String readPasswordFromDatabase(Account account) { + if (account == null) { + return null; + } + SQLiteDatabase db = mOpenHelper.getReadableDatabase(); Cursor cursor = db.query(TABLE_ACCOUNTS, new String[]{ACCOUNTS_PASSWORD}, ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?", @@ -293,6 +298,10 @@ public class AccountManagerService } private String readUserDataFromDatabase(Account account, String key) { + if (account == null) { + return null; + } + SQLiteDatabase db = mOpenHelper.getReadableDatabase(); Cursor cursor = db.query(TABLE_EXTRAS, new String[]{EXTRAS_VALUE}, EXTRAS_ACCOUNTS_ID @@ -364,6 +373,9 @@ public class AccountManagerService SQLiteDatabase db = mOpenHelper.getWritableDatabase(); db.beginTransaction(); try { + if (account == null) { + return false; + } boolean noBroadcast = false; if (account.type.equals(GOOGLE_ACCOUNT_TYPE)) { // Look for the 'nobroadcast' flag and remove it since we don't want it to persist @@ -417,6 +429,14 @@ public class AccountManagerService checkManageAccountsPermission(); long identityToken = clearCallingIdentity(); try { + if (account == null) { + try { + response.onError(AccountManager.ERROR_CODE_BAD_ARGUMENTS, "null account"); + } catch (RemoteException e) { + // it doesn't matter if we are unable to deliver this error + } + return; + } new RemoveAccountSession(response, account).bind(); } finally { restoreCallingIdentity(identityToken); @@ -513,6 +533,9 @@ public class AccountManagerService } private boolean saveAuthTokenToDatabase(Account account, String type, String authToken) { + if (account == null || type == null) { + return false; + } cancelNotification(getSigninRequiredNotificationId(account)); SQLiteDatabase db = mOpenHelper.getWritableDatabase(); db.beginTransaction(); @@ -539,6 +562,9 @@ public class AccountManagerService } public String readAuthTokenFromDatabase(Account account, String authTokenType) { + if (account == null || authTokenType == null) { + return null; + } SQLiteDatabase db = mOpenHelper.getReadableDatabase(); Cursor cursor = db.query(TABLE_AUTHTOKENS, new String[]{AUTHTOKENS_AUTHTOKEN}, AUTHTOKENS_ACCOUNTS_ID + "=(select _id FROM accounts WHERE name=? AND type=?) AND " @@ -586,6 +612,9 @@ public class AccountManagerService } private void setPasswordInDB(Account account, String password) { + if (account == null) { + return; + } ContentValues values = new ContentValues(); values.put(ACCOUNTS_PASSWORD, password); mOpenHelper.getWritableDatabase().update(TABLE_ACCOUNTS, values, @@ -608,23 +637,12 @@ public class AccountManagerService } } - private void sendResult(IAccountManagerResponse response, Bundle bundle) { - if (response != null) { - try { - response.onResult(bundle); - } catch (RemoteException e) { - // if the caller is dead then there is no one to care about remote - // exceptions - if (Log.isLoggable(TAG, Log.VERBOSE)) { - Log.v(TAG, "failure while notifying response", e); - } - } - } - } - public void setUserData(Account account, String key, String value) { checkAuthenticateAccountsPermission(account); long identityToken = clearCallingIdentity(); + if (account == null) { + return; + } if (account.type.equals(GOOGLE_ACCOUNT_TYPE) && key.equals("broadcast")) { sendAccountsChangedBroadcast(); return; @@ -637,6 +655,9 @@ public class AccountManagerService } private void writeUserdataIntoDatabase(Account account, String key, String value) { + if (account == null || key == null) { + return; + } SQLiteDatabase db = mOpenHelper.getWritableDatabase(); db.beginTransaction(); try { @@ -685,6 +706,22 @@ public class AccountManagerService long identityToken = clearCallingIdentity(); try { + try { + if (account == null) { + response.onError(AccountManager.ERROR_CODE_BAD_ARGUMENTS, + "account is null"); + return; + } + if (authTokenType == null) { + response.onError(AccountManager.ERROR_CODE_BAD_ARGUMENTS, + "authTokenType is null"); + return; + } + } catch (RemoteException e) { + // it doesn't matter if we can't deliver this error + return; + } + // if the caller has permission, do the peek. otherwise go the more expensive // route of starting a Session if (permissionGranted) { @@ -850,6 +887,16 @@ public class AccountManagerService checkManageAccountsPermission(); long identityToken = clearCallingIdentity(); try { + try { + if (authTokenType == null) { + response.onError(AccountManager.ERROR_CODE_BAD_ARGUMENTS, + "authTokenType is null"); + return; + } + } catch (RemoteException e) { + // it doesn't matter if we can't deliver this error + return; + } new Session(response, accountType, expectActivityLaunch) { public void run() throws RemoteException { mAuthenticator.addAccount(this, mAccountType, authTokenType, requiredFeatures, @@ -875,6 +922,16 @@ public class AccountManagerService checkManageAccountsPermission(); long identityToken = clearCallingIdentity(); try { + try { + if (account == null) { + response.onError(AccountManager.ERROR_CODE_BAD_ARGUMENTS, + "account is null"); + return; + } + } catch (RemoteException e) { + // it doesn't matter if we can't deliver this error + return; + } new Session(response, account.type, expectActivityLaunch) { public void run() throws RemoteException { mAuthenticator.confirmCredentials(this, account, options); @@ -895,6 +952,16 @@ public class AccountManagerService checkManageAccountsPermission(); long identityToken = clearCallingIdentity(); try { + try { + if (account == null) { + response.onError(AccountManager.ERROR_CODE_BAD_ARGUMENTS, + "account is null"); + return; + } + } catch (RemoteException e) { + // it doesn't matter if we can't deliver this error + return; + } new Session(response, account.type, expectActivityLaunch) { public void run() throws RemoteException { mAuthenticator.updateCredentials(this, account, authTokenType, loginOptions); @@ -917,6 +984,16 @@ public class AccountManagerService checkManageAccountsPermission(); long identityToken = clearCallingIdentity(); try { + try { + if (accountType == null) { + response.onError(AccountManager.ERROR_CODE_BAD_ARGUMENTS, + "accountType is null"); + return; + } + } catch (RemoteException e) { + // it doesn't matter if we can't deliver this error + return; + } new Session(response, accountType, expectActivityLaunch) { public void run() throws RemoteException { mAuthenticator.editProperties(this, mAccountType); @@ -1565,8 +1642,10 @@ public class AccountManagerService } private boolean permissionIsGranted(Account account, String authTokenType, int callerUid) { - final boolean fromAuthenticator = hasAuthenticatorUid(account.type, callerUid); - final boolean hasExplicitGrants = hasExplicitlyGrantedPermission(account, authTokenType); + final boolean fromAuthenticator = account != null + && hasAuthenticatorUid(account.type, callerUid); + final boolean hasExplicitGrants = account != null + && hasExplicitlyGrantedPermission(account, authTokenType); if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, "checkGrantsOrCallingUidAgainstAuthenticator: caller uid " + callerUid + ", account " + account @@ -1610,7 +1689,7 @@ public class AccountManagerService private void checkCallingUidAgainstAuthenticator(Account account) { final int uid = Binder.getCallingUid(); - if (!hasAuthenticatorUid(account.type, uid)) { + if (account == null || !hasAuthenticatorUid(account.type, uid)) { String msg = "caller uid " + uid + " is different than the authenticator's uid"; Log.w(TAG, msg); throw new SecurityException(msg); @@ -1641,6 +1720,9 @@ public class AccountManagerService * @hide */ public void grantAppPermission(Account account, String authTokenType, int uid) { + if (account == null || authTokenType == null) { + return; + } SQLiteDatabase db = mOpenHelper.getWritableDatabase(); db.beginTransaction(); try { @@ -1668,6 +1750,9 @@ public class AccountManagerService * @hide */ public void revokeAppPermission(Account account, String authTokenType, int uid) { + if (account == null || authTokenType == null) { + return; + } SQLiteDatabase db = mOpenHelper.getWritableDatabase(); db.beginTransaction(); try { From 38a9becfdd23e582571f624b624680cc5938d423 Mon Sep 17 00:00:00 2001 From: Eric Fischer <enf@google.com> Date: Wed, 28 Oct 2009 21:16:52 -0700 Subject: [PATCH 10/10] Import revised translations. DO NOT MERGE --- core/res/res/values-nb/strings.xml | 128 +++++++++--------- core/res/res/values-nl/strings.xml | 2 +- .../res/values-nb/strings.xml | 2 +- .../VpnServices/res/values-nb/strings.xml | 4 +- 4 files changed, 68 insertions(+), 68 deletions(-) diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml index ef90da71092cd..ced4f16a6ceb8 100644 --- a/core/res/res/values-nb/strings.xml +++ b/core/res/res/values-nb/strings.xml @@ -111,7 +111,7 @@ <string name="httpErrorFile" msgid="8250549644091165175">"Kunne ikke åpne filen."</string> <string name="httpErrorFileNotFound" msgid="5588380756326017105">"Fant ikke den forespurte filen."</string> <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"For mange forespørsler blir behandlet. Prøv igjen senere."</string> - <string name="notification_title" msgid="1259940370369187045">"Påloggingsfeil for <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string> + <string name="notification_title" msgid="1259940370369187045">"Innloggingsfeil for <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string> <string name="contentServiceSync" msgid="8353523060269335667">"Synkronisering"</string> <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Synkronisering"</string> <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"For mange slettinger av <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string> @@ -147,8 +147,8 @@ <string name="permgroupdesc_location" msgid="2430258821648348660">"Overvåking av telefonens fysiske plassering"</string> <string name="permgrouplab_network" msgid="5808983377727109831">"Nettverkstilgang"</string> <string name="permgroupdesc_network" msgid="5035763698958415998">"Gir applikasjoner tilgang til diverse nettverksfunksjoner."</string> - <string name="permgrouplab_accounts" msgid="3359646291125325519">"Dine kontoer"</string> - <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Gi tilgang til de tilgjengelige kontoene."</string> + <string name="permgrouplab_accounts" msgid="3359646291125325519">"Google-kontoer"</string> + <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Tilgang til tilgjengelige Google-kontoer."</string> <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"Maskinvarekontroll"</string> <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"Direkte tilgang til maskinvaren på telefonen."</string> <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"Telefonsamtaler"</string> @@ -195,7 +195,7 @@ <string name="permdesc_shutdown" msgid="7046500838746291775">"Lar applikasjonen sette aktivitetshåndtereren i avslutningstilstand. Slår ikke systemet helt av."</string> <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"forhindre applikasjonsbytte"</string> <string name="permdesc_stopAppSwitches" msgid="3857886086919033794">"Lar applikasjonen forhindre brukeren fra å bytte til en annen applikasjon."</string> - <string name="permlab_runSetActivityWatcher" msgid="7811586187574696296">"Blokker popup-vinduer"</string> + <string name="permlab_runSetActivityWatcher" msgid="7811586187574696296">"overvåke og kontrollere all applikasjonsoppstart"</string> <string name="permdesc_runSetActivityWatcher" msgid="3228701938345388092">"Lar applikasjonen overvåke og kontrollere hvordan systemet starter applikasjoner. Ondsinnede applikasjoner kan ta over systemet helt. Denne rettigheten behøves bare for utvikling, aldri for vanlig bruk av telefonen."</string> <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"kringkaste melding om fjernet pakke"</string> <string name="permdesc_broadcastPackageRemoved" msgid="3453286591439891260">"Lar applikasjonen kringkaste en melding om at en applikasjonspakke er blitt fjernet. Ondsinnede applikasjoner kan bruke dette til å drepe vilkårlige andre kjørende applikasjoner."</string> @@ -210,9 +210,9 @@ <string name="permlab_batteryStats" msgid="7863923071360031652">"endre batteristatistikk"</string> <string name="permdesc_batteryStats" msgid="5847319823772230560">"Lar applikasjonen endre på innsamlet batteristatistikk. Ikke ment for vanlige applikasjoner."</string> <string name="permlab_backup" msgid="470013022865453920">"kontrollere backup og gjenoppretting"</string> - <string name="permdesc_backup" msgid="4837493065154256525">"Gir programmet tillatelse til å kontrollere systemets mekanismer for sikkerhetskopiering og·gjenoppretting. Ikke beregnet på vanlige programmer."</string> - <string name="permlab_backup_data" msgid="4057625941707926463">"sikkerhetskopier og gjenopprett programmets data"</string> - <string name="permdesc_backup_data" msgid="8274426305151227766">"Gir programmet tillatelse til å ta del i systemets mekanismer for sikkerhetskopiering og gjenoppretting."</string> + <string name="permdesc_backup" msgid="4837493065154256525">"Lar applikasjonen kontrollere systemets backup- og gjenopprettingsmekanisme. Ikke ment for vanlige applikasjoner."</string> + <string name="permlab_backup_data" msgid="4057625941707926463">"foreta backup og gjenoppretting av applikasjonens data"</string> + <string name="permdesc_backup_data" msgid="8274426305151227766">"Lar applikasjonen delta i systemets backup- og gjenopprettingsmekanisme."</string> <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"vis uautoriserte vinduer"</string> <string name="permdesc_internalSystemWindow" msgid="5895082268284998469">"Tillater at det opprettes vinduer ment for bruk av systemets interne brukergrensesnitt. Ikke ment for vanlige applikasjoner."</string> <string name="permlab_systemAlertWindow" msgid="3372321942941168324">"vise advarsler på systemnivå"</string> @@ -258,7 +258,7 @@ <string name="permlab_writeSettings" msgid="1365523497395143704">"endre globale systeminnstillinger"</string> <string name="permdesc_writeSettings" msgid="838789419871034696">"Lar applikasjonen endre systemets innstillingsdata. Ondsinnede applikasjoner kan skade systemets innstillinger."</string> <string name="permlab_writeSecureSettings" msgid="204676251876718288">"endre sikre systeminnstillinger"</string> - <string name="permdesc_writeSecureSettings" msgid="5497873143539034724">"Gir programmet tillatelse til å endre systemets data for sikkerhetsinnstilling. Ikke beregnet på vanlige programmer."</string> + <string name="permdesc_writeSecureSettings" msgid="5497873143539034724">"Gir programmet tillatelse til å endre systemets data for sikkerhetsinnstilling. Ikke ment for vanlige programmer."</string> <string name="permlab_writeGservices" msgid="2149426664226152185">"redigere Google-tjenestekartet"</string> <string name="permdesc_writeGservices" msgid="6602362746516676175">"Lar applikasjonen redigere Google-tjenestekartet. Ikke ment for bruk av vanlige applikasjoner."</string> <string name="permlab_receiveBootCompleted" msgid="7776779842866993377">"starte automatisk sammen med systemet"</string> @@ -315,8 +315,8 @@ <string name="permdesc_callPhone" msgid="3369867353692722456">"Lar applikasjonen ringe telefonnummer uten inngripen fra brukeren. Ondsinnede applikasjoner kan forårsake uventede oppringinger på telefonregningen. Merk at dette ikke gir applikasjonen lov til å ringe nødnummer."</string> <string name="permlab_callPrivileged" msgid="4198349211108497879">"ringe vilkårlige telefonnummer direkte"</string> <string name="permdesc_callPrivileged" msgid="244405067160028452">"Lar applikasjonen ringe hvilket som helst telefonnummer, inkludert nødnummer, uten inngripen fra brukeren. Ondsinnede applikasjoner kan forårsake unødvendige og ulovlige samtaler til nødtjenester."</string> - <string name="permlab_performCdmaProvisioning" msgid="5604848095315421425">"start CDMA-telefonoppsett direkte"</string> - <string name="permdesc_performCdmaProvisioning" msgid="6457447676108355905">"Gir programmet tillatelse til å starte klargjøring av CDMA. Skadelige programmer kan starte klargjøring av CDMA uten grunn"</string> + <string name="permlab_performCdmaProvisioning" msgid="5604848095315421425">"begynne CDMA-telefonoppsett direkte"</string> + <string name="permdesc_performCdmaProvisioning" msgid="6457447676108355905">"Lar applikasjonen begynne CDMA-oppsett. Ondsinnede applikasjoner kan bruke dette til å starte CDMA-oppsett uten grunn."</string> <string name="permlab_locationUpdates" msgid="7785408253364335740">"kontrollere varsling for plasseringsendring"</string> <string name="permdesc_locationUpdates" msgid="2300018303720930256">"Lar applikasjonen slå av/på varsling om plasseringsendringer fra radioen. Ikke ment for vanlige applikasjoner."</string> <string name="permlab_checkinProperties" msgid="7855259461268734914">"få tilgang til egenskaper for innsjekking"</string> @@ -432,56 +432,56 @@ <item msgid="2506857312718630823">"ICQ"</item> <item msgid="1648797903785279353">"Jabber"</item> </string-array> - <string name="phoneTypeCustom" msgid="1644738059053355820">"Tilpasset"</string> - <string name="phoneTypeHome" msgid="2570923463033985887">"Privat"</string> + <string name="phoneTypeCustom" msgid="1644738059053355820">"Egendefinert"</string> + <string name="phoneTypeHome" msgid="2570923463033985887">"Hjemme"</string> <string name="phoneTypeMobile" msgid="6501463557754751037">"Mobil"</string> <string name="phoneTypeWork" msgid="8863939667059911633">"Arbeid"</string> - <string name="phoneTypeFaxWork" msgid="3517792160008890912">"Send faks (arbeid)"</string> - <string name="phoneTypeFaxHome" msgid="2067265972322971467">"Send faks (privat)"</string> + <string name="phoneTypeFaxWork" msgid="3517792160008890912">"Faks arbeid"</string> + <string name="phoneTypeFaxHome" msgid="2067265972322971467">"Faks hjemme"</string> <string name="phoneTypePager" msgid="7582359955394921732">"Personsøker"</string> <string name="phoneTypeOther" msgid="1544425847868765990">"Annen"</string> - <string name="phoneTypeCallback" msgid="2712175203065678206">"Tilbakeringing"</string> + <string name="phoneTypeCallback" msgid="2712175203065678206">"Tilbakering"</string> <string name="phoneTypeCar" msgid="8738360689616716982">"Bil"</string> - <string name="phoneTypeCompanyMain" msgid="540434356461478916">"Firma (sentralbord)"</string> + <string name="phoneTypeCompanyMain" msgid="540434356461478916">"Firma hoved"</string> <string name="phoneTypeIsdn" msgid="8022453193171370337">"ISDN"</string> <string name="phoneTypeMain" msgid="6766137010628326916">"Hoved"</string> - <string name="phoneTypeOtherFax" msgid="8587657145072446565">"Annen faks"</string> + <string name="phoneTypeOtherFax" msgid="8587657145072446565">"Faks annen"</string> <string name="phoneTypeRadio" msgid="4093738079908667513">"Radio"</string> <string name="phoneTypeTelex" msgid="3367879952476250512">"Teleks"</string> - <string name="phoneTypeTtyTdd" msgid="8606514378585000044">"TTY/TDD"</string> - <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"Mobil (arbeid)"</string> - <string name="phoneTypeWorkPager" msgid="649938731231157056">"Personsøker (arbeid)"</string> + <string name="phoneTypeTtyTdd" msgid="8606514378585000044">"Teksttelefon"</string> + <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"Mobil arbeid"</string> + <string name="phoneTypeWorkPager" msgid="649938731231157056">"Personsøker arbeid"</string> <string name="phoneTypeAssistant" msgid="5596772636128562884">"Assistent"</string> <string name="phoneTypeMms" msgid="7254492275502768992">"MMS"</string> - <string name="eventTypeBirthday" msgid="2813379844211390740">"Fødselsdag"</string> - <string name="eventTypeAnniversary" msgid="3876779744518284000">"Merkedag"</string> - <string name="eventTypeOther" msgid="5834288791948564594">"Aktivitet"</string> - <string name="emailTypeCustom" msgid="8525960257804213846">"Tilpasset"</string> - <string name="emailTypeHome" msgid="449227236140433919">"Privat"</string> + <string name="eventTypeBirthday" msgid="2813379844211390740">"Bursdag"</string> + <string name="eventTypeAnniversary" msgid="3876779744518284000">"Jubileum"</string> + <string name="eventTypeOther" msgid="5834288791948564594">"Akivitet"</string> + <string name="emailTypeCustom" msgid="8525960257804213846">"Egendefinert"</string> + <string name="emailTypeHome" msgid="449227236140433919">"Hjemme"</string> <string name="emailTypeWork" msgid="3548058059601149973">"Arbeid"</string> <string name="emailTypeOther" msgid="2923008695272639549">"Annen"</string> <string name="emailTypeMobile" msgid="119919005321166205">"Mobil"</string> - <string name="postalTypeCustom" msgid="8903206903060479902">"Tilpasset"</string> - <string name="postalTypeHome" msgid="8165756977184483097">"Privat"</string> + <string name="postalTypeCustom" msgid="8903206903060479902">"Egendefinert"</string> + <string name="postalTypeHome" msgid="8165756977184483097">"Hjemme"</string> <string name="postalTypeWork" msgid="5268172772387694495">"Arbeid"</string> <string name="postalTypeOther" msgid="2726111966623584341">"Annen"</string> - <string name="imTypeCustom" msgid="2074028755527826046">"Tilpasset"</string> - <string name="imTypeHome" msgid="6241181032954263892">"Privat"</string> + <string name="imTypeCustom" msgid="2074028755527826046">"Egendefinert"</string> + <string name="imTypeHome" msgid="6241181032954263892">"Hjemme"</string> <string name="imTypeWork" msgid="1371489290242433090">"Arbeid"</string> <string name="imTypeOther" msgid="5377007495735915478">"Annen"</string> - <string name="imProtocolCustom" msgid="6919453836618749992">"Tilpasset"</string> + <string name="imProtocolCustom" msgid="6919453836618749992">"Egendefinert"</string> <string name="imProtocolAim" msgid="7050360612368383417">"AIM"</string> <string name="imProtocolMsn" msgid="144556545420769442">"Windows Live"</string> <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string> <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string> - <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string> + <string name="imProtocolQq" msgid="8887484379494111884">"OQ"</string> <string name="imProtocolGoogleTalk" msgid="3808393979157698766">"Google Talk"</string> <string name="imProtocolIcq" msgid="1574870433606517315">"ICQ"</string> <string name="imProtocolJabber" msgid="2279917630875771722">"Jabber"</string> <string name="imProtocolNetMeeting" msgid="8287625655986827971">"NetMeeting"</string> <string name="orgTypeWork" msgid="29268870505363872">"Arbeid"</string> <string name="orgTypeOther" msgid="3951781131570124082">"Annen"</string> - <string name="orgTypeCustom" msgid="225523415372088322">"Tilpasset"</string> + <string name="orgTypeCustom" msgid="225523415372088322">"Egendefinert"</string> <string name="contact_status_update_attribution" msgid="5112589886094402795">"via <xliff:g id="SOURCE">%1$s</xliff:g>"</string> <string name="contact_status_update_attribution_with_date" msgid="5945386376369979909">"<xliff:g id="DATE">%1$s</xliff:g> via <xliff:g id="SOURCE">%2$s</xliff:g>"</string> <string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"Skriv inn PIN-kode:"</string> @@ -530,17 +530,17 @@ <string name="battery_status_charging" msgid="756617993998772213">"Lader…"</string> <string name="battery_low_title" msgid="7923774589611311406">"Koble til en lader"</string> <string name="battery_low_subtitle" msgid="7388781709819722764">"Batteriet er nesten tomt:"</string> - <string name="battery_low_percent_format" msgid="696154104579022959">"<xliff:g id="NUMBER">%d%%</xliff:g> eller mindre gjenstår."</string> + <string name="battery_low_percent_format" msgid="696154104579022959">"mindre enn <xliff:g id="NUMBER">%d%%</xliff:g> igjen."</string> <string name="battery_low_why" msgid="7279169609518386372">"Batteribruk"</string> - <string name="factorytest_failed" msgid="5410270329114212041">"Factory test failed"</string> + <string name="factorytest_failed" msgid="5410270329114212041">"Fabrikktesten feilet"</string> <string name="factorytest_not_system" msgid="4435201656767276723">"The FACTORY_TEST action is only supported for packages installed in /system/app."</string> <string name="factorytest_no_action" msgid="872991874799998561">"No package was found that provides the FACTORY_TEST action."</string> - <string name="factorytest_reboot" msgid="6320168203050791643">"Reboot"</string> + <string name="factorytest_reboot" msgid="6320168203050791643">"Omstart"</string> <string name="js_dialog_title" msgid="8143918455087008109">"Siden \'<xliff:g id="TITLE">%s</xliff:g> sier:"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> <string name="js_dialog_before_unload" msgid="1901675448179653089">"Naviger bort fra denne siden?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Velg OK for å fortsette, eller Avbryt for å forbli på denne siden."</string> <string name="save_password_label" msgid="6860261758665825069">"Bekreft"</string> - <string name="double_tap_toast" msgid="1068216937244567247">"Tips: trykk to ganger for å zoome inn og ut."</string> + <string name="double_tap_toast" msgid="1068216937244567247">"Dobbelttrykk for å zoome inn og ut."</string> <string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"lese nettleserens logg og bokmerker"</string> <string name="permdesc_readHistoryBookmarks" msgid="4981489815467617191">"Lar applikasjonen lese alle adresser nettleseren har besøkt, og alle nettleserens bokmerker."</string> <string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"skrive til nettleserens logg og bokmerker"</string> @@ -623,7 +623,7 @@ <item quantity="one" msgid="2178576254385739855">"i morgen"</item> <item quantity="other" msgid="2973062968038355991">"om <xliff:g id="COUNT">%d</xliff:g> d"</item> </plurals> - <string name="preposition_for_date" msgid="9093949757757445117">"den <xliff:g id="DATE">%s</xliff:g>"</string> + <string name="preposition_for_date" msgid="9093949757757445117">"<xliff:g id="DATE">%s</xliff:g>"</string> <string name="preposition_for_time" msgid="5506831244263083793">"kl. <xliff:g id="TIME">%s</xliff:g>"</string> <string name="preposition_for_year" msgid="5040395640711867177">"i <xliff:g id="YEAR">%s</xliff:g>"</string> <string name="day" msgid="8144195776058119424">"dag"</string> @@ -675,24 +675,24 @@ <string name="dialog_alert_title" msgid="2049658708609043103">"Merk"</string> <string name="capital_on" msgid="1544682755514494298">"På"</string> <string name="capital_off" msgid="6815870386972805832">"Av"</string> - <string name="whichApplication" msgid="4533185947064773386">"Complete action using"</string> - <string name="alwaysUse" msgid="4583018368000610438">"Use by default for this action."</string> - <string name="clearDefaultHintMsg" msgid="4815455344600932173">"Clear default in Home Settings &gt; Applications &gt; Manage applications."</string> - <string name="chooseActivity" msgid="1009246475582238425">"Select an action"</string> - <string name="noApplications" msgid="1691104391758345586">"No applications can perform this action."</string> - <string name="aerr_title" msgid="653922989522758100">"Sorry!"</string> - <string name="aerr_application" msgid="4683614104336409186">"The application <xliff:g id="APPLICATION">%1$s</xliff:g> (process <xliff:g id="PROCESS">%2$s</xliff:g>) has stopped unexpectedly. Please try again."</string> - <string name="aerr_process" msgid="1551785535966089511">"The process <xliff:g id="PROCESS">%1$s</xliff:g> has stopped unexpectedly. Please try again."</string> - <string name="anr_title" msgid="3100070910664756057">"Sorry!"</string> - <string name="anr_activity_application" msgid="3538242413112507636">"Activity <xliff:g id="ACTIVITY">%1$s</xliff:g> (in application <xliff:g id="APPLICATION">%2$s</xliff:g>) is not responding."</string> - <string name="anr_activity_process" msgid="5420826626009561014">"Activity <xliff:g id="ACTIVITY">%1$s</xliff:g> (in process <xliff:g id="PROCESS">%2$s</xliff:g>) is not responding."</string> - <string name="anr_application_process" msgid="4185842666452210193">"Application <xliff:g id="APPLICATION">%1$s</xliff:g> (in process <xliff:g id="PROCESS">%2$s</xliff:g>) is not responding."</string> - <string name="anr_process" msgid="1246866008169975783">"Process <xliff:g id="PROCESS">%1$s</xliff:g> is not responding."</string> - <string name="force_close" msgid="3653416315450806396">"Force close"</string> + <string name="whichApplication" msgid="4533185947064773386">"Fullfør med"</string> + <string name="alwaysUse" msgid="4583018368000610438">"Bruk som standardvalg."</string> + <string name="clearDefaultHintMsg" msgid="4815455344600932173">"Fjern standardvalg i Innstillinger &gt; Applikasjoner &gt; Installerte applikasjoner."</string> + <string name="chooseActivity" msgid="1009246475582238425">"Velg en aktivitet"</string> + <string name="noApplications" msgid="1691104391758345586">"Ingen applikasjoner kan gjøre dette."</string> + <string name="aerr_title" msgid="653922989522758100">"Beklager!"</string> + <string name="aerr_application" msgid="4683614104336409186">"Applikasjonen <xliff:g id="APPLICATION">%1$s</xliff:g> (prosess <xliff:g id="PROCESS">%2$s</xliff:g>) stoppet uventet. Prøv igjen."</string> + <string name="aerr_process" msgid="1551785535966089511">"Prosessen <xliff:g id="PROCESS">%1$s</xliff:g> stoppet uventet. Prøv igjen."</string> + <string name="anr_title" msgid="3100070910664756057">"Beklager!"</string> + <string name="anr_activity_application" msgid="3538242413112507636">"Aktiviteten <xliff:g id="ACTIVITY">%1$s</xliff:g> (i applikasjonen <xliff:g id="APPLICATION">%2$s</xliff:g>) svarer ikke."</string> + <string name="anr_activity_process" msgid="5420826626009561014">"Aktiviteten <xliff:g id="ACTIVITY">%1$s</xliff:g> (i prosessen <xliff:g id="PROCESS">%2$s</xliff:g>) svarer ikke."</string> + <string name="anr_application_process" msgid="4185842666452210193">"Applikasjonen <xliff:g id="APPLICATION">%1$s</xliff:g> (i prosessen <xliff:g id="PROCESS">%2$s</xliff:g>) svarer ikke."</string> + <string name="anr_process" msgid="1246866008169975783">"Prosessen <xliff:g id="PROCESS">%1$s</xliff:g> svarer ikke."</string> + <string name="force_close" msgid="3653416315450806396">"Tving avslutning"</string> <string name="report" msgid="4060218260984795706">"Rapportér"</string> - <string name="wait" msgid="7147118217226317732">"Wait"</string> + <string name="wait" msgid="7147118217226317732">"Vent"</string> <string name="debug" msgid="9103374629678531849">"Debug"</string> - <string name="sendText" msgid="5132506121645618310">"Select an action for text"</string> + <string name="sendText" msgid="5132506121645618310">"Velg mål for tekst"</string> <string name="volume_ringtone" msgid="6885421406845734650">"Ringetonevolum"</string> <string name="volume_music" msgid="5421651157138628171">"Medievolum"</string> <string name="volume_music_hint_playing_through_bluetooth" msgid="9165984379394601533">"Spiller over Bluetooth"</string> @@ -740,12 +740,12 @@ <string name="usb_storage_stop_message" msgid="2390958966725232848">"Før du slår av USB-lagring, sjekk at du har avmontert enheten i USB-verten. Velg «slå av» for å slå av USB-lagring."</string> <string name="usb_storage_stop_button_mount" msgid="1181858854166273345">"Slå av"</string> <string name="usb_storage_stop_button_unmount" msgid="3774611918660582898">"Avbryt"</string> - <string name="usb_storage_stop_error_message" msgid="3746037090369246731">"Det har oppstått et problem ved deaktiveringen av USB-lagring. Kontroller at du har frakoblet USB-verten, og prøv igjen."</string> + <string name="usb_storage_stop_error_message" msgid="3746037090369246731">"Det har oppstått et problem ved deaktiveringen av USB-lagring. Kontroller at du har demontert USB-verten, og prøv igjen."</string> <string name="extmedia_format_title" msgid="8663247929551095854">"Formatere minnekort"</string> <string name="extmedia_format_message" msgid="3621369962433523619">"Er du sikker på at du ønsker å formatere minnekortet? Alle data på kortet vil gå tapt."</string> - <string name="extmedia_format_button_format" msgid="4131064560127478695">"Format"</string> + <string name="extmedia_format_button_format" msgid="4131064560127478695">"Formatér"</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-debugging tilkoblet"</string> - <string name="adb_active_notification_message" msgid="8470296818270110396">"Velg for å deaktivere USB-feilsøking"</string> + <string name="adb_active_notification_message" msgid="8470296818270110396">"Velg for å deaktivere USB-debugging."</string> <string name="select_input_method" msgid="6865512749462072765">"Velg inndatametode"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ"</string> @@ -777,19 +777,19 @@ <string name="create_contact_using" msgid="4947405226788104538">"Lag kontakt"\n"med nummeret <xliff:g id="NUMBER">%s</xliff:g>"</string> <string name="accessibility_compound_button_selected" msgid="5612776946036285686">"valgt"</string> <string name="accessibility_compound_button_unselected" msgid="8864512895673924091">"ikke valgt"</string> - <string name="grant_credentials_permission_message_desc" msgid="6883276587034335667">"De·oppførte·programmene ber om tilgangstillatelse til påloggingsopplysningene for konto <xliff:g id="ACCOUNT">%1$s</xliff:g> fra <xliff:g id="APPLICATION">%2$s</xliff:g>. Vil du gi denne tillatelsen? I·så·fall·lagres·svaret,·og·du·blir·ikke·spurt·flere·ganger."</string> - <string name="grant_credentials_permission_message_with_authtokenlabel_desc" msgid="3159007601893584687">"De·oppførte·programmene ber om tilgangstillatelse til <xliff:g id="TYPE">%1$s</xliff:g>-påloggingsopplysningene for konto <xliff:g id="ACCOUNT">%2$s</xliff:g> fra <xliff:g id="APPLICATION">%3$s</xliff:g>. Vil du gi denne tillatelsen? I·så·fall·lagres·svaret,·og·du·blir·ikke·spurt·flere·ganger."</string> + <string name="grant_credentials_permission_message_desc" msgid="6883276587034335667">"Det nevnte programmet ber om tilgangstillatelse til påloggingsopplysningene for konto <xliff:g id="ACCOUNT">%1$s</xliff:g> fra <xliff:g id="APPLICATION">%2$s</xliff:g>. Vil du gi denne tillatelsen? I så fall vil svaret ditt bli lagret, og du vil ikke bli spurt flere ganger."</string> + <string name="grant_credentials_permission_message_with_authtokenlabel_desc" msgid="3159007601893584687">"Det nevnte programmet ber om tilgangstillatelse til <xliff:g id="TYPE">%1$s</xliff:g>-påloggingsopplysningene for konto <xliff:g id="ACCOUNT">%2$s</xliff:g> fra <xliff:g id="APPLICATION">%3$s</xliff:g>. Vil du gi denne tillatelsen? I så fall vil svaret ditt bli lagret, og du vil ikke bli spurt flere ganger."</string> <string name="allow" msgid="7225948811296386551">"Tillat"</string> <string name="deny" msgid="2081879885755434506">"Avslå"</string> <string name="permission_request_notification_title" msgid="5390555465778213840">"Tillatelse forespurt"</string> - <string name="permission_request_notification_with_subtitle" msgid="4325409589686688000">"Tillatelse forespurt"\n"for konto <xliff:g id="ACCOUNT">%s</xliff:g>"</string> + <string name="permission_request_notification_with_subtitle" msgid="4325409589686688000">"Trenger tillatelse"\n"for konto <xliff:g id="ACCOUNT">%s</xliff:g>"</string> <string name="input_method_binding_label" msgid="1283557179944992649">"Inndatametode"</string> <string name="sync_binding_label" msgid="3687969138375092423">"Synkronisering"</string> <string name="accessibility_binding_label" msgid="4148120742096474641">"Tilgjengelighet"</string> <string name="wallpaper_binding_label" msgid="1240087844304687662">"Bakgrunnsbilde"</string> - <string name="chooser_wallpaper" msgid="7873476199295190279">"Endre bakgrunnsbilde"</string> - <string name="pptp_vpn_description" msgid="2688045385181439401">"PPTP·(point-to-point·tunneling·protocol)"</string> - <string name="l2tp_vpn_description" msgid="3750692169378923304">"Tunnelprotokoll for lag 2"</string> - <string name="l2tp_ipsec_psk_vpn_description" msgid="3945043564008303239">"Forhåndsdelt nøkkelbasert L2TP/IPSec VPN"</string> - <string name="l2tp_ipsec_crt_vpn_description" msgid="5382714073103653577">"Sertifikatbasert L2TP/IPSec VPN"</string> + <string name="chooser_wallpaper" msgid="7873476199295190279">"Velg bakgrunnsbilde"</string> + <string name="pptp_vpn_description" msgid="2688045385181439401">"Punkt-til-punkt-tunneleringsprotokoll"</string> + <string name="l2tp_vpn_description" msgid="3750692169378923304">"Lag 2-tunneleringsprotokoll"</string> + <string name="l2tp_ipsec_psk_vpn_description" msgid="3945043564008303239">"Passordbasert L2TP/IPSec-VPN"</string> + <string name="l2tp_ipsec_crt_vpn_description" msgid="5382714073103653577">"Sertifikatbasert L2TP/IPSec-VPN"</string> </resources> diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index f4192845370d1..c5f5a4b609842 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -444,7 +444,7 @@ <string name="phoneTypeOther" msgid="1544425847868765990">"Overig"</string> <string name="phoneTypeCallback" msgid="2712175203065678206">"Terugbelnummer"</string> <string name="phoneTypeCar" msgid="8738360689616716982">"Auto"</string> - <string name="phoneTypeCompanyMain" msgid="540434356461478916">"Hoofdkantoor"</string> + <string name="phoneTypeCompanyMain" msgid="540434356461478916">"Bedrijf, algemeen"</string> <string name="phoneTypeIsdn" msgid="8022453193171370337">"ISDN"</string> <string name="phoneTypeMain" msgid="6766137010628326916">"Algemeen"</string> <string name="phoneTypeOtherFax" msgid="8587657145072446565">"Andere fax"</string> diff --git a/packages/SubscribedFeedsProvider/res/values-nb/strings.xml b/packages/SubscribedFeedsProvider/res/values-nb/strings.xml index 53bf3b57193e6..30a2c5ea96368 100644 --- a/packages/SubscribedFeedsProvider/res/values-nb/strings.xml +++ b/packages/SubscribedFeedsProvider/res/values-nb/strings.xml @@ -15,6 +15,6 @@ --> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="app_label" msgid="5400580392303600842">"Synkroniser·innmatinger"</string> + <string name="app_label" msgid="5400580392303600842">"Strømsynkronisering"</string> <string name="provider_label" msgid="3669714991966737047">"Push-abonnementer"</string> </resources> diff --git a/packages/VpnServices/res/values-nb/strings.xml b/packages/VpnServices/res/values-nb/strings.xml index 506f99926de0f..9aac82867b043 100644 --- a/packages/VpnServices/res/values-nb/strings.xml +++ b/packages/VpnServices/res/values-nb/strings.xml @@ -16,7 +16,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4589592829302498102">"VPN-tjenester"</string> - <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> er VPN-tilkoblet"</string> - <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> er VPN-frakoblet"</string> + <string name="vpn_notification_title_connected" msgid="8598654486956133580">"Koblet til VPNet <xliff:g id="PROFILENAME">%s</xliff:g>"</string> + <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"Koblet fra VPNet <xliff:g id="PROFILENAME">%s</xliff:g>"</string> <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Trykk for å koble til et VPN på nytt"</string> </resources>