summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.xml361
-rw-r--r--cmds/stagefright/stagefright.cpp15
-rw-r--r--core/java/android/app/ContextImpl.java5
-rw-r--r--core/java/android/app/Notification.java369
-rw-r--r--core/java/android/app/SharedPreferencesImpl.java6
-rw-r--r--core/java/android/content/ClipboardManager.java2
-rw-r--r--core/java/android/hardware/Camera.java1
-rw-r--r--core/java/android/hardware/SensorManager.java16
-rw-r--r--core/java/android/os/StrictMode.java80
-rw-r--r--core/java/android/provider/Settings.java14
-rw-r--r--core/java/android/server/BluetoothEventLoop.java2
-rw-r--r--core/java/android/webkit/WebSettings.java2
-rw-r--r--core/res/res/drawable-hdpi/overscroll_edge.pngbin1793 -> 9702 bytes
-rw-r--r--core/res/res/drawable-hdpi/overscroll_glow.pngbin37035 -> 54228 bytes
-rw-r--r--core/res/res/drawable-mdpi/overscroll_edge.pngbin2180 -> 9702 bytes
-rw-r--r--core/res/res/drawable-mdpi/overscroll_glow.pngbin30390 -> 54228 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_sys_battery_0.pngbin1034 -> 392 bytes
-rwxr-xr-xcore/res/res/drawable-mdpi/stat_sys_battery_10.pngbin738 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_sys_battery_100.pngbin738 -> 241 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_sys_battery_15.pngbin0 -> 252 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_sys_battery_20.pngbin746 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_sys_battery_28.pngbin0 -> 250 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_sys_battery_40.pngbin769 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_sys_battery_43.pngbin0 -> 261 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_sys_battery_57.pngbin0 -> 254 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_sys_battery_60.pngbin762 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_sys_battery_71.pngbin0 -> 253 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_sys_battery_80.pngbin724 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_sys_battery_85.pngbin0 -> 248 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_sys_battery_charge_anim0.pngbin854 -> 443 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_sys_battery_charge_anim1.pngbin864 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_sys_battery_charge_anim100.pngbin0 -> 429 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_sys_battery_charge_anim15.pngbin0 -> 443 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_sys_battery_charge_anim2.pngbin875 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_sys_battery_charge_anim28.pngbin0 -> 450 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_sys_battery_charge_anim3.pngbin888 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_sys_battery_charge_anim4.pngbin879 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_sys_battery_charge_anim43.pngbin0 -> 452 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_sys_battery_charge_anim5.pngbin868 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_sys_battery_charge_anim57.pngbin0 -> 450 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_sys_battery_charge_anim71.pngbin0 -> 444 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_sys_battery_charge_anim85.pngbin0 -> 430 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_sys_battery_unknown.pngbin895 -> 449 bytes
-rw-r--r--core/res/res/drawable/stat_sys_battery.xml11
-rw-r--r--core/res/res/drawable/stat_sys_battery_charge.xml62
-rw-r--r--core/res/res/layout-xlarge/status_bar_latest_event_content.xml21
-rw-r--r--core/res/res/layout-xlarge/status_bar_latest_event_content_large_icon.xml44
-rw-r--r--core/res/res/layout-xlarge/status_bar_latest_event_ticker.xml44
-rw-r--r--core/res/res/layout-xlarge/status_bar_latest_event_ticker_large_icon.xml44
-rw-r--r--core/res/res/values-xlarge/dimens.xml3
-rw-r--r--core/res/res/values/styles.xml5
-rw-r--r--docs/html/guide/practices/screens_support.jd478
-rw-r--r--docs/html/guide/topics/resources/providing-resources.jd10
-rw-r--r--docs/html/images/axis_globe_inverted.pngbin0 -> 6296 bytes
-rw-r--r--docs/html/images/screens_support/screens-ranges.pngbin8514 -> 21221 bytes
-rw-r--r--docs/html/sdk/adt_download.jd7
-rw-r--r--docs/html/sdk/eclipse-adt.jd4
-rw-r--r--docs/html/sdk/sdk_toc.cs2
-rw-r--r--docs/html/sdk/tools-notes.jd64
-rw-r--r--include/camera/Camera.h14
-rw-r--r--include/camera/CameraHardwareInterface.h4
-rw-r--r--include/camera/CameraParameters.h27
-rw-r--r--include/media/stagefright/AMRWriter.h1
-rw-r--r--include/media/stagefright/FileSource.h1
-rw-r--r--include/media/stagefright/MPEG4Writer.h4
-rw-r--r--media/libmediaplayerservice/StagefrightRecorder.cpp8
-rw-r--r--media/libstagefright/AMRWriter.cpp31
-rw-r--r--media/libstagefright/FileSource.cpp23
-rw-r--r--media/libstagefright/MPEG2TSWriter.cpp2
-rw-r--r--media/libstagefright/MPEG4Writer.cpp66
-rw-r--r--media/libstagefright/StagefrightMediaScanner.cpp9
-rw-r--r--media/libstagefright/rtsp/ARTPWriter.cpp2
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerGetCurrentPositionStateUnitTest.java4
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerGetDurationStateUnitTest.java2
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerPauseStateUnitTest.java8
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerSeekToStateUnitTest.java4
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerSetAudioStreamTypeStateUnitTest.java2
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerStartStateUnitTest.java2
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerStopStateUnitTest.java2
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.pngbin979 -> 0 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_default.pngbin0 -> 1108 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_default.pngbin0 -> 738 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_pressed.pngbin0 -> 1630 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_pressed.pngbin0 -> 2223 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_sysbar_home.pngbin953 -> 0 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_default.pngbin0 -> 958 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_pressed.pngbin0 -> 1787 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_default.pngbin384 -> 633 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_pressed.pngbin0 -> 1950 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu.pngbin301 -> 0 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_default.pngbin0 -> 456 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_pressed.pngbin0 -> 1306 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent.pngbin477 -> 0 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_default.pngbin0 -> 416 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_pressed.pngbin0 -> 1114 bytes
-rw-r--r--packages/SystemUI/res/drawable/ic_sysbar_back.xml (renamed from packages/SystemUI/res/drawable/status_bar_menu.xml)4
-rw-r--r--packages/SystemUI/res/drawable/ic_sysbar_home.xml (renamed from packages/SystemUI/res/drawable/status_bar_home.xml)4
-rw-r--r--packages/SystemUI/res/drawable/ic_sysbar_ime.xml (renamed from packages/SystemUI/res/drawable/status_bar_back.xml)4
-rw-r--r--[-rwxr-xr-x]packages/SystemUI/res/drawable/ic_sysbar_menu.xml (renamed from packages/SystemUI/res/drawable/status_bar_recent.xml)4
-rwxr-xr-xpackages/SystemUI/res/drawable/ic_sysbar_recent.xml21
-rw-r--r--packages/SystemUI/res/drawable/status_bar_ticker_background.xml (renamed from packages/SystemUI/res/drawable/ic_sysbar_icon_bg.xml)18
-rw-r--r--packages/SystemUI/res/drawable/ticker_background.xml27
-rw-r--r--packages/SystemUI/res/layout-xlarge/status_bar.xml32
-rw-r--r--packages/SystemUI/res/layout-xlarge/status_bar_latest_event.xml13
-rw-r--r--packages/SystemUI/res/layout-xlarge/sysbar_panel_notifications.xml43
-rw-r--r--packages/SystemUI/res/layout-xlarge/ticker.xml42
-rw-r--r--packages/SystemUI/res/layout-xlarge/ticker_compat.xml26
-rw-r--r--packages/SystemUI/res/values-xlarge/config.xml3
-rw-r--r--packages/SystemUI/res/values-xlarge/dimens.xml27
-rw-r--r--packages/SystemUI/res/values/colors.xml1
-rw-r--r--packages/SystemUI/res/values/config.xml3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java31
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java27
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java125
-rw-r--r--services/java/com/android/server/BatteryService.java11
-rwxr-xr-xservices/java/com/android/server/NotificationManagerService.java42
-rw-r--r--services/java/com/android/server/WindowManagerService.java2
-rw-r--r--telephony/java/com/android/internal/telephony/DataConnectionTracker.java2
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java49
-rw-r--r--test-runner/src/android/test/IsolatedContext.java5
-rw-r--r--tests/StatusBar/AndroidManifest.xml9
-rw-r--r--tests/StatusBar/res/drawable-mdpi/pineapple.pngbin0 -> 12574 bytes
-rw-r--r--tests/StatusBar/res/layout/confirmation_activity.xml28
-rw-r--r--tests/StatusBar/src/com/android/statusbartest/ConfirmationActivity.java32
-rw-r--r--tests/StatusBar/src/com/android/statusbartest/NotificationBuilderTest.java138
-rw-r--r--tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java89
127 files changed, 1948 insertions, 805 deletions
diff --git a/api/current.xml b/api/current.xml
index 3ccb4e9..3d5a265 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -32205,7 +32205,7 @@
type="android.app.Notification"
static="false"
final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
visibility="public"
>
<parameter name="icon" type="int">
@@ -32254,7 +32254,7 @@
synchronized="false"
static="false"
final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
visibility="public"
>
<parameter name="context" type="android.content.Context">
@@ -32524,6 +32524,16 @@
visibility="public"
>
</field>
+<field name="largeIcon"
+ type="android.graphics.Bitmap"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="ledARGB"
type="int"
transient="false"
@@ -32574,19 +32584,18 @@
visibility="public"
>
</field>
-<field name="tickerIcons"
- type="android.graphics.Bitmap[]"
+<field name="tickerText"
+ type="java.lang.CharSequence"
transient="false"
volatile="false"
- value="null"
static="false"
final="false"
deprecated="not deprecated"
visibility="public"
>
</field>
-<field name="tickerSubtitle"
- type="java.lang.CharSequence"
+<field name="tickerView"
+ type="android.widget.RemoteViews"
transient="false"
volatile="false"
static="false"
@@ -32595,18 +32604,19 @@
visibility="public"
>
</field>
-<field name="tickerText"
- type="java.lang.CharSequence"
+<field name="vibrate"
+ type="long[]"
transient="false"
volatile="false"
+ value="null"
static="false"
final="false"
deprecated="not deprecated"
visibility="public"
>
</field>
-<field name="tickerTitle"
- type="java.lang.CharSequence"
+<field name="when"
+ type="long"
transient="false"
volatile="false"
static="false"
@@ -32615,27 +32625,334 @@
visibility="public"
>
</field>
-<field name="vibrate"
- type="long[]"
- transient="false"
- volatile="false"
- value="null"
+</class>
+<class name="Notification.Builder"
+ extends="java.lang.Object"
+ abstract="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="Notification.Builder"
+ type="android.app.Notification.Builder"
static="false"
final="false"
deprecated="not deprecated"
visibility="public"
>
-</field>
-<field name="when"
- type="long"
- transient="false"
- volatile="false"
+<parameter name="context" type="android.content.Context">
+</parameter>
+</constructor>
+<method name="getNotification"
+ return="android.app.Notification"
+ abstract="false"
+ native="false"
+ synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
visibility="public"
>
-</field>
+</method>
+<method name="setAutoCancel"
+ return="android.app.Notification.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="autoCancel" type="boolean">
+</parameter>
+</method>
+<method name="setContent"
+ return="android.app.Notification.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="views" type="android.widget.RemoteViews">
+</parameter>
+</method>
+<method name="setContentInfo"
+ return="android.app.Notification.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="info" type="java.lang.CharSequence">
+</parameter>
+</method>
+<method name="setContentIntent"
+ return="android.app.Notification.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="intent" type="android.app.PendingIntent">
+</parameter>
+</method>
+<method name="setContentText"
+ return="android.app.Notification.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="text" type="java.lang.CharSequence">
+</parameter>
+</method>
+<method name="setContentTitle"
+ return="android.app.Notification.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="title" type="java.lang.CharSequence">
+</parameter>
+</method>
+<method name="setDefaults"
+ return="android.app.Notification.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="defaults" type="int">
+</parameter>
+</method>
+<method name="setDeleteIntent"
+ return="android.app.Notification.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="intent" type="android.app.PendingIntent">
+</parameter>
+</method>
+<method name="setFullScreenIntent"
+ return="android.app.Notification.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="intent" type="android.app.PendingIntent">
+</parameter>
+<parameter name="highPriority" type="boolean">
+</parameter>
+</method>
+<method name="setLargeIcon"
+ return="android.app.Notification.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="icon" type="android.graphics.Bitmap">
+</parameter>
+</method>
+<method name="setLights"
+ return="android.app.Notification.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="argb" type="int">
+</parameter>
+<parameter name="onMs" type="int">
+</parameter>
+<parameter name="offMs" type="int">
+</parameter>
+</method>
+<method name="setNumber"
+ return="android.app.Notification.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="number" type="int">
+</parameter>
+</method>
+<method name="setOngoing"
+ return="android.app.Notification.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="ongoing" type="boolean">
+</parameter>
+</method>
+<method name="setOnlyAlertOnce"
+ return="android.app.Notification.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="onlyAlertOnce" type="boolean">
+</parameter>
+</method>
+<method name="setSmallIcon"
+ return="android.app.Notification.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="icon" type="int">
+</parameter>
+</method>
+<method name="setSmallIcon"
+ return="android.app.Notification.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="icon" type="int">
+</parameter>
+<parameter name="level" type="int">
+</parameter>
+</method>
+<method name="setSound"
+ return="android.app.Notification.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="sound" type="android.net.Uri">
+</parameter>
+</method>
+<method name="setSound"
+ return="android.app.Notification.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="sound" type="android.net.Uri">
+</parameter>
+<parameter name="streamType" type="int">
+</parameter>
+</method>
+<method name="setTicker"
+ return="android.app.Notification.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="tickerText" type="java.lang.CharSequence">
+</parameter>
+</method>
+<method name="setTicker"
+ return="android.app.Notification.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="tickerText" type="java.lang.CharSequence">
+</parameter>
+<parameter name="views" type="android.widget.RemoteViews">
+</parameter>
+</method>
+<method name="setVibrate"
+ return="android.app.Notification.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="pattern" type="long[]">
+</parameter>
+</method>
+<method name="setWhen"
+ return="android.app.Notification.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="when" type="long">
+</parameter>
+</method>
</class>
<class name="NotificationManager"
extends="java.lang.Object"
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index f0758fd..579d8c3 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -107,6 +107,20 @@ static void displayDecodeHistogram(Vector<int64_t> *decodeTimesUs) {
}
}
+static void displayAVCProfileLevelIfPossible(const sp<MetaData>& meta) {
+ uint32_t type;
+ const void *data;
+ size_t size;
+ if (meta->findData(kKeyAVCC, &type, &data, &size)) {
+ const uint8_t *ptr = (const uint8_t *)data;
+ CHECK(size >= 7);
+ CHECK(ptr[0] == 1); // configurationVersion == 1
+ uint8_t profile = ptr[1];
+ uint8_t level = ptr[3];
+ fprintf(stderr, "AVC video profile %d and level %d\n", profile, level);
+ }
+}
+
static void playSource(OMXClient *client, sp<MediaSource> &source) {
sp<MetaData> meta = source->getFormat();
@@ -126,6 +140,7 @@ static void playSource(OMXClient *client, sp<MediaSource> &source) {
fprintf(stderr, "Failed to instantiate decoder for '%s'.\n", mime);
return;
}
+ displayAVCProfileLevelIfPossible(meta);
}
source.clear();
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index dda3107..82b3f75 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -575,7 +575,8 @@ class ContextImpl extends Context {
}
Map map = null;
- if (prefsFile.exists() && prefsFile.canRead()) {
+ FileStatus stat = new FileStatus();
+ if (FileUtils.getFileStatus(prefsFile.getPath(), stat) && prefsFile.canRead()) {
try {
FileInputStream str = new FileInputStream(prefsFile);
map = XmlUtils.readMapXml(str);
@@ -588,7 +589,7 @@ class ContextImpl extends Context {
Log.w(TAG, "getSharedPreferences", e);
}
}
- sp.replace(map);
+ sp.replace(map, stat);
}
return sp;
}
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index e602518..920e457 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -16,6 +16,7 @@
package android.app;
+import java.text.NumberFormat;
import java.util.Date;
import android.app.PendingIntent;
@@ -29,8 +30,12 @@ import android.os.Parcelable;
import android.text.TextUtils;
import android.text.format.DateFormat;
import android.text.format.DateUtils;
+import android.util.Slog;
+import android.view.View;
import android.widget.RemoteViews;
+import com.android.internal.R;
+
/**
* A class that represents how a persistent notification is to be presented to
* the user using the {@link android.app.NotificationManager}.
@@ -41,6 +46,8 @@ import android.widget.RemoteViews;
*/
public class Notification implements Parcelable
{
+ private static final String TAG = "Notification";
+
/**
* Use all default values (where applicable).
*/
@@ -84,6 +91,15 @@ public class Notification implements Parcelable
public int icon;
/**
+ * If the icon in the status bar is to have more than one level, you can set this. Otherwise,
+ * leave it at its default value of 0.
+ *
+ * @see android.widget.ImageView#setImageLevel
+ * @see android.graphics.drawable#setLevel
+ */
+ public int iconLevel;
+
+ /**
* The number of events that this notification represents. For example, in a new mail
* notification, this could be the number of unread messages. This number is superimposed over
* the icon in the status bar. If the number is 0 or negative, it is not shown in the status
@@ -132,38 +148,15 @@ public class Notification implements Parcelable
* text for when the text scrolls in and when it is displayed all at once
* in conjunction with one or more icons.
*
- * @see #tickerTitle
- * @see #tickerSubtitle
- * @see #tickerIcons
+ * @see #tickerView
*/
public CharSequence tickerText;
/**
- * The title line for the ticker over a the fat status bar on xlarge devices.
- *
- * @see #tickerText
- * @see #tickerSubtitle
- * @see #tickerIcons
- */
- public CharSequence tickerTitle;
-
- /**
- * The subtitle line for the ticker over a the fat status bar on xlarge devices.
- *
- * @see #tickerText
- * @see #tickerTitle
- * @see #tickerIcons
- */
- public CharSequence tickerSubtitle;
-
- /**
- * The icons to show to the left of the other ticker fields.
- *
- * @see #tickerText
- * @see #tickerTitle
- * @see #tickerSubtitle
+ * The view to show as the ticker in the status bar when the notification
+ * is posted.
*/
- public Bitmap[] tickerIcons;
+ public RemoteViews tickerView;
/**
* The view that will represent this notification in the expanded status bar.
@@ -171,13 +164,9 @@ public class Notification implements Parcelable
public RemoteViews contentView;
/**
- * If the icon in the status bar is to have more than one level, you can set this. Otherwise,
- * leave it at its default value of 0.
- *
- * @see android.widget.ImageView#setImageLevel
- * @see android.graphics.drawable#setLevel
+ * The bitmap that may escape the bounds of the panel and bar.
*/
- public int iconLevel;
+ public Bitmap largeIcon;
/**
* The sound to play.
@@ -327,6 +316,7 @@ public class Notification implements Parcelable
/**
* Constructs a Notification object with everything set to 0.
+ * You might want to consider using {@link Builder} instead.
*/
public Notification()
{
@@ -334,7 +324,6 @@ public class Notification implements Parcelable
}
/**
- * @deprecated use {@link #Notification(int,CharSequence,long)} and {@link #setLatestEventInfo}.
* @hide
*/
public Notification(Context context, int icon, CharSequence tickerText, long when,
@@ -356,7 +345,10 @@ public class Notification implements Parcelable
* activates.
* @param when The time to show in the time field. In the System.currentTimeMillis
* timebase.
+ *
+ * @deprecated Use {@link Builder} instead.
*/
+ @Deprecated
public Notification(int icon, CharSequence tickerText, long when)
{
this.icon = icon;
@@ -384,22 +376,13 @@ public class Notification implements Parcelable
tickerText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
}
if (parcel.readInt() != 0) {
- tickerTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
+ tickerView = RemoteViews.CREATOR.createFromParcel(parcel);
}
if (parcel.readInt() != 0) {
- tickerSubtitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
- }
- final int tickerIconCount = parcel.readInt();
- if (tickerIconCount >= 0) {
- tickerIcons = new Bitmap[tickerIconCount];
- for (int i=0; i<tickerIconCount; i++) {
- if (parcel.readInt() != 0) {
- tickerIcons[i] = Bitmap.CREATOR.createFromParcel(parcel);
- }
- }
+ contentView = RemoteViews.CREATOR.createFromParcel(parcel);
}
if (parcel.readInt() != 0) {
- contentView = RemoteViews.CREATOR.createFromParcel(parcel);
+ largeIcon = Bitmap.CREATOR.createFromParcel(parcel);
}
defaults = parcel.readInt();
flags = parcel.readInt();
@@ -434,22 +417,15 @@ public class Notification implements Parcelable
if (this.tickerText != null) {
that.tickerText = this.tickerText.toString();
}
- if (this.tickerTitle != null) {
- that.tickerTitle = this.tickerTitle.toString();
- }
- if (this.tickerSubtitle != null) {
- that.tickerSubtitle = this.tickerSubtitle.toString();
- }
- if (this.tickerIcons != null) {
- final int N = this.tickerIcons.length;
- that.tickerIcons = new Bitmap[N];
- for (int i=0; i<N; i++) {
- that.tickerIcons[i] = Bitmap.createBitmap(this.tickerIcons[i]);
- }
+ if (this.tickerView != null) {
+ that.tickerView = this.tickerView.clone();
}
if (this.contentView != null) {
that.contentView = this.contentView.clone();
}
+ if (this.largeIcon != null) {
+ that.largeIcon = Bitmap.createBitmap(this.largeIcon);
+ }
that.iconLevel = that.iconLevel;
that.sound = this.sound; // android.net.Uri is immutable
that.audioStreamType = this.audioStreamType;
@@ -503,35 +479,21 @@ public class Notification implements Parcelable
} else {
parcel.writeInt(0);
}
- if (tickerTitle != null) {
+ if (tickerView != null) {
parcel.writeInt(1);
- TextUtils.writeToParcel(tickerTitle, parcel, flags);
+ tickerView.writeToParcel(parcel, 0);
} else {
parcel.writeInt(0);
}
- if (tickerSubtitle != null) {
+ if (contentView != null) {
parcel.writeInt(1);
- TextUtils.writeToParcel(tickerSubtitle, parcel, flags);
+ contentView.writeToParcel(parcel, 0);
} else {
parcel.writeInt(0);
}
- if (tickerIcons != null) {
- final int N = tickerIcons.length;
- parcel.writeInt(N);
- for (int i=0; i<N; i++) {
- if (tickerIcons[i] != null) {
- parcel.writeInt(1);
- tickerIcons[i].writeToParcel(parcel, flags);
- } else {
- parcel.writeInt(0);
- }
- }
- } else {
- parcel.writeInt(-1);
- }
- if (contentView != null) {
+ if (largeIcon != null) {
parcel.writeInt(1);
- contentView.writeToParcel(parcel, 0);
+ largeIcon.writeToParcel(parcel, 0);
} else {
parcel.writeInt(0);
}
@@ -591,22 +553,25 @@ public class Notification implements Parcelable
* {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} flag, which requires
* that you take care of task management as described in
* <a href="{@docRoot}guide/topics/fundamentals.html#lcycles">Application Fundamentals: Activities and Tasks</a>.
+ *
+ * @deprecated Use {@link Builder} instead.
*/
+ @Deprecated
public void setLatestEventInfo(Context context,
CharSequence contentTitle, CharSequence contentText, PendingIntent contentIntent) {
RemoteViews contentView = new RemoteViews(context.getPackageName(),
- com.android.internal.R.layout.status_bar_latest_event_content);
+ R.layout.status_bar_latest_event_content);
if (this.icon != 0) {
- contentView.setImageViewResource(com.android.internal.R.id.icon, this.icon);
+ contentView.setImageViewResource(R.id.icon, this.icon);
}
if (contentTitle != null) {
- contentView.setTextViewText(com.android.internal.R.id.title, contentTitle);
+ contentView.setTextViewText(R.id.title, contentTitle);
}
if (contentText != null) {
- contentView.setTextViewText(com.android.internal.R.id.text, contentText);
+ contentView.setTextViewText(R.id.text, contentText);
}
if (this.when != 0) {
- contentView.setLong(com.android.internal.R.id.time, "setTime", when);
+ contentView.setLong(R.id.time, "setTime", when);
}
this.contentView = contentView;
@@ -651,4 +616,242 @@ public class Notification implements Parcelable
sb.append(")");
return sb.toString();
}
+
+ public static class Builder {
+ private Context mContext;
+
+ private long mWhen;
+ private int mSmallIcon;
+ private int mSmallIconLevel;
+ private int mNumber;
+ private CharSequence mContentTitle;
+ private CharSequence mContentText;
+ private CharSequence mContentInfo;
+ private PendingIntent mContentIntent;
+ private RemoteViews mContentView;
+ private PendingIntent mDeleteIntent;
+ private PendingIntent mFullScreenIntent;
+ private CharSequence mTickerText;
+ private RemoteViews mTickerView;
+ private Bitmap mLargeIcon;
+ private Uri mSound;
+ private int mAudioStreamType;
+ private long[] mVibrate;
+ private int mLedArgb;
+ private int mLedOnMs;
+ private int mLedOffMs;
+ private int mDefaults;
+ private int mFlags;
+
+ public Builder(Context context) {
+ mContext = context;
+ mWhen = System.currentTimeMillis();
+ }
+
+ public Builder setWhen(long when) {
+ mWhen = when;
+ return this;
+ }
+
+ public Builder setSmallIcon(int icon) {
+ mSmallIcon = icon;
+ return this;
+ }
+
+ public Builder setSmallIcon(int icon, int level) {
+ mSmallIcon = icon;
+ mSmallIconLevel = level;
+ return this;
+ }
+
+ public Builder setContentTitle(CharSequence title) {
+ mContentTitle = title;
+ return this;
+ }
+
+ public Builder setContentText(CharSequence text) {
+ mContentText = text;
+ return this;
+ }
+
+ public Builder setNumber(int number) {
+ mNumber = number;
+ return this;
+ }
+
+ public Builder setContentInfo(CharSequence info) {
+ mContentInfo = info;
+ return this;
+ }
+
+ public Builder setContent(RemoteViews views) {
+ mContentView = views;
+ return this;
+ }
+
+ public Builder setContentIntent(PendingIntent intent) {
+ mContentIntent = intent;
+ return this;
+ }
+
+ public Builder setDeleteIntent(PendingIntent intent) {
+ mDeleteIntent = intent;
+ return this;
+ }
+
+ public Builder setFullScreenIntent(PendingIntent intent, boolean highPriority) {
+ mFullScreenIntent = intent;
+ setFlag(FLAG_HIGH_PRIORITY, highPriority);
+ return this;
+ }
+
+ public Builder setTicker(CharSequence tickerText) {
+ mTickerText = tickerText;
+ return this;
+ }
+
+ public Builder setTicker(CharSequence tickerText, RemoteViews views) {
+ mTickerText = tickerText;
+ mTickerView = views;
+ return this;
+ }
+
+ public Builder setLargeIcon(Bitmap icon) {
+ mLargeIcon = icon;
+ return this;
+ }
+
+ public Builder setSound(Uri sound) {
+ mSound = sound;
+ mAudioStreamType = STREAM_DEFAULT;
+ return this;
+ }
+
+ public Builder setSound(Uri sound, int streamType) {
+ mSound = sound;
+ mAudioStreamType = streamType;
+ return this;
+ }
+
+ public Builder setVibrate(long[] pattern) {
+ mVibrate = pattern;
+ return this;
+ }
+
+ public Builder setLights(int argb, int onMs, int offMs) {
+ mLedArgb = argb;
+ mLedOnMs = onMs;
+ mLedOffMs = offMs;
+ mFlags |= FLAG_SHOW_LIGHTS;
+ return this;
+ }
+
+ public Builder setOngoing(boolean ongoing) {
+ setFlag(FLAG_ONGOING_EVENT, ongoing);
+ return this;
+ }
+
+ public Builder setOnlyAlertOnce(boolean onlyAlertOnce) {
+ setFlag(FLAG_ONLY_ALERT_ONCE, onlyAlertOnce);
+ return this;
+ }
+
+ public Builder setAutoCancel(boolean autoCancel) {
+ setFlag(FLAG_ONLY_ALERT_ONCE, autoCancel);
+ return this;
+ }
+
+ public Builder setDefaults(int defaults) {
+ mDefaults = defaults;
+ int moreFlags = 0;
+ if ((defaults & DEFAULT_LIGHTS) != 0) {
+ moreFlags |= FLAG_SHOW_LIGHTS;
+ }
+ return this;
+ }
+
+ private void setFlag(int mask, boolean value) {
+ if (value) {
+ mFlags |= mask;
+ } else {
+ mFlags &= ~mask;
+ }
+ }
+
+ private RemoteViews makeRemoteViews(int resId) {
+ RemoteViews contentView = new RemoteViews(mContext.getPackageName(), resId);
+ if (mSmallIcon != 0) {
+ contentView.setImageViewResource(R.id.icon, mSmallIcon);
+ }
+ if (mContentTitle != null) {
+ contentView.setTextViewText(R.id.title, mContentTitle);
+ }
+ if (mContentText != null) {
+ contentView.setTextViewText(R.id.text, mContentText);
+ }
+ if (mContentInfo != null) {
+ contentView.setTextViewText(R.id.info, mContentInfo);
+ } else if (mNumber > 0) {
+ NumberFormat f = NumberFormat.getIntegerInstance();
+ contentView.setTextViewText(R.id.info, f.format(mNumber));
+ contentView.setFloat(R.id.info, "setTextSize",
+ mContext.getResources().getDimensionPixelSize(
+ R.dimen.status_bar_content_number_size));
+ } else {
+ contentView.setViewVisibility(R.id.info, View.GONE);
+ }
+ if (mWhen != 0) {
+ contentView.setLong(R.id.time, "setTime", mWhen);
+ }
+ return contentView;
+ }
+
+ private RemoteViews makeContentView() {
+ if (mContentView != null) {
+ return mContentView;
+ } else {
+ return makeRemoteViews(mLargeIcon == null
+ ? R.layout.status_bar_latest_event_content
+ : R.layout.status_bar_latest_event_content_large_icon);
+ }
+ }
+
+ private RemoteViews makeTickerView() {
+ if (mTickerView != null) {
+ return mTickerView;
+ } else {
+ if (mContentView == null) {
+ return makeRemoteViews(mLargeIcon == null
+ ? R.layout.status_bar_latest_event_ticker
+ : R.layout.status_bar_latest_event_ticker_large_icon);
+ } else {
+ return null;
+ }
+ }
+ }
+
+ public Notification getNotification() {
+ Notification n = new Notification();
+ n.when = mWhen;
+ n.icon = mSmallIcon;
+ n.iconLevel = mSmallIconLevel;
+ n.number = mNumber;
+ n.contentView = makeContentView();
+ n.contentIntent = mContentIntent;
+ n.deleteIntent = mDeleteIntent;
+ n.fullScreenIntent = mFullScreenIntent;
+ n.tickerText = mTickerText;
+ n.tickerView = makeTickerView();
+ n.largeIcon = mLargeIcon;
+ n.sound = mSound;
+ n.audioStreamType = mAudioStreamType;
+ n.vibrate = mVibrate;
+ n.ledARGB = mLedArgb;
+ n.ledOnMS = mLedOnMs;
+ n.ledOffMS = mLedOffMs;
+ n.defaults = mDefaults;
+ n.flags = mFlags;
+ return n;
+ }
+ }
}
diff --git a/core/java/android/app/SharedPreferencesImpl.java b/core/java/android/app/SharedPreferencesImpl.java
index 2096a78..a807d3b 100644
--- a/core/java/android/app/SharedPreferencesImpl.java
+++ b/core/java/android/app/SharedPreferencesImpl.java
@@ -103,12 +103,16 @@ final class SharedPreferencesImpl implements SharedPreferences {
}
}
- public void replace(Map newContents) {
+ /*package*/ void replace(Map newContents, FileStatus stat) {
synchronized (this) {
mLoaded = true;
if (newContents != null) {
mMap = newContents;
}
+ if (stat != null) {
+ mStatTimestamp = stat.mtime;
+ mStatSize = stat.size;
+ }
}
}
diff --git a/core/java/android/content/ClipboardManager.java b/core/java/android/content/ClipboardManager.java
index 85a6765..3e2b763 100644
--- a/core/java/android/content/ClipboardManager.java
+++ b/core/java/android/content/ClipboardManager.java
@@ -189,7 +189,7 @@ public class ClipboardManager extends android.text.ClipboardManager {
*/
public boolean hasText() {
try {
- return getService().hasPrimaryClip();
+ return getService().hasClipboardText();
} catch (RemoteException e) {
return false;
}
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 378189e..f3b2c81 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -906,6 +906,7 @@ public class Camera {
* Changes the settings for this Camera service.
*
* @param params the Parameters to use for this Camera service
+ * @throws RuntimeException if any parameter is invalid or not supported.
* @see #getParameters()
*/
public void setParameters(Parameters params) {
diff --git a/core/java/android/hardware/SensorManager.java b/core/java/android/hardware/SensorManager.java
index 3f6e4ce..c178aee 100644
--- a/core/java/android/hardware/SensorManager.java
+++ b/core/java/android/hardware/SensorManager.java
@@ -1158,7 +1158,7 @@ public class SensorManager
*
* <p>
* <center><img src="../../../images/axis_globe.png"
- * alt="Sensors coordinate-system diagram." border="0" /></center>
+ * alt="World coordinate-system diagram." border="0" /></center>
* </p>
*
* <p>
@@ -1521,9 +1521,19 @@ public class SensorManager
* <li>values[1]: <i>pitch</i>, rotation around the X axis.</li>
* <li>values[2]: <i>roll</i>, rotation around the Y axis.</li>
* </ul>
+ * <p>The reference coordinate-system used is different from the world
+ * coordinate-system defined for the rotation matrix:</p>
+ * <ul>
+ * <li>X is defined as the vector product <b>Y.Z</b> (It is tangential to
+ * the ground at the device's current location and roughly points West).</li>
+ * <li>Y is tangential to the ground at the device's current location and
+ * points towards the magnetic North Pole.</li>
+ * <li>Z points towards the center of the Earth and is perpendicular to the ground.</li>
+ * </ul>
+ *
* <p>
- * <center><img src="../../../images/axis_device.png"
- * alt="Sensors coordinate-system diagram." border="0" /></center>
+ * <center><img src="../../../images/axis_device_inverted.png"
+ * alt="Inverted world coordinate-system diagram." border="0" /></center>
* </p>
* <p>
* All three angles above are in <b>radians</b> and <b>positive</b> in the
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java
index c836e56..4facc39 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -32,6 +32,7 @@ import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.concurrent.atomic.AtomicInteger;
/**
* <p>StrictMode is a developer tool which detects things you might be
@@ -208,6 +209,12 @@ public final class StrictMode {
*/
private static volatile int sVmPolicyMask = 0;
+ /**
+ * The number of threads trying to do an async dropbox write.
+ * Just to limit ourselves out of paranoia.
+ */
+ private static final AtomicInteger sDropboxCallsInFlight = new AtomicInteger(0);
+
private StrictMode() {}
/**
@@ -984,7 +991,6 @@ public final class StrictMode {
if (violationMaskSubset != 0) {
int violationBit = parseViolationFromMessage(info.crashInfo.exceptionMessage);
violationMaskSubset |= violationBit;
- final int violationMaskSubsetFinal = violationMaskSubset;
final int savedPolicyMask = getThreadPolicyMask();
final boolean justDropBox = (info.policy & PENALTY_MASK) == PENALTY_DROPBOX;
@@ -995,20 +1001,7 @@ public final class StrictMode {
// call synchronously which Binder data suggests
// isn't always super fast, despite the implementation
// in the ActivityManager trying to be mostly async.
- new Thread("callActivityManagerForStrictModeDropbox") {
- public void run() {
- Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
- try {
- ActivityManagerNative.getDefault().
- handleApplicationStrictModeViolation(
- RuntimeInit.getApplicationObject(),
- violationMaskSubsetFinal,
- info);
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException handling StrictMode violation", e);
- }
- }
- }.start();
+ dropboxViolationAsync(violationMaskSubset, info);
return;
}
@@ -1040,6 +1033,44 @@ public final class StrictMode {
}
}
+ /**
+ * In the common case, as set by conditionallyEnableDebugLogging,
+ * we're just dropboxing any violations but not showing a dialog,
+ * not loggging, and not killing the process. In these cases we
+ * don't need to do a synchronous call to the ActivityManager.
+ * This is used by both per-thread and vm-wide violations when
+ * applicable.
+ */
+ private static void dropboxViolationAsync(
+ final int violationMaskSubset, final ViolationInfo info) {
+ int outstanding = sDropboxCallsInFlight.incrementAndGet();
+ if (outstanding > 20) {
+ // What's going on? Let's not make make the situation
+ // worse and just not log.
+ sDropboxCallsInFlight.decrementAndGet();
+ return;
+ }
+
+ if (LOG_V) Log.d(TAG, "Dropboxing async; in-flight=" + outstanding);
+
+ new Thread("callActivityManagerForStrictModeDropbox") {
+ public void run() {
+ Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
+ try {
+ ActivityManagerNative.getDefault().
+ handleApplicationStrictModeViolation(
+ RuntimeInit.getApplicationObject(),
+ violationMaskSubset,
+ info);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException handling StrictMode violation", e);
+ }
+ int outstanding = sDropboxCallsInFlight.decrementAndGet();
+ if (LOG_V) Log.d(TAG, "Dropbox complete; in-flight=" + outstanding);
+ }
+ }.start();
+ }
+
private static class AndroidCloseGuardReporter implements CloseGuard.Reporter {
public void report (String message, Throwable allocationSite) {
onVmPolicyViolation(message, allocationSite);
@@ -1130,14 +1161,25 @@ public final class StrictMode {
Log.e(TAG, message, originStack);
}
- if ((sVmPolicyMask & PENALTY_DROPBOX) != 0) {
- final ViolationInfo info = new ViolationInfo(originStack, sVmPolicyMask);
+ boolean penaltyDropbox = (sVmPolicyMask & PENALTY_DROPBOX) != 0;
+ boolean penaltyDeath = (sVmPolicyMask & PENALTY_DEATH) != 0;
+
+ int violationMaskSubset = PENALTY_DROPBOX | DETECT_VM_CURSOR_LEAKS;
+ ViolationInfo info = new ViolationInfo(originStack, sVmPolicyMask);
+
+ if (penaltyDropbox && !penaltyDeath) {
+ // Common case for userdebug/eng builds. If no death and
+ // just dropboxing, we can do the ActivityManager call
+ // asynchronously.
+ dropboxViolationAsync(violationMaskSubset, info);
+ return;
+ }
+ if (penaltyDropbox) {
// The violationMask, passed to ActivityManager, is a
// subset of the original StrictMode policy bitmask, with
// only the bit violated and penalty bits to be executed
// by the ActivityManagerService remaining set.
- int violationMaskSubset = PENALTY_DROPBOX | DETECT_VM_CURSOR_LEAKS;
final int savedPolicyMask = getThreadPolicyMask();
try {
// First, remove any policy before we call into the Activity Manager,
@@ -1158,7 +1200,7 @@ public final class StrictMode {
}
}
- if ((sVmPolicyMask & PENALTY_DEATH) != 0) {
+ if (penaltyDeath) {
System.err.println("StrictMode VmPolicy violation with POLICY_DEATH; shutting down.");
Process.killProcess(Process.myPid());
System.exit(10);
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 7075774..4ea4a16 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3318,20 +3318,6 @@ public final class Settings {
"pdp_watchdog_max_pdp_reset_fail_count";
/**
- * Address to ping as a last sanity check before attempting any recovery.
- * Unset or set to "0.0.0.0" to skip this check.
- * @hide
- */
- public static final String PDP_WATCHDOG_PING_ADDRESS = "pdp_watchdog_ping_address";
-
- /**
- * The "-w deadline" parameter for the ping, ie, the max time in
- * seconds to spend pinging.
- * @hide
- */
- public static final String PDP_WATCHDOG_PING_DEADLINE = "pdp_watchdog_ping_deadline";
-
- /**
* The interval in milliseconds at which to check gprs registration
* after the first registration mismatch of gprs and voice service,
* to detect possible data network registration problems.
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index 56ab6bf..4f56281 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -287,6 +287,8 @@ class BluetoothEventLoop {
mBluetoothService.setIsDiscovering(true);
intent = new Intent(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
} else {
+ // Stop the discovery.
+ mBluetoothService.cancelDiscovery();
mBluetoothService.setIsDiscovering(false);
intent = new Intent(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
}
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index 4d582ef..f4caa74 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -483,11 +483,11 @@ public class WebSettings {
// default to "en"
buffer.append("en");
}
+ buffer.append("; ");
// add the model for the release build
if ("REL".equals(Build.VERSION.CODENAME)) {
final String model = Build.MODEL;
if (model.length() > 0) {
- buffer.append("; ");
buffer.append(model);
}
}
diff --git a/core/res/res/drawable-hdpi/overscroll_edge.png b/core/res/res/drawable-hdpi/overscroll_edge.png
index 58b4f19..6d3c26d 100644
--- a/core/res/res/drawable-hdpi/overscroll_edge.png
+++ b/core/res/res/drawable-hdpi/overscroll_edge.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/overscroll_glow.png b/core/res/res/drawable-hdpi/overscroll_glow.png
index fa58f1e..0b0b936 100644
--- a/core/res/res/drawable-hdpi/overscroll_glow.png
+++ b/core/res/res/drawable-hdpi/overscroll_glow.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/overscroll_edge.png b/core/res/res/drawable-mdpi/overscroll_edge.png
index 22f4ef8..6d3c26d 100644
--- a/core/res/res/drawable-mdpi/overscroll_edge.png
+++ b/core/res/res/drawable-mdpi/overscroll_edge.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/overscroll_glow.png b/core/res/res/drawable-mdpi/overscroll_glow.png
index 761fb74..0b0b936 100644
--- a/core/res/res/drawable-mdpi/overscroll_glow.png
+++ b/core/res/res/drawable-mdpi/overscroll_glow.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_0.png b/core/res/res/drawable-mdpi/stat_sys_battery_0.png
index 4a5e99e..750e652 100644
--- a/core/res/res/drawable-mdpi/stat_sys_battery_0.png
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_0.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_10.png b/core/res/res/drawable-mdpi/stat_sys_battery_10.png
deleted file mode 100755
index b789f23..0000000
--- a/core/res/res/drawable-mdpi/stat_sys_battery_10.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_100.png b/core/res/res/drawable-mdpi/stat_sys_battery_100.png
index d280aeb..70d7fa4 100644
--- a/core/res/res/drawable-mdpi/stat_sys_battery_100.png
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_100.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_15.png b/core/res/res/drawable-mdpi/stat_sys_battery_15.png
new file mode 100644
index 0000000..0eb58e1
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_15.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_20.png b/core/res/res/drawable-mdpi/stat_sys_battery_20.png
deleted file mode 100644
index 009a9fd..0000000
--- a/core/res/res/drawable-mdpi/stat_sys_battery_20.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_28.png b/core/res/res/drawable-mdpi/stat_sys_battery_28.png
new file mode 100644
index 0000000..f634dde
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_28.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_40.png b/core/res/res/drawable-mdpi/stat_sys_battery_40.png
deleted file mode 100644
index 15b57f4..0000000
--- a/core/res/res/drawable-mdpi/stat_sys_battery_40.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_43.png b/core/res/res/drawable-mdpi/stat_sys_battery_43.png
new file mode 100644
index 0000000..f0376bd
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_43.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_57.png b/core/res/res/drawable-mdpi/stat_sys_battery_57.png
new file mode 100644
index 0000000..840af66
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_57.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_60.png b/core/res/res/drawable-mdpi/stat_sys_battery_60.png
deleted file mode 100644
index 21078fd..0000000
--- a/core/res/res/drawable-mdpi/stat_sys_battery_60.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_71.png b/core/res/res/drawable-mdpi/stat_sys_battery_71.png
new file mode 100644
index 0000000..04c3569
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_71.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_80.png b/core/res/res/drawable-mdpi/stat_sys_battery_80.png
deleted file mode 100644
index 9268f7b..0000000
--- a/core/res/res/drawable-mdpi/stat_sys_battery_80.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_85.png b/core/res/res/drawable-mdpi/stat_sys_battery_85.png
new file mode 100644
index 0000000..c742da7
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_85.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim0.png b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim0.png
index ff3cabd..957dab3 100644
--- a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim0.png
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim0.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim1.png b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim1.png
deleted file mode 100644
index b563701..0000000
--- a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim1.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim100.png b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim100.png
new file mode 100644
index 0000000..e6d7da0
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim100.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim15.png b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim15.png
new file mode 100644
index 0000000..957dab3
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim15.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim2.png b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim2.png
deleted file mode 100644
index 904989e..0000000
--- a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim2.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim28.png b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim28.png
new file mode 100644
index 0000000..5aba0bb
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim28.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim3.png b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim3.png
deleted file mode 100644
index ba011c9..0000000
--- a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim3.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim4.png b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim4.png
deleted file mode 100644
index 4f1c485..0000000
--- a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim4.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim43.png b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim43.png
new file mode 100644
index 0000000..dc5fac6
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim43.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim5.png b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim5.png
deleted file mode 100644
index 4d3396d..0000000
--- a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim5.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim57.png b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim57.png
new file mode 100644
index 0000000..1233ed8
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim57.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim71.png b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim71.png
new file mode 100644
index 0000000..06d397b
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim71.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim85.png b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim85.png
new file mode 100644
index 0000000..1056faf
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim85.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_unknown.png b/core/res/res/drawable-mdpi/stat_sys_battery_unknown.png
index ed72ebf..44eb313 100644
--- a/core/res/res/drawable-mdpi/stat_sys_battery_unknown.png
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_unknown.png
Binary files differ
diff --git a/core/res/res/drawable/stat_sys_battery.xml b/core/res/res/drawable/stat_sys_battery.xml
index 968595d..1060375 100644
--- a/core/res/res/drawable/stat_sys_battery.xml
+++ b/core/res/res/drawable/stat_sys_battery.xml
@@ -20,11 +20,12 @@
<level-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:maxLevel="4" android:drawable="@android:drawable/stat_sys_battery_0" />
- <item android:maxLevel="14" android:drawable="@android:drawable/stat_sys_battery_10" />
- <item android:maxLevel="29" android:drawable="@android:drawable/stat_sys_battery_20" />
- <item android:maxLevel="49" android:drawable="@android:drawable/stat_sys_battery_40" />
- <item android:maxLevel="69" android:drawable="@android:drawable/stat_sys_battery_60" />
- <item android:maxLevel="89" android:drawable="@android:drawable/stat_sys_battery_80" />
+ <item android:maxLevel="15" android:drawable="@android:drawable/stat_sys_battery_15" />
+ <item android:maxLevel="35" android:drawable="@android:drawable/stat_sys_battery_28" />
+ <item android:maxLevel="49" android:drawable="@android:drawable/stat_sys_battery_43" />
+ <item android:maxLevel="60" android:drawable="@android:drawable/stat_sys_battery_57" />
+ <item android:maxLevel="75" android:drawable="@android:drawable/stat_sys_battery_71" />
+ <item android:maxLevel="90" android:drawable="@android:drawable/stat_sys_battery_85" />
<item android:maxLevel="100" android:drawable="@android:drawable/stat_sys_battery_100" />
</level-list>
diff --git a/core/res/res/drawable/stat_sys_battery_charge.xml b/core/res/res/drawable/stat_sys_battery_charge.xml
index 92d7c4f..a6c4575 100644
--- a/core/res/res/drawable/stat_sys_battery_charge.xml
+++ b/core/res/res/drawable/stat_sys_battery_charge.xml
@@ -1,7 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
-/* //device/apps/common/res/drawable/stat_sys_battery.xml
-**
** Copyright 2007, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,56 +17,14 @@
-->
<level-list xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:maxLevel="14">
- <animation-list
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:oneshot="false">
- <item android:drawable="@drawable/stat_sys_battery_charge_anim0" android:duration="2000" />
- <item android:drawable="@drawable/stat_sys_battery_charge_anim1" android:duration="1000" />
- <item android:drawable="@drawable/stat_sys_battery_charge_anim2" android:duration="1000" />
- <item android:drawable="@drawable/stat_sys_battery_charge_anim3" android:duration="1000" />
- <item android:drawable="@drawable/stat_sys_battery_charge_anim4" android:duration="1000" />
- <item android:drawable="@drawable/stat_sys_battery_charge_anim5" android:duration="1000" />
- </animation-list>
- </item>
- <item android:maxLevel="29">
- <animation-list
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:oneshot="false">
- <item android:drawable="@drawable/stat_sys_battery_charge_anim1" android:duration="2000" />
- <item android:drawable="@drawable/stat_sys_battery_charge_anim2" android:duration="1000" />
- <item android:drawable="@drawable/stat_sys_battery_charge_anim3" android:duration="1000" />
- <item android:drawable="@drawable/stat_sys_battery_charge_anim4" android:duration="1000" />
- <item android:drawable="@drawable/stat_sys_battery_charge_anim5" android:duration="1000" />
- </animation-list>
- </item>
- <item android:maxLevel="49">
- <animation-list
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:oneshot="false">
- <item android:drawable="@drawable/stat_sys_battery_charge_anim2" android:duration="2000" />
- <item android:drawable="@drawable/stat_sys_battery_charge_anim3" android:duration="1000" />
- <item android:drawable="@drawable/stat_sys_battery_charge_anim4" android:duration="1000" />
- <item android:drawable="@drawable/stat_sys_battery_charge_anim5" android:duration="1000" />
- </animation-list>
- </item>
- <item android:maxLevel="69">
- <animation-list
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:oneshot="false">
- <item android:drawable="@drawable/stat_sys_battery_charge_anim3" android:duration="2000" />
- <item android:drawable="@drawable/stat_sys_battery_charge_anim4" android:duration="1000" />
- <item android:drawable="@drawable/stat_sys_battery_charge_anim5" android:duration="1000" />
- </animation-list>
- </item>
- <item android:maxLevel="89">
- <animation-list
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:oneshot="false">
- <item android:drawable="@drawable/stat_sys_battery_charge_anim4" android:duration="2000" />
- <item android:drawable="@drawable/stat_sys_battery_charge_anim5" android:duration="1000" />
- </animation-list>
- </item>
- <item android:maxLevel="101" android:drawable="@drawable/stat_sys_battery_charge_anim5" />
+ <item android:maxLevel="4" android:drawable="@android:drawable/stat_sys_battery_charge_anim0" />
+ <item android:maxLevel="15" android:drawable="@android:drawable/stat_sys_battery_charge_anim15" />
+ <item android:maxLevel="35" android:drawable="@android:drawable/stat_sys_battery_charge_anim28" />
+ <item android:maxLevel="49" android:drawable="@android:drawable/stat_sys_battery_charge_anim43" />
+ <item android:maxLevel="60" android:drawable="@android:drawable/stat_sys_battery_charge_anim57" />
+ <item android:maxLevel="75" android:drawable="@android:drawable/stat_sys_battery_charge_anim71" />
+ <item android:maxLevel="90" android:drawable="@android:drawable/stat_sys_battery_charge_anim85" />
+ <item android:maxLevel="100" android:drawable="@android:drawable/stat_sys_battery_charge_anim100" />
</level-list>
+
diff --git a/core/res/res/layout-xlarge/status_bar_latest_event_content.xml b/core/res/res/layout-xlarge/status_bar_latest_event_content.xml
index d599154..e4aa270 100644
--- a/core/res/res/layout-xlarge/status_bar_latest_event_content.xml
+++ b/core/res/res/layout-xlarge/status_bar_latest_event_content.xml
@@ -1,23 +1,20 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- >
-
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ >
<ImageView android:id="@+id/icon"
android:layout_width="48dp"
android:layout_height="64dp"
- android:layout_alignParentLeft="true"
- android:layout_alignParentTop="true"
+ android:layout_marginLeft="4dp"
android:scaleType="center"
/>
-
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:orientation="vertical"
- android:paddingLeft="16dp"
+ android:paddingLeft="8dp"
>
<TextView android:id="@+id/title"
android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Title"
@@ -37,5 +34,13 @@
android:fadingEdge="horizontal"
/>
</LinearLayout>
+ <TextView android:id="@+id/info"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Info"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:singleLine="true"
+ android:gravity="center_vertical"
+ android:paddingLeft="8dp"
+ />
</LinearLayout>
diff --git a/core/res/res/layout-xlarge/status_bar_latest_event_content_large_icon.xml b/core/res/res/layout-xlarge/status_bar_latest_event_content_large_icon.xml
new file mode 100644
index 0000000..1e1f9de
--- /dev/null
+++ b/core/res/res/layout-xlarge/status_bar_latest_event_content_large_icon.xml
@@ -0,0 +1,44 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ >
+ <LinearLayout
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:layout_weight="1"
+ android:orientation="vertical"
+ >
+ <TextView android:id="@+id/title"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Title"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:ellipsize="marquee"
+ android:fadingEdge="horizontal"
+ />
+ <TextView android:id="@+id/text"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:singleLine="true"
+ android:ellipsize="marquee"
+ android:fadingEdge="horizontal"
+ />
+ </LinearLayout>
+ <TextView android:id="@+id/info"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Info"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:singleLine="true"
+ android:gravity="center_vertical"
+ android:paddingLeft="8dp"
+ />
+ <ImageView android:id="@+id/icon"
+ android:layout_width="48dp"
+ android:layout_height="64dp"
+ android:scaleType="center"
+ />
+</LinearLayout>
+
diff --git a/core/res/res/layout-xlarge/status_bar_latest_event_ticker.xml b/core/res/res/layout-xlarge/status_bar_latest_event_ticker.xml
new file mode 100644
index 0000000..b09ed44
--- /dev/null
+++ b/core/res/res/layout-xlarge/status_bar_latest_event_ticker.xml
@@ -0,0 +1,44 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/status_bar_height"
+ >
+ <ImageView android:id="@+id/icon"
+ android:layout_width="48dp"
+ android:layout_height="match_parent"
+ android:scaleType="center"
+ />
+ <LinearLayout
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:layout_weight="1"
+ android:orientation="vertical"
+ android:paddingLeft="16dp"
+ >
+ <TextView android:id="@+id/title"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Title"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:ellipsize="marquee"
+ android:fadingEdge="horizontal"
+ />
+ <TextView android:id="@+id/text"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:singleLine="true"
+ android:ellipsize="marquee"
+ android:fadingEdge="horizontal"
+ />
+ </LinearLayout>
+ <TextView android:id="@+id/info"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Info"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:singleLine="true"
+ android:gravity="center_vertical"
+ />
+</LinearLayout>
+
diff --git a/core/res/res/layout-xlarge/status_bar_latest_event_ticker_large_icon.xml b/core/res/res/layout-xlarge/status_bar_latest_event_ticker_large_icon.xml
new file mode 100644
index 0000000..6c2e6f7
--- /dev/null
+++ b/core/res/res/layout-xlarge/status_bar_latest_event_ticker_large_icon.xml
@@ -0,0 +1,44 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ >
+ <LinearLayout
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:layout_weight="1"
+ android:orientation="vertical"
+ android:paddingLeft="16dp"
+ >
+ <TextView android:id="@+id/title"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Title"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:ellipsize="marquee"
+ android:fadingEdge="horizontal"
+ />
+ <TextView android:id="@+id/text"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:singleLine="true"
+ android:ellipsize="marquee"
+ android:fadingEdge="horizontal"
+ />
+ </LinearLayout>
+ <TextView android:id="@+id/info"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Info"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:singleLine="true"
+ android:gravity="center_vertical"
+ />
+ <ImageView android:id="@+id/icon"
+ android:layout_width="48dp"
+ android:layout_height="match_parent"
+ android:scaleType="center"
+ />
+</LinearLayout>
+
diff --git a/core/res/res/values-xlarge/dimens.xml b/core/res/res/values-xlarge/dimens.xml
index f52c627..fef3c13 100644
--- a/core/res/res/values-xlarge/dimens.xml
+++ b/core/res/res/values-xlarge/dimens.xml
@@ -21,6 +21,9 @@
<dimen name="status_bar_height">48dip</dimen>
<!-- Height of the status bar -->
<dimen name="status_bar_icon_size">48dip</dimen>
+ <!-- Size of the giant number (unread count) in the notifications -->
+ <dimen name="status_bar_content_number_size">48sp</dimen>
+
<!-- Margin at the edge of the screen to ignore touch events for in the windowshade. -->
<!-- Margin for permanent screen decorations at the bottom. -->
<dimen name="screen_margin_bottom">48dip</dimen>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 403ec2f..7a429b0 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -213,12 +213,17 @@
<item name="android:textStyle">bold</item>
</style>
<style name="TextAppearance.StatusBar.EventContent">
+ <item name="android:textAppearance">?android:attr/textAppearanceSmall</item>
<item name="android:textColor">?android:attr/textColorPrimaryInverse</item>
</style>
<style name="TextAppearance.StatusBar.EventContent.Title">
<item name="android:textSize">18sp</item>
<item name="android:textStyle">bold</item>
</style>
+ <style name="TextAppearance.StatusBar.EventContent.Info">
+ <item name="android:textAppearance">?android:attr/textAppearanceLarge</item>
+ <item name="android:textColor">#ff272727</item>
+ </style>
<!-- Widget Styles -->
diff --git a/docs/html/guide/practices/screens_support.jd b/docs/html/guide/practices/screens_support.jd
index 13b5e3a..7811d90 100644
--- a/docs/html/guide/practices/screens_support.jd
+++ b/docs/html/guide/practices/screens_support.jd
@@ -35,7 +35,9 @@ page.title=Supporting Multiple Screens
<ol>
<li><code><a href="{@docRoot}guide/topics/manifest/supports-screens-element.html">&lt;supports-screens&gt;</a></code></li>
<li><code><a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">&lt;uses-sdk&gt;</a></code></li>
- <li><a href="{@docRoot}guide/topics/resources/providing-resources.html#AlternativeResources">Alternative Resources</a></li>
+ <li><a
+href="{@docRoot}guide/topics/resources/providing-resources.html#AlternativeResources">
+Providing Alternative Resources</a></li>
<li><a href="{@docRoot}guide/developing/tools/avd.html">Android Virtual Devices</a></li>
</ol>
@@ -53,7 +55,7 @@ sizes and resolutions. </p>
<p>This document explains the screens-support features provided by the platform
and how you use them in your application. By following the practices described
here, you can easily create an application that displays properly on all
-supported device screens and that you can deploy to any device as a single .apk.
+supported device screens and that you can deploy to any device as a single {@code .apk}.
</p>
<p>If you have already developed and published an application for Android 1.5 or
@@ -63,10 +65,16 @@ and that are running Android 1.6 or later. In most cases, only minor adjustments
are needed, however you should make sure to <a href="#testing">test your
application</a> on all supported screens. </p>
+<p>Starting in Android 2.2, the platform includes support for extra high density screens
+(<em>xhdpi</em>), and starting in Android 2.3, the platform includes support for extra large screens
+(<em>xlarge</em>). If you've already followed the guidance in this document to support all other
+screen types, you should consider providing additional support for <em>xhdpi</em> and
+<em>xlarge</em> screens.</p>
+
<p>In particular, if you have an existing application that you would like to
-make available for users of devices with small screens (such as QVGA), please
-see <a href="#strategies">Strategies for Legacy Applications</a> for more
-information about how to do that. </p>
+make available on small screens (such as QVGA) or for which you would like to provide better support
+for extra large screens, please see <a href="#strategies">Strategies for Legacy Applications</a> for
+more information about how to do that. </p>
<h2 id="overview">Overview of Screens Support</h2>
@@ -82,11 +90,11 @@ screen-compatibility features.</p>
<dl>
<dt><em>Screen size</em></dt>
- <dd>Actual physical size, measured as the screen's diagonal.
+ <dd>Actual physical size, measured as the screen's diagonal.
- <p>For simplicity, Android collapses all actual screen sizes into three
-generalized sizes: large, normal, and small. Applications can provide custom
-layouts for each of these three sizes &mdash; the platform transparently handles
+ <p>For simplicity, Android collapses all actual screen sizes into four
+generalized sizes: small, normal, large, and extra large. Applications can provide custom
+layouts for each of these four sizes &mdash; the platform transparently handles
the rendering of the layouts at the actual screen size.</p></dd>
<dt><em>Aspect ratio</em></dt>
@@ -110,22 +118,22 @@ sometimes significantly more &mdash; pixels spread across the same area. The
density of a screen is important because, other things being equal, a UI element
(such as a button) whose height and width are defined in terms of screen pixels
will appear larger on the lower density screen and smaller on the higher density
-screen. </p>
+screen.</p>
- <p>For simplicity, Android collapses all actual screen densities into three
-generalized densities: high, medium, and low. Applications can provide custom
-resources for each of these three densities &mdash; the platform handles the
-scaling of the resources up or down to meet the actual screen density. </p></dd>
-<dt><em>Density-independent pixel (dip)</em></dt>
+ <p>For simplicity, Android collapses all actual screen densities into four
+generalized densities: low, medium, large, and extra large. Applications can provide custom
+resources for each of these densities &mdash; the platform handles any necessary
+scaling of the resources up or down to meet the specific screen density. </p></dd>
+<dt><em>Density-independent pixel (dp)</em></dt>
<dd>A virtual pixel unit that applications can use in defining their UI, to
-express layout dimensions or position in a density-independent way.
+express layout dimensions or position in a density-independent way.
<p>The density-independent pixel is equivalent to one physical pixel on a 160
dpi screen, the baseline density assumed by the platform (as described later in
this document). At run time, the platform transparently handles any scaling of
-the dip units needed, based on the actual density of the screen in use. The
-conversion of dip units to screen pixels is simple: <code>pixels = dips *
-(density / 160)</code>. For example, on 240 dpi screen, 1 dip would equal 1.5
-physical pixels. Using dip units to define your application's UI is highly
+the dp units needed, based on the actual density of the screen in use. The
+conversion of dp units to screen pixels is simple: <nobr><code>pixels = dps *
+(density / 160)</code></nobr>. For example, on 240 dpi screen, 1 dp would equal 1.5
+physical pixels. Using dp units to define your application's UI is highly
recommended, as a way of ensuring proper display of your UI on different
screens. </p></dd>
</dl>
@@ -146,13 +154,19 @@ applications, the platform divides the range of actual supported screen sizes
and resolutions into:</p>
<ul>
-<li>A set of three generalized sizes: <em>large</em>, <em>normal</em>, and <em>small</em>, and </li>
-<li>A set of three generalized densities: <em>hdpi</em> (high), <em>mdpi</em> (medium), and <em>ldpi</em> (low)
+<li>A set of four generalized sizes: <em>small</em>, <em>normal</em>, <em>large</em>,
+and <em>xlarge</em></em>
+<li>A set of four generalized densities: <em>ldpi</em> (low), <em>mdpi</em> (medium),
+<em>hdpi</em> (high), and <em>xhdpi</em> (extra high)
</ul>
+<p class="note"><strong>Note:</strong> The <code>xhdpi</code> density category was added in
+Android 2.2 (API Level 8). The <em>xlarge</em> size category was added in Android 2.3 (API Level
+9).</p>
+
<p>Applications can provide custom resources (primarily layouts) for any of the
-three generalized sizes and can provide resources (primarily drawables such as
-images) for any of the three generalized densities. Applications do not need to
+four generalized sizes and can provide resources (primarily drawables such as
+images) for any of the four generalized densities. Applications do not need to
work with the actual physical size or density of the device screen. At run time,
the platform handles the loading of the correct size or density resources, based
on the generalized size or density of the current device screen, and adapts them
@@ -177,8 +191,8 @@ its characteristics. </p>
<img src="{@docRoot}images/screens_support/screens-ranges.png" />
-<p class="img-caption"><strong>Figure 1.</strong>
-Illustration of how the Android platform maps actual screen densities and sizes
+<p class="img-caption"><strong>Figure 1.</strong>
+Illustration of how the Android platform maps actual screen densities and sizes
to generalized density and size configurations. </p>
<p>Although the platform lets your application provide layouts and resources for
@@ -213,6 +227,9 @@ sizes and densities of emulator skins included in the Android SDK.</p>
<td style="background-color:#f3f3f3">
<nobr>High density (240), <em>hdpi</em><nobr>
</td>
+ <td style="background-color:#f3f3f3">
+ <nobr>Extra high density (320), <em>xhdpi</em><nobr>
+ </td>
</tr>
<tr>
<td style="background-color:#f3f3f3">
@@ -222,6 +239,7 @@ sizes and densities of emulator skins included in the Android SDK.</p>
</td>
<td></td>
<td></td>
+ <td></td>
</tr>
<tr>
<td style="background-color:#f3f3f3">
@@ -230,6 +248,7 @@ sizes and densities of emulator skins included in the Android SDK.</p>
<td style="font-size:.9em;">WQVGA400 (240x400)<br>WQVGA432 (240x432)</td>
<td style="font-size:.9em;">HVGA (320x480)</td>
<td style="font-size:.9em;">WVGA800 (480x800)<br>WVGA854 (480x854)</td>
+ <td style="font-size:.9em;"></td>
</tr>
<tr>
<td style="background-color:#f3f3f3">
@@ -238,16 +257,27 @@ sizes and densities of emulator skins included in the Android SDK.</p>
<td></td>
<td style="font-size:.9em;">WVGA800* (480x800)<br>WVGA854* (480x854)</td>
<td></td>
+ <td></td>
+ </tr>
+ <tr>
+ <td style="background-color:#f3f3f3">
+ <em>Extra Large</em> screen
+ </td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
</tr>
<tr>
- <td colspan="4" style="border:none;font-size:90%;">* To emulate this
- configuration, specify a custom density of 160 when
+ <td colspan="4" style="border:none;font-size:90%;">* To emulate this
+ configuration, specify a custom density of 160 when
creating an AVD that uses a WVGA800 or WVGA854 skin.
</td>
+ </tr>
</table>
-<p>For an overview of the relative numbers of high (hdpi), medium (mdpi), and
-low (ldpi) density screens in Android-powered devices available now, see the <a
+<p>For an overview of the relative numbers of high (hdpi), medium (mdpi), and
+low (ldpi) density screens in Android-powered devices available now, see the <a
href="{@docRoot}resources/dashboard/screens.html">Screen Sizes and Densities</a> dashboard.</p>
@@ -262,9 +292,9 @@ resources at run time is based on the alternative resources framework.
<p> If you want to use size- or density-specific layouts or drawables in your
application and you are not familiar with resource qualifiers or how the
-platform uses them, please read
+platform uses them, please read
<a href="{@docRoot}guide/topics/resources/providing-resources.html#AlternativeResources">
-Alternative Resources</a>.
+Providing Alternative Resources</a>.
</div>
</div>
@@ -277,19 +307,20 @@ to use them:</p>
<ul>
<li>The platform supports a set of resource qualifiers that let you provide
-size- and density-specific resources, if needed. The qualifiers for
-size-specific resources are <code>large</code>, <code>normal</code>, and
-<code>small</code>, and those for density-specific resources are
-<code>hdpi</code> (high), <code>mdpi</code> (medium), and <code>ldpi</code>
-(low). The qualifiers correspond to the generalized densities described in
+size- and density-specific resources, if needed. The qualifiers for
+size-specific resources are <code>small</code>, <code>normal</code>, <code>large</code>, and
+<code>xlarge</code>. Those for density-specific resources are <code>ldpi</code>
+(low), <code>mdpi</code> (medium), <code>hdpi</code> (high), and <code>xhdpi</code> (extra high).
+The qualifiers correspond to the generalized densities described in
<a href="#range">Range of screens supported</a>, above.</li>
- <li>The platform also provides a
+ <li>The platform also provides a
<a href="{@docRoot}guide/topics/manifest/supports-screens-element.html">
<code>&lt;supports-screens&gt;</code></a>
manifest element, whose attributes
-<code>android:largeScreens</code>, <code>android:normalScreens</code>, and
-<code>android:smallScreens</code> let you specify what generalized screen sizes
-your application supports. A fourth attribute, <code>android:anyDensity</code>,
+<code>android:smallScreens</code>, <code>android:normalScreens</code>,
+<code>android:largeScreens</code>, and <code>android:xlargeScreens</code> let you specify what
+generalized screen sizes
+your application supports. Another attribute, <code>android:anyDensity</code>,
lets you indicate whether or not your application includes built-in support for
multiple densities.</li>
</ul>
@@ -299,7 +330,7 @@ application, to ensure the best possible display on the current device
screen:</p>
<ol>
-<li><em>Pre-scaling of resources (such as image assets)</em>
+<li><em>Pre-scaling of resources (such as image assets)</em>
<p>Based on the density of the current screen, the platform automatically
loads any size- or density-specific resources from your application and displays
@@ -344,18 +375,18 @@ lower-density screen, coordinates are scaled down.<p>
<p>For more information, see the <code>android:anyDensity</code> attribute in
<a href="#attrs">Manifest attributes for screens support</a>.</p></li>
-<div class="sidebox-wrapper" xstyle="margin-bottom:2em;margin-top:.5em;width:90%;">
- <img id="rule" src="{@docRoot}assets/images/grad-rule-qv.png">
- <div id="qv-sub-rule">
- <img src="{@docRoot}assets/images/icon_market.jpg" style="float:left;margin:0;padding:0;">
- <p style="color:#669999;">Publishing to Small Screen Devices</p>
+<div class="sidebox-wrapper" xstyle="margin-bottom:2em;margin-top:.5em;width:90%;">
+ <img id="rule" src="{@docRoot}assets/images/grad-rule-qv.png">
+ <div id="qv-sub-rule">
+ <img src="{@docRoot}assets/images/icon_market.jpg" style="float:left;margin:0;padding:0;">
+ <p style="color:#669999;">Publishing to Small Screen Devices</p>
<p>To ensure the best experience for users on small-screen devices, Android
Market only shows applications that explicitly declare support for small
screens. If you developed an application on Android 1.5 or earlier and published
it on Android Market, you need to <a href="#testing">test your application</a>
-on small screens and then upload an updated version that explicitly
+on small screens and then upload an updated version that explicitly
<a href="#attrs">indicates support for small screens</a>. </p>
- </div>
+ </div>
</div>
<li><em>Compatibility-mode display on larger screen-sizes</em>
@@ -374,7 +405,7 @@ of scaling the application, however, the application's 320x480 interface will be
placed as a "postage stamp" in the larger 480x800 screen.</p>
<p>For more information, see the <code>android:anyDensity</code> attribute in
-<a href="#attrs">Manifest elements for screens support</a> and the
+<a href="#attrs">Manifest elements for screens support</a> and the
<a href="#compatibility-examples">Screen-Compatibility Examples</a>
section.</p></li>
</ol>
@@ -415,7 +446,7 @@ does this in three ways: </p>
<ul>
<li>Through pre-scaling of drawable resources (scaled at resource loading
time)</li>
-<li>Through auto-scaling of density-independent pixel (dip) values used in
+<li>Through auto-scaling of density-independent pixel (dp) values used in
layouts</li>
<li>Through auto-scaling of absolute pixel values used in the application (only
needed if the application has set <code>android:anyDensity="false"</code> in its
@@ -437,25 +468,36 @@ density (left), HVGA medium density (center), and QVGA low density (right). </p>
<p>In most cases, you can take advantage of density independence in your
application simply by making sure that your layouts specify all dimension values
-in density-independent pixels (<code>dip</code> or <code>dp</code>) or
+in density-independent pixels (<code>dp</code> or <code>dp</code>) or
scale-independent pixels (<code>sip</code> or <code>sp</code>, for text only).
If you are using absolute pixel values in the application and manifest includes
<a href="#attrs"><code>android:anyDensity="true"</code></a>, you will also need
-to scale the pixel values. See <a href="#dips-pels">Converting from dips to
-pixels</a> for more information. </p>
+to scale the pixel values. See <a href="#dips-pels">Converting dp units to
+pixel units</a> for more information. </p>
<h3 id="attrs">Manifest attributes for screens support</h3>
-<p> Android 1.6 introduced a new manifest element,
+<p> Android 1.6 introduced a new manifest element,
<a href="{@docRoot}guide/topics/manifest/supports-screens-element.html"><code>&lt;supports-screens&gt;</code></a>,
whose attributes you can use to control the
display of your application on different classes of device screens, as listed
-below. The <code>smallScreens</code>, <code>normalScreens</code>, and
-<code>largeScreens</code> attributes correspond to the generalized screen sizes
+in table 2. The <code>smallScreens</code>, <code>normalScreens</code>, <code>largeScreens</code> and
+<code>xlargeScreens</code> attributes correspond to the generalized screen sizes
described in <a href="#range">Range of screens supported</a>, earlier in this
-document.</p>
-
+document. Notice that the default values for each attribute vary, depending
+on your minimum and targeted platform, as indicated in the <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">{@code
+android:minSdkVersion}</a> and <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">{@code
+android:targetSdkVersion}</a> attributes of your <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">{@code &lt;uses-sdk&gt;}</a>
+manifest element.</p>
+
+<p class="table-caption" id="table2"><strong>Table 2.</strong> Summary of attributes for the <a
+href="{@docRoot}guide/topics/manifest/supports-screens-element.html">{@code
+&lt;supports-screens&gt;}</a> manifest element, including default values based on platform
+version.</p>
<table id="vrr8">
<tr>
<th>
@@ -465,10 +507,12 @@ document.</p>
Description
</th>
<th>
- Default value,<br><nobr>Android 1.5 and Lower</nobr>
+ Default value, when<br><nobr><code>minSdkVersion</code> or</nobr>
+<code>targetSdkVersion</code> is 4 or lower
</th>
<th>
- Default value,<br><nobr>Android 1.6 and Higher</nobr>
+ Default value, when<br><nobr><code>minSdkVersion</code> or</nobr>
+<code>targetSdkVersion</code> is 5 or higher
</th>
</tr>
<tr>
@@ -540,11 +584,46 @@ baseline screen.</p>
<td>"<code>false</code>"</td>
<td>"<code>true</code>"</td>
</tr>
+ <tr>
+ <td colspan="4"><strong>Note:</strong> Android 2.3 (API Level 9) introduced a new
+attribute for the <code>&lt;supports-screens&gt;</code> element: <code>xlargeScreens</code>, shown
+below. It works the same as the other screen attributes above, but, if neither your
+<code>minSdkVersion</code> or <code>targetSdkVersion</code> are set to "9", the default value is
+"false" when your application is installed on a device running Android 2.3.</td>
+ </tr>
+ <tr>
+ <th>
+ Attribute
+ </th>
+ <th >
+ Description
+ </th>
+ <th>
+ Default value, when<br><nobr><code>minSdkVersion</code> or</nobr>
+<code>targetSdkVersion</code> is 8 or lower
+ </th>
+ <th>
+ Default value, when<br><nobr><code>minSdkVersion</code> or</nobr>
+<code>targetSdkVersion</code> is 9 or higher
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <code>android:xlargeScreens</code>
+ </td>
+ <td>
+ Whether or not the application UI is designed for use on
+<em>xlarge</em> screens &mdash; "<code>true</code>" if it is, and
+"<code>false</code>" if not.
+ </td>
+<td>"<code>false</code>"</td>
+<td>"<code>true</code>"</td>
+ </tr>
</table>
<p>In general, when you declare a screen-size attribute
-(<code>smallScreens</code>, <code>normalScreens</code>, or
-<code>largeScreens</code>) as "<code>true</code>", you are signaling to the
+(<code>smallScreens</code>, <code>normalScreens</code>, <code>largeScreens</code>, or
+<code>xlargeScreens</code>) as "<code>true</code>", you are signaling to the
platform that your application is designed to render properly on that screen
size. As a result, the platform does not apply any size-compatibility features
(such as a virtual HVGA display area). If you declare a screen-size attribute as
@@ -577,16 +656,20 @@ features for applications.</p>
<ul>
<li>Assume that you declare <code>smallScreens="false" normalScreens="true"
-largeScreens="false" </code> in your application's manifest. <p>Although the
-application is not designed for display on large screens, the platform can still
-run it successfully in <a href="#compatibility-examples">size-compatibility
-mode</a>. Android Market does not filter the application from devices
-<em>normal</em> and <em>large</em> size screens, but does filter it from
-<em>small</em> size screens, since the application provides no screen support at
-<em>small</em> size (and there is no smaller size).</p></li>
+largeScreens="false" xlargeScreens="false"</code> in your application's manifest. <p>Although the
+application is not designed for display on large or extra large screens, the platform can still
+run it successfully in <a href="#compatibility-examples">screen-compatibility
+mode</a>. Android Market shows the application to devices with
+<em>normal</em>, <em>large</em>, and <em>xlarge</em> size screens, but does filter it from
+<em>small</em> size screens, because the application provides no screen support at
+<em>small</em> size. Android's <a href="#compatibility-examples">screen-compatibility
+mode</a> mode does not provide support for screens that are smaller than those the
+application supports&mdash;it only provides support for screens that are larger. Thus,
+although the application declares "false" for <em>large</em> and <em>xlarge</em> screens,
+the application still functions, but runs in compatibility mode.</p></li>
<li>Assume that you declare <code>smallScreens="false" normalScreens="false"
-largeScreens="true"</code> in your application's manifest. <p>Android Market
+largeScreens="true" xlargeScreens="true"</code> in your application's manifest. <p>Android Market
filters the application from users of devices with <em>small</em> and
<em>normal</em> size screens. In effect, this prevents such users from
installing the application.</p></li>
@@ -599,23 +682,24 @@ application must ensure that it declares its UI dimensions using
density-independent pixels (<code>dp</code>) and scales any absolute pixel
values (<code>px</code>) or math by the scaling factor available from {@link
android.util.DisplayMetrics#density android.util.DisplayMetrics.density}. See <a
-href="#dips-pels">Converting from dips to pixels</a> for an example.</p>
+href="#dips-pels">Converting dp units to pixel units</a> for an example.</p>
<p>Note that the setting of the <code>android:anyDensity</code> attribute does
not affect the platform's pre-scaling of drawable resources, such as bitmaps and
nine-patch images, which always takes place by default. </p>
-<p>The following example shows a manifest that declares support for large,
-normal, and small screens in any densities.</p>
-
-<pre>&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"&gt;
- ...
- &lt;supports-screens
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; android:largeScreens="true"
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; android:normalScreens="true"
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; android:smallScreens="true"
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; android:anyDensity="true" /&gt;
- ...
+<p>The following example shows a manifest that declares support for small, normal, large, and
+ xlarge screens in any density.</p>
+
+<pre>
+&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"&gt;
+ ...
+ &lt;supports-screens
+ android:smallScreens="true"
+ android:normalScreens="true"
+ android:largeScreens="true"
+ android:xlargeScreens="true"
+ android:anyDensity="true" /&gt;
&lt;/manifest&gt;
</pre>
<!-- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; android:resizeable="true" -->
@@ -624,36 +708,25 @@ normal, and small screens in any densities.</p>
</h4>
<p>The default values for the <code>&lt;supports-screens&gt;</code> attributes
-differ, depending on the the value of the
+differ, depending on the the value of the
<a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html"><code>android:minSdkVersion</code></a>
attribute in the application's manifest, as well as on
-the value of <code>android:targetSdkVersion</code>, if declared:</p>
+the value of <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">{@code
+android:targetSdkVersion}</a>, if declared.</p>
-<div>
- <ul>
- <li>
- If <code>android:minSdkVersion</code> or
-<code>android:targetSdkVersion</code> is "4" (Android 1.6) or higher, the
-default value for everything is "<code>true</code>". If your application uses
-APIs introduced in Android 1.6 or higher, but does not support specific screen
-densities and/or screen sizes, you need to explicitly set the appropriate
-attributes to "<code>false</code>".
- </li>
- <li>
- If <code>android:minSdkVersion</code> is declared with a value of "3"
-(Android 1.5) or lower <em>and</em> a <code>android:targetSdkVersion</code>
-attribute is <em>not</em> declared with a value of "4" or higher, the default
-value for all attributes except <code>android:normalScreens</code> is
-"<code>false</code>". If you are primarily targeting pre-Android 1.6 platforms
-but also want to support other densities/screen sizes, you need to explicitly
-set the appropriate attributes to "<code>true</code>".
- </li>
- <li>
- Note that <code>android:normalScreens</code> always defaults to
-<code>true</code>.
- </li>
- </ul>
-</div>
+<p>Above, <a href="#table2">table 2</a> indicates the default values for each attribute, based on
+the values you provide for the <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">{@code
+android:minSdkVersion}</a> and <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">{@code
+android:targetSdkVersion}</a>, in the <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">{@code &lt;uses-sdk&gt;}</a>
+element.</p>
+
+<p class="note"><strong>Note:</strong> If your application uses APIs introduced in Android 1.6 or
+higher, but does not support specific screen densities and/or screen sizes, you need to explicitly
+set the appropriate attributes to "<code>false</code>" (because most are "true", by default).</p>
<h3 id="qualifiers">Resource directory qualifiers for screen size and density</h3>
@@ -673,7 +746,7 @@ of Screens Supported</a>, earlier in this document.</p>
</tr>
<tr>
- <td rowspan="3">Size</td>
+ <td rowspan="4">Size</td>
<td><code>small</code></td>
<td>Resources designed for <em>small</em> size screens.</td>
</tr>
@@ -683,11 +756,15 @@ of Screens Supported</a>, earlier in this document.</p>
</tr>
<tr>
<td><code>large</code></td>
-<td>Resources for <em>large</em> size screens.</td>
+<td>Resources designed for <em>large</em> size screens.</td>
+</tr>
+<tr>
+<td><code>xlarge</code></td>
+<td>Resources designed for <em>extra large</em> size screens.</td>
</tr>
<tr>
-<td rowspan="4">Density</td>
+<td rowspan="5">Density</td>
<td><code>ldpi</code></td>
<td>Resources designed for low-density (<em>ldpi</em>) screens.</td>
</tr>
@@ -700,6 +777,10 @@ of Screens Supported</a>, earlier in this document.</p>
<td>Resources designed for high-density (<em>hdpi</em>) screens.</td>
</tr>
<tr>
+<td><code>xhdpi</code></td>
+<td>Resources designed for extra high-density (<em>xhdpi</em>) screens.</td>
+</tr>
+<tr>
<td><code>nodpi</code></td>
<td>Density-independent resources. The platform does not auto-scale resources
tagged with this qualifier, regardless of the current screen's density.</td>
@@ -732,31 +813,34 @@ running on Android 1.5 (API Level 3). </td>
Note that the density and the screen size are independent parameters and are
interpreted by the system individually. For example, WVGA high density is
considered a normal screen because its physical size is about the same as one of
-T-Mobile G1. On the other hand, a WVGA medium density screen is considered a
+T-Mobile G1. On the other hand, a WVGA medium density screen is considered a
<i>large</i> screen &mdash; it offers the same resolution but at lower pixel
density, meaning that it is both physically larger than the baseline screen and
can display significantly more information than a normal screen size.
</p>
<p>Here is an example of the resource directory structure of an application that
-supports low and high density, and employs different layout schemes.</p>
+employs different layout schemes for different screen sizes and supports low and high density
+screens.</p>
-<pre>res/layout/my_layout.xml // layout for normal screen size
+<pre>
+res/layout/my_layout.xml // layout for normal screen size
res/layout-small/my_layout.xml // layout for small screen size
res/layout-large/my_layout.xml // layout for large screen size
res/layout-large-land/my_layout.xml // layout for large screen size in landscape mode
+res/layout-xlarge/my_layout.xml // layout for extra large screen size
-res/drawable-ldpi/my_icon.png // icon image for low density
-res/drawable-mdpi/dpi/my_icon.png // icon for medium density
-res/drawable-hdpi/my_icon.png // icon image for high density
+res/drawable-lhdpi/my_icon.png // image for low density
+res/drawable-mdpi/dpi/my_icon.png // image for medium density
+res/drawable-hdpi/my_icon.png // image for high density
res/drawable-nodpi/composite.xml // density independent resource
</pre>
<p>For more information about how to use resource qualifiers or how the platform
-selects them, please read
+selects them, please read
<a href="{@docRoot}guide/topics/resources/providing-resources.html#AlternativeResources">
-Alternative Resources</a>.</p>
+Providing Alternative Resources</a>.</p>
<h2 id="screen-independence">Best practices for Screen Independence</h2>
@@ -771,10 +855,11 @@ different screens. Here is a quick checklist:</p>
<ol>
<li>
- Prefer wrap_content, fill_parent and the dip unit to px in XML layout files
+ Use {@code wrap_content}, {@code fill_parent}, or the {@code dp} unit (instead of {@code px}),
+when specifying dimensions in an XML layout file
</li>
<li>
- Avoid AbsoluteLayout
+ Do not use {@code AbsoluteLayout}
</li>
<li>
Do not use hard coded pixel values in your code
@@ -784,19 +869,19 @@ different screens. Here is a quick checklist:</p>
</li>
</ol>
-<h3 id="use-relative">1. Prefer wrap_content, fill_parent and the dip unit to
+<h3 id="use-relative">1. Use wrap_content, fill_parent, or the dp unit, instead of
absolute pixels<br> </h3>
<p>When defining the <code>layout_width</code> and <code>layout_height</code> of
views in an XML layout file, using <code>wrap_content</code>,
-<code>fill_parent</code> or the <code>dip</code> will guarantee that the view is
+<code>fill_parent</code> or the <code>dp</code> will guarantee that the view is
given an appropriate size on the current device screen. For instance, a view
-with a <code>layout_width="100dip"</code> will measure 100 pixels wide on an
+with a <code>layout_width="100dp"</code> will measure 100 pixels wide on an
HVGA@160 density display and 150 pixels on a WVGA@240 density display, but the
view will occupy approximately the same physical space. </p>
<p>Similarly, you should prefer the <code>sp</code> (scale-independent pixel,
-the scale factor depends on a user setting) or <code>dip</code> (if you don't
+the scale factor depends on a user setting) or <code>dp</code> (if you don't
want to allow the user to scale the text) to define font sizes.</p>
<h3 id="avoid-absolute">2. Avoid AbsoluteLayout </h3>
@@ -808,7 +893,7 @@ positions which might easily lead to user interfaces that do not work well on
different displays. Because of this, <code>AbsoluteLayout</code> was deprecated
in Android 1.5 (API Level 3). </p>
-<p>You can achieve much the same layout by using a
+<p>You can achieve much the same layout by using a
{@link android.widget.FrameLayout FrameLayout} instead, and setting
<code>layout_margin</code> attributes of the children. This approach is more
flexible and will yield better results on different screens.</p>
@@ -822,9 +907,9 @@ code in pixels. For instance, if <code>myView.getWidth()</code> returns 10, the
view is 10 pixels wide. In some cases, you may need to scale the pixel values
that you use in your code. The sections below provide more information. </p>
-<h4 id="dips-pels">Converting from dips to pixels</h4>
+<h4 id="dips-pels">Converting dp units to pixel units</h4>
-<p>In some cases, you will need to express dimensions in <code>dip</code> and
+<p>In some cases, you will need to express dimensions in <code>dp</code> and
then convert them to pixels. Imagine an application in which a scroll gesture is
recognized after the user's finger has moved by at least 16 pixels. On a
baseline screen, the user will have to move his finger by 16 pixels / 160
@@ -832,26 +917,26 @@ dpi = 1/10th of an inch (or 2.5 mm) before the gesture is recognized. On a
device with a high (240) density display, the user will move his finger by only
16 pixels / 240 dpi = 1/15th of an inch (or 1.7 mm.) The distance is much
shorter and the application thus appears more sensitive to the user. To fix this
-issue, the gesture threshold must be expressed in the code in <code>dip</code>
+issue, the gesture threshold must be expressed in the code in <code>dp</code>
and then converted to actual pixels.</p>
-<pre>// The gesture threshold expressed in dip
-private static final float GESTURE_THRESHOLD_DIP = 16.0f;
+<pre>// The gesture threshold expressed in dp
+private static final float GESTURE_THRESHOLD_DP = 16.0f;
-// Convert the dips to pixels
+// Convert the dps to pixels
final float scale = getContext().getResources().getDisplayMetrics().density;
-mGestureThreshold = (int) (GESTURE_THRESHOLD_DIP * scale + 0.5f);</span>
+mGestureThreshold = (int) (GESTURE_THRESHOLD_DP * scale + 0.5f);</span>
// Use mGestureThreshold as a distance in pixels
</pre>
-<p>The {@link android.util.DisplayMetrics#density android.util.DisplayMetrics.density}
+<p>The {@link android.util.DisplayMetrics#density android.util.DisplayMetrics.density}
field specifies the the scale factor you must use to
-convert dips to pixels according to the current screen density. You can access
+convert dps to pixels according to the current screen density. You can access
the current screen's metrics through a <code>Context</code> or
<code>Activity</code>. On a medium (160) density screen,
<code>DisplayMetrics.density</code> equals "1.0", whereas on a high (240)
-density screen it equals "1.5". You can refer to the documentation of the
+density screen it equals "1.5". You can refer to the documentation of the
{@link android.util.DisplayMetrics DisplayMetrics}
class for details.</p>
@@ -901,7 +986,7 @@ platform assumes that the resources in that directory are designed for the
baseline medium density. It is not recommended that you put density-specific
resources such as images in the default directory.</p>
-<p>For more information about valid resource qualifiers, see
+<p>For more information about valid resource qualifiers, see
<a href="#qualifiers">Resource directory qualifiers</a>, earlier in this
document.</p>
@@ -945,7 +1030,7 @@ resource directory:</p>
<p style="margin-left:2em;"><code>res/drawable-nodpi/icon.png</code></p>
-<p>You can also take complete control of the scaling mechanism by using the
+<p>You can also take complete control of the scaling mechanism by using the
{@link android.graphics.BitmapFactory.Options BitmapFactory.Options} class,
which lets you define whether you want the bitmap to be pre-scaled and what the
density of the bitmap should be. For instance, if you are loading a bitmap from
@@ -953,12 +1038,12 @@ a web server, you may want to force the bitmap's density to be high density.
When pre-scaling is disabled, the resulting bitmap is in auto-scaling mode. The
bitmap is associated with a density (that you may or may not have specified
through the <code>BitmapFactory.Options</code>) which will be used to scale the
-bitmap on screen <em>at drawing time</em>.
+bitmap on screen <em>at drawing time</em>.
<p>Using auto-scaling instead of pre-scaling is more CPU expensive than
-pre-scaling but uses less memory. You can refer to the documentation of
-{@link android.graphics.BitmapFactory BitmapFactory},
-{@link android.graphics.Bitmap Bitmap}, and
+pre-scaling but uses less memory. You can refer to the documentation of
+{@link android.graphics.BitmapFactory BitmapFactory},
+{@link android.graphics.Bitmap Bitmap}, and
{@link android.graphics.Canvas Canvas} for more
information on auto-scaling.</p>
@@ -973,7 +1058,7 @@ auto-scaled at draw time.</p>
<p>If you have already developed and published an Android application based on
Android 1.5 or earlier platform version, you need to consider how you will adapt
-your application so that it is deployable to </p>
+your application so that it is deployable to:</p>
<ul>
<li>Existing devices, which may be running Android 1.5 (or lower) platform
@@ -982,16 +1067,21 @@ version, as well as to </li>
screen sizes and resolutions</li>
</ul>
+<p class="note"><strong>Note:</strong> Even if your application targets Android 1.6 already, you
+should follow the same strategies below in order to support <em>xhdpi</em> and <em>xlarge</em>
+screens on Android 2.3 (API Level 9), while maintaining compatibility with older versions of
+the platform.</p>
+
<p>To support the newer devices and the different screens they use, you might
need to make some changes in your app, but at the same time your app may be very
stable and so you want to minimize the changes. There are a variety of ways that
you can extend your existing application to support new devices with multiple
screens <em>and</em> existing devices running older platform versions. You
should be able to make these changes to your application such that you can
-distribute a single .apk to any and all devices.</p>
+distribute a single {@code .apk} to all devices.</p>
<p>The recommended strategy is to develop against the most recent version of the
-platform you are targeting, and test on the minimum one you want to run on.
+platform you are targeting, and test on the minimum platform version you want to run on.
Here's how to do that:</p>
<ol>
@@ -999,39 +1089,41 @@ Here's how to do that:</p>
<code>android:minSdkVersion</code> attribute as it is. You <em>do not</em> need
to increment the value of the attribute to support new devices and multiple
screens. </li>
- <li>Extend compatibility for Android 1.6 (and higher) devices by adding
+ <li>Extend compatibility for Android 1.6 (and higher) devices by adding
a new attribute &mdash; <code>android:targetSdkVersion</code> &mdash; to the
<code>uses-sdk</code> element. Set the value of the attribute to
-"<code>4</code>". This allows your application to "inherit" the platform's
+<code>"4"</code>. [To support <em>xhdpi</em> and <em>xlarge</em> screens, set the value to
+<code>"9"</code>.] This allows your application to "inherit" the platform's
multiple screens support, even though it is technically using an earlier version
of the API. </li>
<li>Add an empty <code>&lt;supports-screens&gt;</code> element as a child of
<code>&lt;manifest&gt;</code>. If you need to enable size or density attributes
later, this is where you will add them.</li>
<li>Change your application's build properties, such that it compiles against
-the Android 1.6 (API Level 4) library, rather than against the Android 1.5 (or
+the Android 1.6 (API Level 4) library [or against Android 2.3 (API Level 9) to support
+<em>xhdpi</em> and <em>xlarge</em> screens], rather than against the Android 1.5 (or
earlier) library. You will not be able to compile your application against the
older platform because of the new manifest attribute. </li>
- <li>Set up AVDs for testing your application on Android 1.6 and higher
+ <li>Set up AVDs for testing your application on Android 1.6 [or Android 2.3] and higher
releases. Create AVDs that use the screen sizes and densities that you want to
-support. When you create the AVDs, make sure to select the Android 1.6 or higher
+support. When you create the AVDs, make sure to select the Android 1.6 [or Android 2.3] or higher
platform as the system image to run. For more information, see <a
href="#testing">How to Test Your Application on Multiple Screens</a>,
below.</li>
- <li>Set up AVDs for testing your application on Android 1.5 (or earlier
-platform). You need AVDs running the older platforms you are targeting, so that
+ <li>Set up AVDs for testing your application on older versions of the platform, as low as the
+version declared by your <code>android:minSdkVersion</code>. You need AVDs running the older
+platforms you are targeting, so that
you can test for compatibility and ensure that there are no functional
regressions. </li>
- <li>Compile your application against the Android 1.6 library and run it on the
+ <li>Compile your application against the Android 1.6 [or Android 2.3] library and run it on the
AVDs you created. Observe the way your application looks and runs, and test all
of the user interactions. </li>
<li>Debug any display or functional issues. For issues that you resolve in
your application code, <span style="color:red">make certain not to use any APIs
-introduced in API Level 4 or later</span>. If you are in doubt, refer to SDK
-reference documentation and look for the API Level specifier for the API you
-want to use. Using an API introduced in API Level 4 or later will mean that your
-application will no longer be compatible with devices running Android 1.5 or
-earlier.</li>
+introduced later than the version declared by your <code>android:minSdkVersion</code></span>. If you
+are in doubt, refer to SDK reference documentation and look for the API Level specifier for the API
+you want to use. Using newer APIs not supported by your minimum version will mean that your
+application will no longer be compatible with devices running on that version.</li>
<li>For resource-related issues, you can try resolving them by:
<ul>
<li>Adding a <code>anyDensity="false"</code> attribute to
@@ -1039,22 +1131,22 @@ earlier.</li>
scaling.</li>
<li>Creating any size- or density-specific resources you need and placing
them in directories tagged with the <a href="#qualifiers">correct
-qualifiers</a>. Qualifiers must be arranged in a proscribed order. See
+qualifiers</a>. Qualifiers must be arranged in a proscribed order. See
<a href="{@docRoot}guide/topics/resources/providing-resources.html#AlternativeResources">
-Alternative Resources</a> for more information. </li>
+Providing Alternative Resources</a> for more information. </li>
<li>Note that if you add size- or density-specific resource directories
tagged with any of the resource qualifiers listed in this document, you should
make sure to also tag those directories with the <code>v&lt;api-level&gt;</code>
-qualifier (for example, <code>-v4</code>). This ensures that those resources
+qualifier (for example, <code>-v4</code> to target API Level 4). This ensures that those resources
will be ignored when the application is run on Android 1.5 or lower platform
versions.</p></li>
</ul>
</li>
<li>If your application does not offer support (such as custom layouts) for
large screens and you want the platform to display your application in
-screen-compatibility mode on larger screens, add a
-<code>largeScreens="false"</code> attribute to the
-<code>&lt;supports-screens&gt;</code> element in the manifest. See
+screen-compatibility mode on larger screens, add the
+<code>largeScreens="false"</code> and <code>xlargeScreens="false"</code> attributes to the
+<code>&lt;supports-screens&gt;</code> element in the manifest. See
<a href="#compatibility-examples">Screen-Compatibility Examples</a> for
illustrations of how the platform displays your application in this case.</li>
<li>If your application does not offer support (such as custom layouts) for
@@ -1077,6 +1169,16 @@ function on a small-screen device. In many cases, the reduced screen area and
density mean that you may need to make tradeoffs in design, content, and
function on those devices. </p>
+<p>Also give extra attention to testing your application on an AVD that emulates an <em>xlarge</em>
+screen. Devices with extra large screens
+are tablet-sized or larger, so you should pay close attention to how usable your application is on
+such screens. You might want to design new layouts specifically for extra large screens, to address
+usability aspects such as the location and size of buttons in your UI. To test your application on
+an extra large screen, create an AVD targeted to Android 2.3 with a high resolution, such as 1280 x
+800, and the default density of 160dpi. This AVD will use any resources you've provided with the
+<code>xlarge</code> <a href="#qualifiers">resouce qualifier</a>.</p>
+
+
<h2 id="testing">How to Test Your Application on Multiple Screens</h2>
<p>Before publishing an application that supports multiple screens, you should
@@ -1091,22 +1193,22 @@ 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. -->
-<div id="f9.5" style="float:right;margin:0;padding:0;">
- <img src="{@docRoot}images/screens_support/avds-config.png" style="padding:0;margin:0;">
- <p class="caption" style="margin:0 0 1.5em 1em;padding:0 0 0 1em;"><strong>Figure 4.</strong>
+<div id="f9.5" class="figure" style="width:530px">
+ <img src="{@docRoot}images/screens_support/avds-config.png" />
+ <p class="img-caption"><strong>Figure 4.</strong>
A typical set of AVDs for testing screens support.</p>
</div>
<p>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 six emulator skins to get you started. You can use the Android AVD
+includes several emulator skins to get you started. You can use the Android AVD
Manager or the <code>android</code> 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
+the defaults. For general information about working with AVDs, see
<a href="{@docRoot}guide/developing/tools/avd.html">Android Virtual
Devices</a>.</p>
-<p>The Android SDK provides a set of default emulator skins that you can use for
+<p>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:</p>
@@ -1125,7 +1227,7 @@ install in your SDK. The Android 1.6 platform offers these default skins:</p>
</li>
</ul>
-<p>The Android 2.0 platform offers all of the Android 1.6 default skins,
+<p>The Android 2.0 platform offers all of the Android 1.6 default skins,
above, plus:</p>
<ul>
@@ -1161,15 +1263,15 @@ scale the entire emulator display, based on both the dpi of the skin and of your
monitor. The default emulator skins included in the Android SDK are listed
in <a href="#screens-table">Table 1</a>, earlier in this document.</p>
-<div style="float: right;background-color:#fff;margin: 0;padding: 20px 0 20px 20px;width:520px;">
- <img src="{@docRoot}images/screens_support/avd-density.png" style="padding:0;margin:0;">
- <p class="caption" style="margin:0 0 1.5em 1em;padding:0 0 0 1em; width:280px;"><strong>Figure 5.</strong>
+<div class="figure" style="width:324px">
+ <img src="{@docRoot}images/screens_support/avd-density.png" >
+ <p class="img-caption"><strong>Figure 5.</strong>
Resolution and density options that you can use, when creating an AVD using the AVD Manager.</p>
</div>
<p>You should also make sure to test your application on different physical
-screen sizes within a single size-density configuration. For example, to
-display this screen configuration on a 30" monitor you will need to adjust
+screen sizes within a single size-density configuration. For example, to
+display this screen configuration on a 30" monitor you will need to adjust
the value passed to <code>-scale</code> to 96*2.8/3.3 = 81dpi. You can also
pass a float value to <code>-scale</code> to specify your own scaling factor:</p>
@@ -1201,7 +1303,7 @@ or "240" for a high-density screen.</li>
<li>Set any other hardware options and complete the AVD creation.</li>
</ol>
-<p>In the example above (WVGA medium density), the new AVD will emulate a 5.8"
+<p>In the example above (WVGA medium density), the new AVD will emulate a 5.8"
WVGA screen.</p>
<p>As an alternative to adjusting the emulator skin configuration, you can use
@@ -1216,21 +1318,21 @@ to the emulator command line when starting the AVD. For example, </p>
<p>This section provides examples of how the Android platform displays an
application written for the baseline screen configuration &mdash; HVGA (320x480)
resolution on a 3.2" screen &mdash; with all of the platform's size- and
-density-compatibility features enabled. That is, the examples show how
-the platform displays an application that doesn't provide built-in support
+density-compatibility features enabled. That is, the examples show how
+the platform displays an application that doesn't provide built-in support
for the screen on which it is being rendered, but which instead relies completely
on the platform.</p>
-<p>The platform's screen-compatibility features are designed to provide such
-an application with a virtual baseline screen environment against which to run,
-while at the same time ensuring for the user a physical display that is
+<p>The platform's screen-compatibility features are designed to provide such
+an application with a virtual baseline screen environment against which to run,
+while at the same time ensuring for the user a physical display that is
approximately the same as the baseline screen size and density. </p>
<p>Legacy applications that have not been modified to support multiple
-screens would be typical examples of such applications. In most cases,
+screens would be typical examples of such applications. In most cases,
you would want to add multiple-screens support to a legacy application and
publish an updated version, as described in <a href="#strategies">Strategies
-for Legacy Applications</a>. However, if you did not do so, the
+for Legacy Applications</a>. However, if you did not do so, the
platform still performs best-effort rendering of your application, as
illustrated below.</p>
@@ -1248,9 +1350,9 @@ density is low density (160 -&gt; 120 virtual dpi).
</li>
<li>
If the device's screen size is <em>small</em>, there are few options
-options for making Android 1.5 applications work well on such a screen, so
+options for making Android 1.5 applications work well on such a screen, so
Android Market will filter applications that are not known to support these
-screens from the device.
+screens from the device.
</li>
<li>
If the device's screen size is <em>large</em>, it limits the application's
diff --git a/docs/html/guide/topics/resources/providing-resources.jd b/docs/html/guide/topics/resources/providing-resources.jd
index d868599..4f3b0da 100644
--- a/docs/html/guide/topics/resources/providing-resources.jd
+++ b/docs/html/guide/topics/resources/providing-resources.jd
@@ -329,7 +329,8 @@ indicates the current locale.</p>
<td>
<code>small</code><br/>
<code>normal</code><br/>
- <code>large</code>
+ <code>large</code><br/>
+ <code>xlarge</code>
</td>
<td>
<ul class="nolist">
@@ -347,6 +348,10 @@ indicates the current locale.</p>
medium-density VGA screen. Such a screen has significantly more
available space in both width and height than an HVGA display.
Examples are VGA and WVGA medium density screens.</li>
+ <li>{@code xlarge}: Screens that are considerably larger than the traditional
+ medium-density HVGA screen. In most cases, devices with extra large screens would be too
+large to carry in a pocket and would most likely be tablet-style devices. <em>Added in API Level
+9.</em></li>
</ul>
<p><em>Added in API Level 4.</em></p>
<p>See <a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple
@@ -437,6 +442,7 @@ application during runtime.</p>
<code>ldpi</code><br/>
<code>mdpi</code><br/>
<code>hdpi</code><br/>
+ <code>xhdpi</code><br/>
<code>nodpi</code>
</td>
<td>
@@ -445,6 +451,8 @@ application during runtime.</p>
<li>{@code mdpi}: Medium-density (on traditional HVGA) screens; approximately
160dpi.</li>
<li>{@code hdpi}: High-density screens; approximately 240dpi.</li>
+ <li>{@code xhdpi}: Extra high-density screens; approximately 320dpi. <em>Added in API
+Level 8</em></li>
<li>{@code nodpi}: This can be used for bitmap resources that you do not want to be scaled
to match the device density.</li>
</ul>
diff --git a/docs/html/images/axis_globe_inverted.png b/docs/html/images/axis_globe_inverted.png
new file mode 100644
index 0000000..bd78c7f
--- /dev/null
+++ b/docs/html/images/axis_globe_inverted.png
Binary files differ
diff --git a/docs/html/images/screens_support/screens-ranges.png b/docs/html/images/screens_support/screens-ranges.png
index 034ac34..dce6264 100644
--- a/docs/html/images/screens_support/screens-ranges.png
+++ b/docs/html/images/screens_support/screens-ranges.png
Binary files differ
diff --git a/docs/html/sdk/adt_download.jd b/docs/html/sdk/adt_download.jd
index 3da576a..33e480a 100644
--- a/docs/html/sdk/adt_download.jd
+++ b/docs/html/sdk/adt_download.jd
@@ -22,6 +22,13 @@ ADT Installation</a>.</p>
<th>Notes</th>
</tr>
<tr>
+ <td>8.0.0</td>
+ <td><a href="http://dl-ssl.google.com/android/ADT-8.0.0.zip">ADT-8.0.0.zip</a></td>
+ <td><nobr> bytes</nobr></td>
+ <td></td>
+ <td>Requires SDK Tools, Revision 8 <em><nobr>November 2010</nobr></em></td>
+ </tr>
+ <tr>
<td>0.9.9</td>
<td><a href="http://dl-ssl.google.com/android/ADT-0.9.9.zip">ADT-0.9.9.zip</a></td>
<td><nobr>8301681 bytes</nobr></td>
diff --git a/docs/html/sdk/eclipse-adt.jd b/docs/html/sdk/eclipse-adt.jd
index c3afebd..8f6f518 100644
--- a/docs/html/sdk/eclipse-adt.jd
+++ b/docs/html/sdk/eclipse-adt.jd
@@ -99,14 +99,14 @@ padding: .25em 1em;
<div class="toggleable opened">
<a href="#" onclick="return toggleDiv(this)">
<img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px" width="9px" />
-ADT 8.0</a> <em>(November 2010)</em>
+ADT 8.0.0</a> <em>(December 2010)</em>
<div class="toggleme">
<dl>
<dt>Dependencies:</dt>
-<p><p>ADT 8.0 is designed for use with SDK Tools r8. If you haven't
+<p><p>ADT 8.0.0 is designed for use with SDK Tools r8. If you haven't
already installed SDK Tools r8 into your SDK, use the Android SDK and AVD Manager to do
so.</p></dd>
diff --git a/docs/html/sdk/sdk_toc.cs b/docs/html/sdk/sdk_toc.cs
index 7ccb7a0..057d9e0 100644
--- a/docs/html/sdk/sdk_toc.cs
+++ b/docs/html/sdk/sdk_toc.cs
@@ -75,7 +75,7 @@
</li>
</ul>
<ul>
- <li><a href="<?cs var:toroot ?>sdk/tools-notes.html">SDK Tools, r7</a></li>
+ <li><a href="<?cs var:toroot ?>sdk/tools-notes.html">SDK Tools, r8</a> <span class="new">new!</span></li>
<li><a href="<?cs var:toroot ?>sdk/win-usb.html">USB Driver for
Windows, r3</a>
</li>
diff --git a/docs/html/sdk/tools-notes.jd b/docs/html/sdk/tools-notes.jd
index 0f075e5..9316fae 100644
--- a/docs/html/sdk/tools-notes.jd
+++ b/docs/html/sdk/tools-notes.jd
@@ -64,6 +64,70 @@ padding: .25em 1em;
<div class="toggleable opened">
<a href="#" onclick="return toggleDiv(this)">
<img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px" width="9px" />
+SDK Tools, Revision 8</a> <em>(December 2010)</em>
+ <div class="toggleme">
+
+<dl>
+<dt>Dependencies:</dt>
+<dd>
+<p>If you are developing in Eclipse with ADT, note that SDK Tools r8 is
+designed for use with ADT 8.0.0 and later. After installing SDK Tools r8, we
+highly recommend updating your ADT Plugin to 8.0.0.</p>
+
+<p>Also note that SDK Tools r8 requires a new SDK component called
+<em>Platform-tools</em>. The new Platform-tools component lets all SDK platforms
+(Android 2.1, Android 2.2, and so on) use the same (latest) version of build
+tools such as <code>adb</code>, <code>aapt</code>, <code>aidl</code>, and
+<code>dx</code>. To download the Platform-tools component, use the Android SDK
+Manager, as described in <a href="adding-components.html">Adding SDK
+Components</a></p>
+
+<dt>Upgrading from SDK Tools r7:</dt>
+<dd>
+<p>If you are upgrading to SDK Tools r8 from an earlier version, note that the
+the default installed location for the <code>adb</code> tool has changed from
+<code>&lt;<em>SDK</em>&gt;/tools/adb</code> to
+<code>&lt;<em>SDK</em>&gt;/platform-tools/adb</code>. This means that you should
+add the new location to your PATH and modify any custom build scripts to
+reference the new location. Copying the <code>adb</code> executable from the new
+location to the old is not recommended, since subsequent updates to the SDK
+Tools will delete the file.</p>
+</dd>
+
+<dt>General notes:</dt>
+<dd>
+<ul>
+<li>All SDK platforms now support Library Projects.</li>
+<li>Support for a true debug build. Developers no longer need to add the
+<code>android:debuggable</code> attribute to the
+<code>&lt;application&gt;</code> tag in the manifest &mdash; the build tools add
+the attribute automatically. In Eclipse/ADT, all incremental builds are assumed
+to be debug builds, so the tools insert <code>android:debuggable="true"</code>.
+When exporting a signed release build, the tools do not add the attribute. In
+Ant, a <code>ant debug</code> command automatically inserts the
+<code>android:debuggable="true"</code> attribute, while <code>ant release</code>
+does not. If <code>android:debuggable="true"</code> is manually set, then
+<code>ant release</code> will actually do a debug build, rather than a release
+build.</li>
+<li>Automatic ProGuard support in release builds. Developers generate a ProGuard
+configuration file using the <code>android</code> tool &mdash; the build tools
+then automatically run ProGuard against the project sources during the build.
+For more information, see the <a
+href="{@docRoot}guide/developing/tools/proguard.html">ProGuard</a>
+documentation. </li>
+<li>New overridable Ant javac properties: <code>java.encoding</code>,
+<code>java.source</code>, and <code>java.target</code> (default values are
+"ascii", "1.5", and "1.5", respectively).</li>
+<li>New UI for the HierarchyViewer tool.</li>
+</ul>
+</dd>
+</dl>
+ </div>
+</div>
+
+<div class="toggleable closed">
+ <a href="#" onclick="return toggleDiv(this)">
+ <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-img" height="9px" width="9px" />
SDK Tools, Revision 7</a> <em>(September 2010)</em>
<div class="toggleme">
diff --git a/include/camera/Camera.h b/include/camera/Camera.h
index 8d8edd6..c7f0b15 100644
--- a/include/camera/Camera.h
+++ b/include/camera/Camera.h
@@ -111,8 +111,8 @@ enum {
};
enum {
- CAMERA_FACING_BACK = 0,
- CAMERA_FACING_FRONT = 1 /* The camera faces to the user */
+ CAMERA_FACING_BACK = 0, /* The facing of the camera is opposite to that of the screen. */
+ CAMERA_FACING_FRONT = 1 /* The facing of the camera is the same as that of the screen. */
};
struct CameraInfo {
@@ -128,10 +128,12 @@ struct CameraInfo {
* camera image needs to be rotated clockwise so it shows correctly on
* the display in its natural orientation. It should be 0, 90, 180, or 270.
*
- * For example, suppose a device has a naturally tall screen, but the camera
- * sensor is mounted in landscape. If the top side of the camera sensor is
- * aligned with the right edge of the display in natural orientation, the
- * value should be 90.
+ * For example, suppose a device has a naturally tall screen. The
+ * back-facing camera sensor is mounted in landscape. You are looking at
+ * the screen. If the top side of the camera sensor is aligned with the
+ * right edge of the screen in natural orientation, the value should be
+ * 90. If the top side of a front-facing camera sensor is aligned with
+ * the right of the screen, the value should be 270.
*/
int orientation;
};
diff --git a/include/camera/CameraHardwareInterface.h b/include/camera/CameraHardwareInterface.h
index 5465441..16f572c 100644
--- a/include/camera/CameraHardwareInterface.h
+++ b/include/camera/CameraHardwareInterface.h
@@ -269,7 +269,9 @@ public:
*/
virtual status_t cancelPicture() = 0;
- /** Set the camera parameters. */
+ /**
+ * Set the camera parameters. This returns BAD_VALUE if any parameter is
+ * invalid or not supported. */
virtual status_t setParameters(const CameraParameters& params) = 0;
/** Return the camera parameters. */
diff --git a/include/camera/CameraParameters.h b/include/camera/CameraParameters.h
index 60031a4..6364d58 100644
--- a/include/camera/CameraParameters.h
+++ b/include/camera/CameraParameters.h
@@ -163,16 +163,23 @@ public:
// the best.
// Example value: "90". Read/write.
static const char KEY_JPEG_QUALITY[];
- // The orientation of the device in degrees. For example, suppose the
- // natural position of the device is landscape. If the user takes a picture
- // in landscape mode in 2048x1536 resolution, the rotation will be set to
- // "0". If the user rotates the phone 90 degrees clockwise, the rotation
- // should be set to "90".
- // The camera driver can set orientation in the EXIF header without rotating
- // the picture. Or the driver can rotate the picture and the EXIF thumbnail.
- // If the Jpeg picture is rotated, the orientation in the EXIF header should
- // be missing or 1 (row #0 is top and column #0 is left side). The driver
- // should not set default value for this parameter.
+ // The rotation angle in degrees relative to the orientation of the camera.
+ // This affects the pictures returned from CAMERA_MSG_COMPRESSED_IMAGE. The
+ // camera driver may set orientation in the EXIF header without rotating the
+ // picture. Or the driver may rotate the picture and the EXIF thumbnail. If
+ // the Jpeg picture is rotated, the orientation in the EXIF header will be
+ // missing or 1 (row #0 is top and column #0 is left side).
+ //
+ // Note that the JPEG pictures of front-facing cameras are not mirrored
+ // as in preview display.
+ //
+ // For example, suppose the natural orientation of the device is portrait.
+ // The device is rotated 270 degrees clockwise, so the device orientation is
+ // 270. Suppose a back-facing camera sensor is mounted in landscape and the
+ // top side of the camera sensor is aligned with the right edge of the
+ // display in natural orientation. So the camera orientation is 90. The
+ // rotation should be set to 0 (270 + 90).
+ //
// Example value: "0" or "90" or "180" or "270". Write only.
static const char KEY_ROTATION[];
// GPS latitude coordinate. GPSLatitude and GPSLatitudeRef will be stored in
diff --git a/include/media/stagefright/AMRWriter.h b/include/media/stagefright/AMRWriter.h
index d8410a9..62d57b4 100644
--- a/include/media/stagefright/AMRWriter.h
+++ b/include/media/stagefright/AMRWriter.h
@@ -44,7 +44,6 @@ protected:
virtual ~AMRWriter();
private:
- FILE *mFile;
int mFd;
status_t mInitCheck;
sp<MediaSource> mSource;
diff --git a/include/media/stagefright/FileSource.h b/include/media/stagefright/FileSource.h
index a7f7181..72a0403 100644
--- a/include/media/stagefright/FileSource.h
+++ b/include/media/stagefright/FileSource.h
@@ -46,7 +46,6 @@ protected:
virtual ~FileSource();
private:
- FILE *mFile;
int mFd;
int64_t mOffset;
int64_t mLength;
diff --git a/include/media/stagefright/MPEG4Writer.h b/include/media/stagefright/MPEG4Writer.h
index e6d8a26..f7618e9 100644
--- a/include/media/stagefright/MPEG4Writer.h
+++ b/include/media/stagefright/MPEG4Writer.h
@@ -61,8 +61,8 @@ protected:
private:
class Track;
- FILE *mFile;
int mFd;
+ status_t mInitCheck;
bool mUse4ByteNalLength;
bool mUse32BitOffset;
bool mIsFileSizeLimitExplicitlyRequested;
@@ -149,7 +149,7 @@ private:
off64_t addSample_l(MediaBuffer *buffer);
off64_t addLengthPrefixedSample_l(MediaBuffer *buffer);
- inline size_t write(const void *ptr, size_t size, size_t nmemb, FILE* stream);
+ inline size_t write(const void *ptr, size_t size, size_t nmemb);
bool exceedsFileSizeLimit();
bool use32BitFileOffset() const;
bool exceedsFileDurationLimit();
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index dadd1db..ec3b5a2 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -864,7 +864,7 @@ status_t StagefrightRecorder::startAMRRecording() {
return UNKNOWN_ERROR;
}
- mWriter = new AMRWriter(dup(mOutputFd));
+ mWriter = new AMRWriter(mOutputFd);
mWriter->addSource(audioEncoder);
if (mMaxFileDurationUs != 0) {
@@ -912,7 +912,7 @@ status_t StagefrightRecorder::startRTPRecording() {
}
}
- mWriter = new ARTPWriter(dup(mOutputFd));
+ mWriter = new ARTPWriter(mOutputFd);
mWriter->addSource(source);
mWriter->setListener(mListener);
@@ -922,7 +922,7 @@ status_t StagefrightRecorder::startRTPRecording() {
status_t StagefrightRecorder::startMPEG2TSRecording() {
CHECK_EQ(mOutputFormat, OUTPUT_FORMAT_MPEG2TS);
- sp<MediaWriter> writer = new MPEG2TSWriter(dup(mOutputFd));
+ sp<MediaWriter> writer = new MPEG2TSWriter(mOutputFd);
if (mAudioSource != AUDIO_SOURCE_LIST_END) {
if (mAudioEncoder != AUDIO_ENCODER_AAC) {
@@ -1204,7 +1204,7 @@ status_t StagefrightRecorder::setupMPEG4Recording(
mediaWriter->clear();
*totalBitRate = 0;
status_t err = OK;
- sp<MediaWriter> writer = new MPEG4Writer(dup(outputFd));
+ sp<MediaWriter> writer = new MPEG4Writer(outputFd);
// Add audio source first if it exists
if (!mCaptureTimeLapse && (mAudioSource != AUDIO_SOURCE_LIST_END)) {
diff --git a/media/libstagefright/AMRWriter.cpp b/media/libstagefright/AMRWriter.cpp
index ecbd96c..0db3d1d 100644
--- a/media/libstagefright/AMRWriter.cpp
+++ b/media/libstagefright/AMRWriter.cpp
@@ -24,22 +24,28 @@
#include <media/mediarecorder.h>
#include <sys/prctl.h>
#include <sys/resource.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
namespace android {
AMRWriter::AMRWriter(const char *filename)
- : mFile(fopen(filename, "wb")),
- mFd(mFile == NULL? -1: fileno(mFile)),
- mInitCheck(mFile != NULL ? OK : NO_INIT),
+ : mFd(-1),
+ mInitCheck(NO_INIT),
mStarted(false),
mPaused(false),
mResumed(false) {
+
+ mFd = open(filename, O_CREAT | O_LARGEFILE | O_TRUNC);
+ if (mFd >= 0) {
+ mInitCheck = OK;
+ }
}
AMRWriter::AMRWriter(int fd)
- : mFile(fdopen(fd, "wb")),
- mFd(mFile == NULL? -1: fileno(mFile)),
- mInitCheck(mFile != NULL ? OK : NO_INIT),
+ : mFd(dup(fd)),
+ mInitCheck(mFd < 0? NO_INIT: OK),
mStarted(false),
mPaused(false),
mResumed(false) {
@@ -50,9 +56,9 @@ AMRWriter::~AMRWriter() {
stop();
}
- if (mFile != NULL) {
- fclose(mFile);
- mFile = NULL;
+ if (mFd != -1) {
+ close(mFd);
+ mFd = -1;
}
}
@@ -92,7 +98,7 @@ status_t AMRWriter::addSource(const sp<MediaSource> &source) {
mSource = source;
const char *kHeader = isWide ? "#!AMR-WB\n" : "#!AMR\n";
- size_t n = strlen(kHeader);
+ ssize_t n = strlen(kHeader);
if (write(mFd, kHeader, n) != n) {
return ERROR_IO;
}
@@ -266,9 +272,8 @@ status_t AMRWriter::threadFunc() {
notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_COMPLETION_STATUS, UNKNOWN_ERROR);
}
- fflush(mFile);
- fclose(mFile);
- mFile = NULL;
+ close(mFd);
+ mFd = -1;
mReachedEOS = true;
if (err == ERROR_END_OF_STREAM) {
return OK;
diff --git a/media/libstagefright/FileSource.cpp b/media/libstagefright/FileSource.cpp
index c9f68e9..98d5b50 100644
--- a/media/libstagefright/FileSource.cpp
+++ b/media/libstagefright/FileSource.cpp
@@ -18,12 +18,14 @@
#include <media/stagefright/MediaDebug.h>
#include <sys/types.h>
#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
namespace android {
FileSource::FileSource(const char *filename)
- : mFile(fopen(filename, "rb")),
- mFd(mFile == NULL ? -1 : fileno(mFile)),
+ : mFd(-1),
mOffset(0),
mLength(-1),
mDecryptHandle(NULL),
@@ -31,11 +33,12 @@ FileSource::FileSource(const char *filename)
mDrmBufOffset(0),
mDrmBufSize(0),
mDrmBuf(NULL){
+
+ mFd = open(filename, O_LARGEFILE | O_RDONLY);
}
FileSource::FileSource(int fd, int64_t offset, int64_t length)
- : mFile(fdopen(fd, "rb")),
- mFd(fd),
+ : mFd(fd),
mOffset(offset),
mLength(length),
mDecryptHandle(NULL),
@@ -48,9 +51,9 @@ FileSource::FileSource(int fd, int64_t offset, int64_t length)
}
FileSource::~FileSource() {
- if (mFile != NULL) {
- fclose(mFile);
- mFile = NULL;
+ if (mFd >= 0) {
+ close(mFd);
+ mFd = -1;
}
if (mDrmBuf != NULL) {
@@ -60,11 +63,11 @@ FileSource::~FileSource() {
}
status_t FileSource::initCheck() const {
- return mFile != NULL ? OK : NO_INIT;
+ return mFd >= 0 ? OK : NO_INIT;
}
ssize_t FileSource::readAt(off64_t offset, void *data, size_t size) {
- if (mFile == NULL) {
+ if (mFd < 0) {
return NO_INIT;
}
@@ -95,7 +98,7 @@ ssize_t FileSource::readAt(off64_t offset, void *data, size_t size) {
}
status_t FileSource::getSize(off64_t *size) {
- if (mFile == NULL) {
+ if (mFd < 0) {
return NO_INIT;
}
diff --git a/media/libstagefright/MPEG2TSWriter.cpp b/media/libstagefright/MPEG2TSWriter.cpp
index 81a2b0d..4d8165e 100644
--- a/media/libstagefright/MPEG2TSWriter.cpp
+++ b/media/libstagefright/MPEG2TSWriter.cpp
@@ -410,7 +410,7 @@ void MPEG2TSWriter::SourceInfo::onMessageReceived(const sp<AMessage> &msg) {
////////////////////////////////////////////////////////////////////////////////
MPEG2TSWriter::MPEG2TSWriter(int fd)
- : mFile(fdopen(fd, "wb")),
+ : mFile(fdopen(dup(fd), "wb")),
mStarted(false),
mNumSourcesDone(0),
mNumTSPacketsWritten(0),
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index 19e3eae..6760707 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -33,6 +33,10 @@
#include <media/stagefright/MediaSource.h>
#include <media/stagefright/Utils.h>
#include <media/mediarecorder.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
#include "include/ESDS.h"
@@ -214,8 +218,8 @@ private:
};
MPEG4Writer::MPEG4Writer(const char *filename)
- : mFile(fopen(filename, "wb")),
- mFd(mFile == NULL? -1: fileno(mFile)),
+ : mFd(-1),
+ mInitCheck(NO_INIT),
mUse4ByteNalLength(true),
mUse32BitOffset(true),
mIsFileSizeLimitExplicitlyRequested(false),
@@ -225,12 +229,16 @@ MPEG4Writer::MPEG4Writer(const char *filename)
mMdatOffset(0),
mEstimatedMoovBoxSize(0),
mInterleaveDurationUs(1000000) {
- CHECK(mFile != NULL);
+
+ mFd = open(filename, O_CREAT | O_LARGEFILE | O_TRUNC);
+ if (mFd >= 0) {
+ mInitCheck = OK;
+ }
}
MPEG4Writer::MPEG4Writer(int fd)
- : mFile(fdopen(fd, "wb")),
- mFd(mFile == NULL? -1: fileno(mFile)),
+ : mFd(dup(fd)),
+ mInitCheck(mFd < 0? NO_INIT: OK),
mUse4ByteNalLength(true),
mUse32BitOffset(true),
mIsFileSizeLimitExplicitlyRequested(false),
@@ -240,7 +248,6 @@ MPEG4Writer::MPEG4Writer(int fd)
mMdatOffset(0),
mEstimatedMoovBoxSize(0),
mInterleaveDurationUs(1000000) {
- CHECK(mFile != NULL);
}
MPEG4Writer::~MPEG4Writer() {
@@ -370,7 +377,7 @@ int64_t MPEG4Writer::estimateMoovBoxSize(int32_t bitRate) {
}
status_t MPEG4Writer::start(MetaData *param) {
- if (mFile == NULL) {
+ if (mInitCheck != OK) {
return UNKNOWN_ERROR;
}
@@ -493,7 +500,7 @@ bool MPEG4Writer::use32BitFileOffset() const {
}
status_t MPEG4Writer::pause() {
- if (mFile == NULL) {
+ if (mInitCheck != OK) {
return OK;
}
mPaused = true;
@@ -577,7 +584,7 @@ void MPEG4Writer::writeCompositionMatrix(int degrees) {
status_t MPEG4Writer::stop() {
- if (mFile == NULL) {
+ if (mInitCheck != OK) {
return OK;
}
@@ -600,9 +607,9 @@ status_t MPEG4Writer::stop() {
// Do not write out movie header on error.
if (err != OK) {
- fflush(mFile);
- fclose(mFile);
- mFile = NULL;
+ close(mFd);
+ mFd = -1;
+ mInitCheck = NO_INIT;
mStarted = false;
return err;
}
@@ -665,7 +672,7 @@ status_t MPEG4Writer::stop() {
// Moov box
lseek64(mFd, mFreeBoxOffset, SEEK_SET);
mOffset = mFreeBoxOffset;
- write(mMoovBoxBuffer, 1, mMoovBoxBufferOffset, mFile);
+ write(mMoovBoxBuffer, 1, mMoovBoxBufferOffset);
// Free box
lseek64(mFd, mOffset, SEEK_SET);
@@ -682,9 +689,9 @@ status_t MPEG4Writer::stop() {
CHECK(mBoxes.empty());
- fflush(mFile);
- fclose(mFile);
- mFile = NULL;
+ close(mFd);
+ mFd = -1;
+ mInitCheck = NO_INIT;
mStarted = false;
return err;
}
@@ -763,20 +770,21 @@ off64_t MPEG4Writer::addLengthPrefixedSample_l(MediaBuffer *buffer) {
}
size_t MPEG4Writer::write(
- const void *ptr, size_t size, size_t nmemb, FILE *stream) {
+ const void *ptr, size_t size, size_t nmemb) {
const size_t bytes = size * nmemb;
- int fd = fileno(stream);
if (mWriteMoovBoxToMemory) {
+ // This happens only when we write the moov box at the end of
+ // recording, not for each output video/audio frame we receive.
off64_t moovBoxSize = 8 + mMoovBoxBufferOffset + bytes;
if (moovBoxSize > mEstimatedMoovBoxSize) {
for (List<off64_t>::iterator it = mBoxes.begin();
it != mBoxes.end(); ++it) {
(*it) += mOffset;
}
- lseek64(fd, mOffset, SEEK_SET);
- ::write(fd, mMoovBoxBuffer, mMoovBoxBufferOffset);
- ::write(fd, ptr, size * nmemb);
+ lseek64(mFd, mOffset, SEEK_SET);
+ ::write(mFd, mMoovBoxBuffer, mMoovBoxBufferOffset);
+ ::write(mFd, ptr, size * nmemb);
mOffset += (bytes + mMoovBoxBufferOffset);
free(mMoovBoxBuffer);
mMoovBoxBuffer = NULL;
@@ -788,7 +796,7 @@ size_t MPEG4Writer::write(
mMoovBoxBufferOffset += bytes;
}
} else {
- ::write(fd, ptr, size * nmemb);
+ ::write(mFd, ptr, size * nmemb);
mOffset += bytes;
}
return bytes;
@@ -822,36 +830,36 @@ void MPEG4Writer::endBox() {
}
void MPEG4Writer::writeInt8(int8_t x) {
- write(&x, 1, 1, mFile);
+ write(&x, 1, 1);
}
void MPEG4Writer::writeInt16(int16_t x) {
x = htons(x);
- write(&x, 1, 2, mFile);
+ write(&x, 1, 2);
}
void MPEG4Writer::writeInt32(int32_t x) {
x = htonl(x);
- write(&x, 1, 4, mFile);
+ write(&x, 1, 4);
}
void MPEG4Writer::writeInt64(int64_t x) {
x = hton64(x);
- write(&x, 1, 8, mFile);
+ write(&x, 1, 8);
}
void MPEG4Writer::writeCString(const char *s) {
size_t n = strlen(s);
- write(s, 1, n + 1, mFile);
+ write(s, 1, n + 1);
}
void MPEG4Writer::writeFourcc(const char *s) {
CHECK_EQ(strlen(s), 4);
- write(s, 1, 4, mFile);
+ write(s, 1, 4);
}
void MPEG4Writer::write(const void *data, size_t size) {
- write(data, 1, size, mFile);
+ write(data, 1, size);
}
bool MPEG4Writer::isFileStreamable() const {
diff --git a/media/libstagefright/StagefrightMediaScanner.cpp b/media/libstagefright/StagefrightMediaScanner.cpp
index 0f6af28..86e0e73 100644
--- a/media/libstagefright/StagefrightMediaScanner.cpp
+++ b/media/libstagefright/StagefrightMediaScanner.cpp
@@ -127,10 +127,11 @@ status_t StagefrightMediaScanner::processFile(
|| !strcasecmp(extension, ".rtttl")
|| !strcasecmp(extension, ".rtx")
|| !strcasecmp(extension, ".ota")) {
- return HandleMIDI(path, &client);
- }
-
- if (mRetriever->setDataSource(path) == OK
+ status_t status = HandleMIDI(path, &client);
+ if (status != OK) {
+ return status;
+ }
+ } else if (mRetriever->setDataSource(path) == OK
&& mRetriever->setMode(
METADATA_MODE_METADATA_RETRIEVAL_ONLY) == OK) {
const char *value;
diff --git a/media/libstagefright/rtsp/ARTPWriter.cpp b/media/libstagefright/rtsp/ARTPWriter.cpp
index 155fd96..5a033e1 100644
--- a/media/libstagefright/rtsp/ARTPWriter.cpp
+++ b/media/libstagefright/rtsp/ARTPWriter.cpp
@@ -46,7 +46,7 @@ static int UniformRand(int limit) {
ARTPWriter::ARTPWriter(int fd)
: mFlags(0),
- mFd(fd),
+ mFd(dup(fd)),
mLooper(new ALooper),
mReflector(new AHandlerReflector<ARTPWriter>(this)) {
CHECK_GE(fd, 0);
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerGetCurrentPositionStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerGetCurrentPositionStateUnitTest.java
index 032b469..fd1c2d3 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerGetCurrentPositionStateUnitTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerGetCurrentPositionStateUnitTest.java
@@ -45,11 +45,11 @@ public class MediaPlayerGetCurrentPositionStateUnitTest extends AndroidTestCase
assertTrue(!stateErrors.errorInPausedState);
assertTrue(!stateErrors.errorInStoppedState);
assertTrue(!stateErrors.errorInPlaybackCompletedState);
- assertTrue(!stateErrors.errorInIdleStateAfterReset);
// Invalid states.
assertTrue(stateErrors.errorInErrorState);
- assertTrue(!stateErrors.errorInIdleState); // onError() won't be called
+ assertTrue(stateErrors.errorInIdleStateAfterReset);
+ assertTrue(stateErrors.errorInIdleState);
}
public void invokeMethodUnderTest(MediaPlayer player) {
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerGetDurationStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerGetDurationStateUnitTest.java
index 5f7abe5..48fd16c 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerGetDurationStateUnitTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerGetDurationStateUnitTest.java
@@ -46,10 +46,10 @@ public class MediaPlayerGetDurationStateUnitTest extends AndroidTestCase impleme
assertTrue(!stateErrors.errorInPlaybackCompletedState);
// Invalid states.
- assertTrue(!stateErrors.errorInIdleState); // onError() won't be called
assertTrue(stateErrors.errorInInitializedState);
assertTrue(stateErrors.errorInErrorState);
assertTrue(stateErrors.errorInIdleStateAfterReset);
+ assertTrue(stateErrors.errorInIdleState);
}
public void invokeMethodUnderTest(MediaPlayer player) {
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerPauseStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerPauseStateUnitTest.java
index 0a18a39..7a96792 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerPauseStateUnitTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerPauseStateUnitTest.java
@@ -29,9 +29,9 @@ public class MediaPlayerPauseStateUnitTest extends AndroidTestCase implements Me
/**
* 1. It is valid to call pause() in the following states:
- * {Started, Paused}.
+ * {Started, Paused, PlaybackCompleted}.
* 2. It is invalid to call pause() in the following states:
- * {Idle, Initialized, Prepared, Stopped, PlaybackCompleted, Error}
+ * {Idle, Initialized, Prepared, Stopped, Error}
*
* @param stateErrors the MediaPlayerStateErrors to check against.
*/
@@ -40,12 +40,12 @@ public class MediaPlayerPauseStateUnitTest extends AndroidTestCase implements Me
assertTrue(!stateErrors.errorInStartedState);
assertTrue(!stateErrors.errorInStartedStateAfterPause);
assertTrue(!stateErrors.errorInPausedState);
+ assertTrue(!stateErrors.errorInPlaybackCompletedState);
// Invalid states.
assertTrue(stateErrors.errorInPreparedState);
assertTrue(stateErrors.errorInPreparedStateAfterStop);
- assertTrue(stateErrors.errorInPlaybackCompletedState);
- assertTrue(!stateErrors.errorInIdleState); // noError() won't be called
+ assertTrue(stateErrors.errorInIdleState);
assertTrue(stateErrors.errorInIdleStateAfterReset);
assertTrue(stateErrors.errorInInitializedState);
assertTrue(stateErrors.errorInStoppedState);
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerSeekToStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerSeekToStateUnitTest.java
index 46bba9b..991fe9c 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerSeekToStateUnitTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerSeekToStateUnitTest.java
@@ -39,17 +39,17 @@ public class MediaPlayerSeekToStateUnitTest extends AndroidTestCase implements M
// Valid states.
assertTrue(!stateErrors.errorInPreparedState);
assertTrue(!stateErrors.errorInPreparedStateAfterStop);
- assertTrue(!stateErrors.errorInStartedState);
assertTrue(!stateErrors.errorInStartedStateAfterPause);
assertTrue(!stateErrors.errorInPausedState);
assertTrue(!stateErrors.errorInPlaybackCompletedState);
// Invalid states.
- assertTrue(!stateErrors.errorInIdleState); // onError() won't be called
+ assertTrue(stateErrors.errorInIdleState);
assertTrue(stateErrors.errorInIdleStateAfterReset);
assertTrue(stateErrors.errorInInitializedState);
assertTrue(stateErrors.errorInStoppedState);
assertTrue(stateErrors.errorInErrorState);
+ assertTrue(!stateErrors.errorInStartedState);
}
public void invokeMethodUnderTest(MediaPlayer player) {
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerSetAudioStreamTypeStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerSetAudioStreamTypeStateUnitTest.java
index 3153792..b984514 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerSetAudioStreamTypeStateUnitTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerSetAudioStreamTypeStateUnitTest.java
@@ -58,7 +58,7 @@ public class MediaPlayerSetAudioStreamTypeStateUnitTest extends AndroidTestCase
}
@LargeTest
- public void testSetAudioSystemType() {
+ public void testSetAudioStreamType() {
mTestTemplate.runTestOnMethod(this);
}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerStartStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerStartStateUnitTest.java
index 6debbb4..68c8e42 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerStartStateUnitTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerStartStateUnitTest.java
@@ -45,7 +45,7 @@ public class MediaPlayerStartStateUnitTest extends AndroidTestCase implements Me
assertTrue(!stateErrors.errorInPlaybackCompletedState);
// Invalid states.
- assertTrue(!stateErrors.errorInIdleState); // onError() won't be called
+ assertTrue(stateErrors.errorInIdleState);
assertTrue(stateErrors.errorInErrorState);
assertTrue(stateErrors.errorInIdleStateAfterReset);
assertTrue(stateErrors.errorInInitializedState);
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerStopStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerStopStateUnitTest.java
index 3427f86..ab8519a 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerStopStateUnitTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerStopStateUnitTest.java
@@ -46,7 +46,7 @@ public class MediaPlayerStopStateUnitTest extends AndroidTestCase implements Med
assertTrue(!stateErrors.errorInPausedState);
// Invalid states.
- assertTrue(!stateErrors.errorInIdleState); // noError() won't be called
+ assertTrue(stateErrors.errorInIdleState);
assertTrue(stateErrors.errorInIdleStateAfterReset);
assertTrue(stateErrors.errorInInitializedState);
assertTrue(stateErrors.errorInErrorState);
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png
deleted file mode 100644
index 6baf5ea..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_default.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_default.png
new file mode 100644
index 0000000..615c8b6
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_default.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_default.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_default.png
new file mode 100644
index 0000000..0122025
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_default.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_pressed.png
new file mode 100644
index 0000000..0786916
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_pressed.png
new file mode 100644
index 0000000..35f9240
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home.png
deleted file mode 100644
index ed813dc..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_default.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_default.png
new file mode 100644
index 0000000..3eb22df
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_default.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_pressed.png
new file mode 100644
index 0000000..1ce9bd1
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_default.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_default.png
index bf33c94..259db7a 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_default.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_default.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_pressed.png
new file mode 100644
index 0000000..993ea55
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu.png
deleted file mode 100644
index d7775f2..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_default.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_default.png
new file mode 100644
index 0000000..fef2cf9
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_default.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_pressed.png
new file mode 100644
index 0000000..05593bc
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent.png
deleted file mode 100644
index 178af73..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_default.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_default.png
new file mode 100644
index 0000000..32c2c79
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_default.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_pressed.png
new file mode 100644
index 0000000..142c413
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable/status_bar_menu.xml b/packages/SystemUI/res/drawable/ic_sysbar_back.xml
index aa7286e..327ccd8 100644
--- a/packages/SystemUI/res/drawable/status_bar_menu.xml
+++ b/packages/SystemUI/res/drawable/ic_sysbar_back.xml
@@ -15,7 +15,7 @@
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_pressed="true" android:drawable="@drawable/status_bar_menu_pressed" />
- <item android:drawable="@drawable/status_bar_menu_default" />
+ <item android:state_pressed="true" android:drawable="@drawable/ic_sysbar_back_pressed" />
+ <item android:drawable="@drawable/ic_sysbar_back_default" />
</selector>
diff --git a/packages/SystemUI/res/drawable/status_bar_home.xml b/packages/SystemUI/res/drawable/ic_sysbar_home.xml
index 0011711..f4e585e 100644
--- a/packages/SystemUI/res/drawable/status_bar_home.xml
+++ b/packages/SystemUI/res/drawable/ic_sysbar_home.xml
@@ -15,7 +15,7 @@
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_pressed="true" android:drawable="@drawable/status_bar_home_pressed" />
- <item android:drawable="@drawable/status_bar_home_default" />
+ <item android:state_pressed="true" android:drawable="@drawable/ic_sysbar_home_pressed" />
+ <item android:drawable="@drawable/ic_sysbar_home_default" />
</selector>
diff --git a/packages/SystemUI/res/drawable/status_bar_back.xml b/packages/SystemUI/res/drawable/ic_sysbar_ime.xml
index 92bf147..1accf00 100644
--- a/packages/SystemUI/res/drawable/status_bar_back.xml
+++ b/packages/SystemUI/res/drawable/ic_sysbar_ime.xml
@@ -15,7 +15,7 @@
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_pressed="true" android:drawable="@drawable/status_bar_back_pressed" />
- <item android:drawable="@drawable/status_bar_back_default" />
+ <item android:state_pressed="true" android:drawable="@drawable/ic_sysbar_ime_pressed" />
+ <item android:drawable="@drawable/ic_sysbar_ime_default" />
</selector>
diff --git a/packages/SystemUI/res/drawable/status_bar_recent.xml b/packages/SystemUI/res/drawable/ic_sysbar_menu.xml
index d708455..7a10607 100755..100644
--- a/packages/SystemUI/res/drawable/status_bar_recent.xml
+++ b/packages/SystemUI/res/drawable/ic_sysbar_menu.xml
@@ -15,7 +15,7 @@
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_pressed="true" android:drawable="@drawable/status_bar_recent_pressed" />
- <item android:drawable="@drawable/status_bar_recent_default" />
+ <item android:state_pressed="true" android:drawable="@drawable/ic_sysbar_menu_pressed" />
+ <item android:drawable="@drawable/ic_sysbar_menu_default" />
</selector>
diff --git a/packages/SystemUI/res/drawable/ic_sysbar_recent.xml b/packages/SystemUI/res/drawable/ic_sysbar_recent.xml
new file mode 100755
index 0000000..39a324b
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_sysbar_recent.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="true" android:drawable="@drawable/ic_sysbar_recent_pressed" />
+ <item android:drawable="@drawable/ic_sysbar_recent_default" />
+</selector>
+
diff --git a/packages/SystemUI/res/drawable/ic_sysbar_icon_bg.xml b/packages/SystemUI/res/drawable/status_bar_ticker_background.xml
index d8ba2a8..c230358 100644
--- a/packages/SystemUI/res/drawable/ic_sysbar_icon_bg.xml
+++ b/packages/SystemUI/res/drawable/status_bar_ticker_background.xml
@@ -4,9 +4,9 @@
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
-
+
http://www.apache.org/licenses/LICENSE-2.0
-
+
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -14,8 +14,14 @@
limitations under the License.
-->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_pressed="true" android:drawable="@drawable/ic_sysbar_press_bg" />
- <item android:drawable="@drawable/ic_sysbar_default_bg" />
-</selector>
+<layer-list
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:opacity="translucent"
+ >
+ <item
+ android:drawable="@drawable/ticker_background_color"
+ android:top="12dp"
+ />
+</layer-list>
+
diff --git a/packages/SystemUI/res/drawable/ticker_background.xml b/packages/SystemUI/res/drawable/ticker_background.xml
new file mode 100644
index 0000000..7320fa0
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ticker_background.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2006 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<layer-list
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:opacity="translucent"
+ >
+ <!-- the large icon extends 12dp beyond the edge of the status bar -->
+ <item
+ android:drawable="@drawable/notification_item_background_color"
+ android:top="12dp"
+ />
+</layer-list>
+
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar.xml b/packages/SystemUI/res/layout-xlarge/status_bar.xml
index d11e6da..4fa306e 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar.xml
@@ -39,7 +39,6 @@
android:id="@+id/notificationIcons"
android:layout_width="wrap_content"
android:layout_height="match_parent"
- android:gravity="center_vertical"
android:orientation="horizontal"
>
<view
@@ -47,7 +46,9 @@
android:id="@+id/icons"
android:layout_width="wrap_content"
android:layout_height="@*android:dimen/status_bar_icon_size"
- android:layout_marginLeft="8dip"
+ android:layout_gravity="top"
+ android:layout_marginTop="5dp"
+ android:layout_marginLeft="8dp"
/>
</com.android.systemui.statusbar.tablet.NotificationIconArea>
@@ -84,13 +85,15 @@
android:id="@+id/battery"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
- android:layout_gravity="center_vertical"
+ android:layout_gravity="top"
+ android:layout_marginTop="18dp"
/>
<ImageView
android:id="@+id/network"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
- android:layout_gravity="center_vertical"
+ android:layout_gravity="top"
+ android:layout_marginTop="14dp"
android:src="@drawable/ic_sysbar_wifi_mini"
/>
</LinearLayout>
@@ -112,7 +115,6 @@
android:paddingLeft="18dip"
android:paddingRight="18dip"
android:src="@drawable/ic_sysbar_back"
- android:background="@drawable/ic_sysbar_icon_bg"
systemui:keyCode="4"
/>
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home"
@@ -121,14 +123,13 @@
android:paddingLeft="18dip"
android:paddingRight="18dip"
android:src="@drawable/ic_sysbar_home"
- android:background="@drawable/ic_sysbar_icon_bg"
systemui:keyCode="3"
/>
<ImageButton android:id="@+id/recent_apps"
android:layout_width="96dip"
android:layout_height="match_parent"
android:src="@drawable/ic_sysbar_recent"
- android:background="@drawable/ic_sysbar_icon_bg"
+ android:background="@null"
android:paddingLeft="18dip"
android:clickable="true"
android:paddingRight="18dip"
@@ -139,7 +140,6 @@
android:paddingLeft="18dip"
android:paddingRight="18dip"
android:src="@drawable/ic_sysbar_menu"
- android:background="@drawable/ic_sysbar_icon_bg"
systemui:keyCode="82"
android:visibility="invisible"
/>
@@ -147,7 +147,6 @@
android:id="@+id/pocket"
android:layout_width="96dip"
android:layout_height="match_parent"
- android:background="@drawable/ic_sysbar_icon_bg"
android:paddingLeft="18dip"
android:paddingRight="18dip"
android:animateLayoutChanges="true"
@@ -169,8 +168,7 @@
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="8dip"
- android:src="@drawable/ic_sysbar_ime_default"
- android:background="@drawable/ic_sysbar_icon_bg"
+ android:src="@drawable/ic_sysbar_ime"
android:visibility="invisible"
/>
</LinearLayout>
@@ -238,17 +236,5 @@
android:visibility="gone"
/>
</RelativeLayout>
-
- <!-- ticker: transient incoming notification information -->
- <FrameLayout
- android:id="@+id/ticker"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_alignParentRight="true"
- android:layout_toRightOf="@+id/systemInfo"
- android:paddingLeft="6dip"
- android:gravity="center_vertical"
- />
-
</RelativeLayout>
</com.android.systemui.statusbar.tablet.TabletStatusBarView>
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_latest_event.xml b/packages/SystemUI/res/layout-xlarge/status_bar_latest_event.xml
index b6679a5..6b12d29 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar_latest_event.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar_latest_event.xml
@@ -13,13 +13,24 @@
android:src="@drawable/status_bar_veto"
android:scaleType="center"
android:background="#ff000000"
+ android:paddingRight="8dp"
/>
+ <ImageView
+ android:id="@+id/large_icon"
+ android:layout_width="@dimen/notification_large_icon_width"
+ android:layout_height="@dimen/notification_large_icon_height"
+ android:layout_alignParentTop="true"
+ android:layout_alignParentLeft="true"
+ android:scaleType="center"
+ />
+ <!-- TODO: scaleType should be top-left but ImageView doesn't support that. -->
+
<com.android.systemui.statusbar.LatestItemView android:id="@+id/content"
android:layout_width="wrap_content"
android:layout_height="64sp"
android:layout_alignParentTop="true"
- android:layout_alignParentLeft="true"
+ android:layout_toRightOf="@id/large_icon"
android:layout_toLeftOf="@id/veto"
android:layout_marginLeft="16dp"
android:focusable="true"
diff --git a/packages/SystemUI/res/layout-xlarge/sysbar_panel_notifications.xml b/packages/SystemUI/res/layout-xlarge/sysbar_panel_notifications.xml
index b23cc7b..f9e2d5e 100644
--- a/packages/SystemUI/res/layout-xlarge/sysbar_panel_notifications.xml
+++ b/packages/SystemUI/res/layout-xlarge/sysbar_panel_notifications.xml
@@ -1,43 +1,40 @@
-<?xml version="1.0" encoding="utf-8"?>
<!--
-/* apps/common/assets/default/default/skins/StatusBar.xml
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
+ Copyright (C) 2006 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
-->
<!-- android:background="@drawable/status_bar_closed_default_background" -->
<com.android.systemui.statusbar.tablet.NotificationPanel
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
- android:layout_width="540dp"
+ android:layout_width="match_parent"
android:animateLayoutChanges="true"
android:background="@drawable/bg_scrim_notification"
+ android:paddingTop="32dp"
android:paddingBottom="32dp"
+ android:orientation="vertical"
+ android:gravity="right"
>
<com.android.systemui.statusbar.tablet.NotificationTitleArea
android:id="@+id/title_area"
- android:layout_height="wrap_content"
+ android:layout_height="160dp"
android:layout_width="384dp"
- android:layout_above="@+id/content_frame"
android:layout_marginLeft="24dp"
- android:paddingBottom="16dp"
+ android:paddingTop="20dp"
android:orientation="vertical"
android:animateLayoutChanges="true"
- android:layout_alignParentRight="true"
>
<com.android.systemui.statusbar.tablet.HoloClock
@@ -143,8 +140,6 @@
android:id="@+id/content_frame"
android:layout_height="wrap_content"
android:layout_width="408dp"
- android:layout_alignParentBottom="true"
- android:layout_alignParentRight="true"
>
<ScrollView
android:id="@+id/notificationScroller"
diff --git a/packages/SystemUI/res/layout-xlarge/ticker.xml b/packages/SystemUI/res/layout-xlarge/ticker.xml
index c8d855f..cae6a77 100644
--- a/packages/SystemUI/res/layout-xlarge/ticker.xml
+++ b/packages/SystemUI/res/layout-xlarge/ticker.xml
@@ -18,36 +18,22 @@
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="match_parent"
+ android:layout_height="wrap_content"
android:orientation="horizontal"
- android:background="#ff000000"
+ android:background="@drawable/status_bar_ticker_background"
+ android:gravity="bottom"
>
+ <!--
+ android:background="@drawable/ticker_background"
+ -->
- <LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:layout_gravity="center_vertical"
- android:orientation="vertical"
- android:paddingLeft="12dp"
- >
-
- <TextView android:id="@+id/title"
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:textAppearance="@*android:style/TextAppearance.StatusBar.Ticker"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textStyle="bold"
- android:maxLines="1"
- />
- <TextView android:id="@+id/subtitle"
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:textAppearance="@*android:style/TextAppearance.StatusBar.Ticker"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:maxLines="1"
- />
- </LinearLayout>
+ <ImageView
+ android:id="@+id/large_icon"
+ android:layout_width="@dimen/notification_large_icon_height"
+ android:layout_height="@dimen/notification_large_icon_width"
+ android:scaleType="center"
+ android:visibility="gone"
+ />
+ <!-- TODO: scaleType should be top-left but ImageView doesn't support that. -->
</LinearLayout>
diff --git a/packages/SystemUI/res/layout-xlarge/ticker_compat.xml b/packages/SystemUI/res/layout-xlarge/ticker_compat.xml
index 79c7543..5d9a680 100644
--- a/packages/SystemUI/res/layout-xlarge/ticker_compat.xml
+++ b/packages/SystemUI/res/layout-xlarge/ticker_compat.xml
@@ -18,11 +18,26 @@
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="match_parent"
+ android:layout_height="@*android:dimen/status_bar_height"
android:orientation="horizontal"
- android:background="#ff000000"
+ android:background="@drawable/status_bar_ticker_background"
>
+ <ImageView
+ android:id="@+id/large_icon"
+ android:layout_width="@dimen/notification_large_icon_width"
+ android:layout_height="@dimen/notification_large_icon_height"
+ android:scaleType="center"
+ android:visibility="gone"
+ />
+
+ <ImageView android:id="@+id/left_icon"
+ android:layout_width="64dp"
+ android:layout_height="match_parent"
+ android:scaleType="center"
+ android:visibility="gone"
+ />
+
<TextView android:id="@+id/text"
android:textAppearance="@*android:style/TextAppearance.StatusBar.Ticker"
android:layout_width="match_parent"
@@ -33,4 +48,11 @@
android:maxLines="2"
/>
+ <ImageView android:id="@+id/right_icon"
+ android:layout_width="64dp"
+ android:layout_height="match_parent"
+ android:scaleType="center"
+ android:visibility="gone"
+ />
+
</LinearLayout>
diff --git a/packages/SystemUI/res/values-xlarge/config.xml b/packages/SystemUI/res/values-xlarge/config.xml
index e6af4f5..e140914 100644
--- a/packages/SystemUI/res/values-xlarge/config.xml
+++ b/packages/SystemUI/res/values-xlarge/config.xml
@@ -26,5 +26,8 @@
interface. This name is in the ComponentName flattened format (package/class) -->
<string name="config_statusBarComponent">com.android.systemui.statusbar.tablet.TabletStatusBar</string>
+ <!-- Whether or not we show the number in the bar. -->
+ <bool name="config_statusBarShowNumber">false</bool>
+
</resources>
diff --git a/packages/SystemUI/res/values-xlarge/dimens.xml b/packages/SystemUI/res/values-xlarge/dimens.xml
new file mode 100644
index 0000000..009b7a8
--- /dev/null
+++ b/packages/SystemUI/res/values-xlarge/dimens.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (c) 2006, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+-->
+<resources>
+ <!-- The width of the big icons in notifications. -->
+ <dimen name="notification_large_icon_width">60dp</dimen>
+ <!-- The width of the big icons in notifications. -->
+ <dimen name="notification_large_icon_height">60dp</dimen>
+ <!-- The width of the ticker, including the icon -->
+ <dimen name="notification_ticker_width">360dp</dimen>
+</resources>
+
+
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index fd2cf99..964e69b 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -19,4 +19,5 @@
<resources>
<drawable name="notification_number_text_color">#ffffffff</drawable>
<drawable name="notification_item_background_color">#ff000000</drawable>
+ <drawable name="ticker_background_color">#ff1d1d1d</drawable>
</resources>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 86beb14..05ed089 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -35,5 +35,8 @@
interface. This name is in the ComponentName flattened format (package/class) -->
<string name="config_statusBarComponent" translatable="false">com.android.systemui.statusbar.phone.PhoneStatusBar</string>
+ <!-- Whether or not we show the number in the bar. -->
+ <bool name="config_statusBarShowNumber">true</bool>
+
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index 9a61be6..dbfbe11 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -93,7 +93,8 @@ public class StatusBarIconView extends AnimatedImageView {
setImageLevel(icon.iconLevel);
}
if (!numberEquals) {
- if (icon.number > 0) {
+ if (icon.number > 0 && mContext.getResources().getBoolean(
+ R.bool.config_statusBarShowNumber)) {
if (mNumberBackground == null) {
mNumberBackground = getContext().getResources().getDrawable(
R.drawable.ic_notification_overlay);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
index 80cb5b2..5f49d8c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
@@ -19,16 +19,16 @@ package com.android.systemui.statusbar.tablet;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Slog;
-import android.widget.ImageView;
-import android.widget.RelativeLayout;
-import android.widget.TextView;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
import com.android.systemui.R;
-public class NotificationPanel extends RelativeLayout implements StatusBarPanel,
+public class NotificationPanel extends LinearLayout implements StatusBarPanel,
View.OnClickListener {
static final String TAG = "NotificationPanel";
@@ -71,6 +71,29 @@ public class NotificationPanel extends RelativeLayout implements StatusBarPanel,
}
}
+ /**
+ * We need to be aligned at the bottom. LinearLayout can't do this, so instead,
+ * let LinearLayout do all the hard work, and then shift everything down to the bottom.
+ */
+ @Override
+ protected void onLayout(boolean changed, int l, int t, int r, int b) {
+ super.onLayout(changed, l, t, r, b);
+ // We know that none of our children are GONE, so don't worry about skipping GONE views.
+ final int N = getChildCount();
+ if (N == 0) {
+ return;
+ }
+ final int allocatedBottom = getChildAt(N-1).getBottom();
+ final int shift = b - allocatedBottom - getPaddingBottom();
+ if (shift <= 0) {
+ return;
+ }
+ for (int i=0; i<N; i++) {
+ final View c = getChildAt(i);
+ c.layout(c.getLeft(), c.getTop() + shift, c.getRight(), c.getBottom() + shift);
+ }
+ }
+
public void onClick(View v) {
if (v == mSettingsButton) {
switchToSettingsMode();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index 233ac45..ab509ef 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -132,8 +132,6 @@ public class TabletStatusBar extends StatusBar {
NotificationIconArea.IconLayout mIconLayout;
TabletTicker mTicker;
- View mTickerView;
- boolean mTicking;
// for disabling the status bar
int mDisabled = 0;
@@ -167,7 +165,7 @@ public class TabletStatusBar extends StatusBar {
mStatusBarView.setIgnoreChildren(0, mNotificationTrigger, mNotificationPanel);
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
- ViewGroup.LayoutParams.WRAP_CONTENT,
+ ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
@@ -278,7 +276,7 @@ public class TabletStatusBar extends StatusBar {
mNotificationPeekTapDuration = vc.getTapTimeout();
mNotificationFlingVelocity = 300; // px/s
- mTicker = new TabletTicker(context, (FrameLayout)sb.findViewById(R.id.ticker));
+ mTicker = new TabletTicker(context);
// The icons
mBatteryController = new BatteryController(mContext);
@@ -385,9 +383,7 @@ public class TabletStatusBar extends StatusBar {
if (DEBUG) Slog.d(TAG, "opening notifications panel");
if (mNotificationPanel.getVisibility() == View.GONE) {
mNotificationPeekWindow.setVisibility(View.GONE);
-
mNotificationPanel.setVisibility(View.VISIBLE);
-
// synchronize with current shadow state
mShadowController.hideElement(mNotificationArea);
}
@@ -396,7 +392,6 @@ public class TabletStatusBar extends StatusBar {
if (DEBUG) Slog.d(TAG, "closing notifications panel");
if (mNotificationPanel.getVisibility() == View.VISIBLE) {
mNotificationPanel.setVisibility(View.GONE);
-
// synchronize with current shadow state
mShadowController.showElement(mNotificationArea);
}
@@ -464,7 +459,7 @@ public class TabletStatusBar extends StatusBar {
boolean immersive = false;
try {
immersive = ActivityManagerNative.getDefault().isTopActivityImmersive();
- Slog.d(TAG, "Top activity is " + (immersive?"immersive":"not immersive"));
+ //Slog.d(TAG, "Top activity is " + (immersive?"immersive":"not immersive"));
} catch (RemoteException ex) {
}
if (false && immersive) {
@@ -603,9 +598,7 @@ public class TabletStatusBar extends StatusBar {
}
private boolean hasTicker(Notification n) {
- return !TextUtils.isEmpty(n.tickerText)
- || !TextUtils.isEmpty(n.tickerTitle)
- || !TextUtils.isEmpty(n.tickerSubtitle);
+ return n.tickerView != null || !TextUtils.isEmpty(n.tickerText);
}
private void tick(StatusBarNotification n) {
@@ -1005,13 +998,21 @@ public class TabletStatusBar extends StatusBar {
} catch (RemoteException ex) {
// system process is dead if we're here.
}
- // animateCollapse();
}
});
} else {
vetoButton.setVisibility(View.INVISIBLE);
}
+ // the large icon
+ ImageView largeIcon = (ImageView)row.findViewById(R.id.large_icon);
+ if (sbn.notification.largeIcon != null) {
+ largeIcon.setImageBitmap(sbn.notification.largeIcon);
+ } else {
+ largeIcon.getLayoutParams().width = 0;
+ largeIcon.setVisibility(View.INVISIBLE);
+ }
+
// bind the click event to the content area
ViewGroup content = (ViewGroup)row.findViewById(R.id.content);
// XXX: update to allow controls within notification views
@@ -1034,7 +1035,7 @@ public class TabletStatusBar extends StatusBar {
exception = e;
}
if (expanded == null) {
- String ident = sbn.pkg + "/0x" + Integer.toHexString(sbn.id);
+ final String ident = sbn.pkg + "/0x" + Integer.toHexString(sbn.id);
Slog.e(TAG, "couldn't inflate view for notification " + ident, exception);
return false;
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java
index 3c3139f..7f743b2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java
@@ -16,9 +16,14 @@
package com.android.systemui.statusbar.tablet;
+import java.util.Arrays;
+
import android.app.Notification;
import android.content.Context;
+import android.content.res.Resources;
import android.graphics.Bitmap;
+import android.graphics.PixelFormat;
+import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
import android.util.Slog;
@@ -26,16 +31,18 @@ import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.view.WindowManagerImpl;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
+import com.android.internal.statusbar.StatusBarIcon;
import com.android.internal.statusbar.StatusBarNotification;
import com.android.systemui.R;
-
-import java.util.Arrays;
+import com.android.systemui.statusbar.StatusBarIconView;
public class TabletTicker extends Handler {
private static final String TAG = "StatusBar.TabletTicker";
@@ -45,17 +52,16 @@ public class TabletTicker extends Handler {
private static final int ADVANCE_DELAY = 5000; // 5 seconds
private Context mContext;
- private FrameLayout mParent;
+ private ViewGroup mWindow;
private StatusBarNotification mCurrentNotification;
private View mCurrentView;
private StatusBarNotification[] mQueue;
private int mQueuePos;
- public TabletTicker(Context context, FrameLayout parent) {
+ public TabletTicker(Context context) {
mContext = context;
- mParent = parent;
// TODO: Make this a configuration value.
// 3 is enough to let us see most cases, but not get so far behind that it's annoying.
@@ -102,18 +108,33 @@ public class TabletTicker extends Handler {
private void advance() {
// Out with the old...
if (mCurrentView != null) {
- mParent.removeView(mCurrentView);
+ mWindow.removeView(mCurrentView);
mCurrentView = null;
mCurrentNotification = null;
}
// In with the new...
- final StatusBarNotification next = dequeue();
- if (next != null) {
+ StatusBarNotification next = dequeue();
+ while (next != null) {
mCurrentNotification = next;
mCurrentView = makeTickerView(next);
- mParent.addView(mCurrentView);
- sendEmptyMessageDelayed(MSG_ADVANCE, ADVANCE_DELAY);
+ if (mCurrentView != null) {
+ if (mWindow == null) {
+ mWindow = makeWindow();
+ WindowManagerImpl.getDefault().addView(mWindow, mWindow.getLayoutParams());
+ }
+ mWindow.addView(mCurrentView);
+ sendEmptyMessageDelayed(MSG_ADVANCE, ADVANCE_DELAY);
+ break;
+ }
+ next = dequeue();
+ }
+
+ // if there's nothing left, close the window
+ // TODO: Do this when the animation is done instead
+ if (mCurrentView == null) {
+ WindowManagerImpl.getDefault().removeView(mWindow);
+ mWindow = null;
}
}
@@ -133,46 +154,76 @@ public class TabletTicker extends Handler {
return notification;
}
+ private ViewGroup makeWindow() {
+ final Resources res = mContext.getResources();
+ final FrameLayout view = new FrameLayout(mContext);
+ final int width = res.getDimensionPixelSize(R.dimen.notification_ticker_width);
+ final int height = res.getDimensionPixelSize(R.dimen.notification_large_icon_height);
+ WindowManager.LayoutParams lp = new WindowManager.LayoutParams(width, height,
+ WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
+ WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+ | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+ | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
+ PixelFormat.TRANSLUCENT);
+ lp.gravity = Gravity.BOTTOM | Gravity.RIGHT;
+ lp.setTitle("NotificationTicker");
+ view.setLayoutParams(lp);
+ return view;
+ }
+
private View makeTickerView(StatusBarNotification notification) {
final Notification n = notification.notification;
LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
- int layoutId;
ViewGroup group;
- if (n.tickerTitle != null || n.tickerSubtitle != null) {
- group = (ViewGroup)inflater.inflate(R.layout.ticker, mParent, false);
- if (n.tickerTitle != null) {
- final TextView title = (TextView)group.findViewById(R.id.title);
- title.setText(n.tickerTitle);
+ int layoutId;
+ int iconId;
+ if (n.largeIcon != null) {
+ iconId = R.id.right_icon;
+ } else {
+ iconId = R.id.left_icon;
+ }
+ if (n.tickerView != null) {
+ group = (ViewGroup)inflater.inflate(R.layout.ticker, null, false);
+ View expanded = null;
+ Exception exception = null;
+ try {
+ expanded = n.tickerView.apply(mContext, group);
}
- if (n.tickerSubtitle != null) {
- final TextView subtitle = (TextView)group.findViewById(R.id.subtitle);
- subtitle.setText(n.tickerSubtitle);
+ catch (RuntimeException e) {
+ exception = e;
}
- } else {
- group = (ViewGroup)inflater.inflate(R.layout.ticker_compat, mParent, false);
+ if (expanded == null) {
+ final String ident = notification.pkg
+ + "/0x" + Integer.toHexString(notification.id);
+ Slog.e(TAG, "couldn't inflate view for notification " + ident, exception);
+ return null;
+ }
+ final int statusBarHeight = mContext.getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.status_bar_height);
+ LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.WRAP_CONTENT, statusBarHeight, 1.0f);
+ lp.gravity = Gravity.BOTTOM;
+ group.addView(expanded, lp);
+ } else if (n.tickerText != null) {
+ group = (ViewGroup)inflater.inflate(R.layout.ticker_compat, mWindow, false);
+ final Drawable icon = StatusBarIconView.getIcon(mContext,
+ new StatusBarIcon(notification.pkg, n.icon, n.iconLevel, 0));
+ ImageView iv = (ImageView)group.findViewById(iconId);
+ iv.setImageDrawable(icon);
+ iv.setVisibility(View.VISIBLE);
TextView tv = (TextView)group.findViewById(R.id.text);
tv.setText(n.tickerText);
+ } else {
+ throw new RuntimeException("tickerView==null && tickerText==null");
}
-
- // No more than 2 icons.
- if (n.tickerIcons != null) {
- int N = n.tickerIcons.length;
- if (N > 2) {
- N = 2;
- }
- for (int i=N-1; i>= 0; i--) {
- Bitmap b = n.tickerIcons[i];
- if (b != null) {
- ImageView iv = (ImageView)inflater.inflate(R.layout.ticker_icon, group, false);
- iv.setImageBitmap(b);
- group.addView(iv, 0);
- }
- }
+ ImageView largeIcon = (ImageView)group.findViewById(R.id.large_icon);
+ if (n.largeIcon != null) {
+ largeIcon.setImageBitmap(n.largeIcon);
+ largeIcon.setVisibility(View.VISIBLE);
}
-
return group;
}
}
diff --git a/services/java/com/android/server/BatteryService.java b/services/java/com/android/server/BatteryService.java
index 40883bd..47599c8 100644
--- a/services/java/com/android/server/BatteryService.java
+++ b/services/java/com/android/server/BatteryService.java
@@ -473,10 +473,15 @@ class BatteryService extends Binder {
private final int getIcon(int level) {
if (mBatteryStatus == BatteryManager.BATTERY_STATUS_CHARGING) {
return com.android.internal.R.drawable.stat_sys_battery_charge;
- } else if (mBatteryStatus == BatteryManager.BATTERY_STATUS_DISCHARGING ||
- mBatteryStatus == BatteryManager.BATTERY_STATUS_NOT_CHARGING ||
- mBatteryStatus == BatteryManager.BATTERY_STATUS_FULL) {
+ } else if (mBatteryStatus == BatteryManager.BATTERY_STATUS_DISCHARGING) {
return com.android.internal.R.drawable.stat_sys_battery;
+ } else if (mBatteryStatus == BatteryManager.BATTERY_STATUS_NOT_CHARGING
+ || mBatteryStatus == BatteryManager.BATTERY_STATUS_FULL) {
+ if (isPowered() && mBatteryLevel >= 100) {
+ return com.android.internal.R.drawable.stat_sys_battery_charge;
+ } else {
+ return com.android.internal.R.drawable.stat_sys_battery;
+ }
} else {
return com.android.internal.R.drawable.stat_sys_battery_unknown;
}
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java
index 1081a20..6de7e6a 100755
--- a/services/java/com/android/server/NotificationManagerService.java
+++ b/services/java/com/android/server/NotificationManagerService.java
@@ -272,11 +272,13 @@ public class NotificationManagerService extends INotificationManager.Stub
public void onNotificationClick(String pkg, String tag, int id) {
cancelNotification(pkg, tag, id, Notification.FLAG_AUTO_CANCEL,
- Notification.FLAG_FOREGROUND_SERVICE);
+ Notification.FLAG_FOREGROUND_SERVICE, true);
}
public void onNotificationClear(String pkg, String tag, int id) {
- cancelNotification(pkg, tag, id, 0, 0); // maybe add some flags?
+ cancelNotification(pkg, tag, id, 0,
+ Notification.FLAG_ONGOING_EVENT | Notification.FLAG_FOREGROUND_SERVICE,
+ true);
}
public void onPanelRevealed() {
@@ -312,7 +314,7 @@ public class NotificationManagerService extends INotificationManager.Stub
int uid, int initialPid, String message) {
Slog.d(TAG, "onNotification error pkg=" + pkg + " tag=" + tag + " id=" + id
+ "; will crashApplication(uid=" + uid + ", pid=" + initialPid + ")");
- cancelNotification(pkg, tag, id, 0, 0);
+ cancelNotification(pkg, tag, id, 0, 0, false);
long ident = Binder.clearCallingIdentity();
try {
ActivityManagerNative.getDefault().crashApplication(uid, initialPid, pkg,
@@ -855,7 +857,20 @@ public class NotificationManagerService extends INotificationManager.Stub
manager.sendAccessibilityEvent(event);
}
- private void cancelNotificationLocked(NotificationRecord r) {
+ private void cancelNotificationLocked(NotificationRecord r, boolean sendDelete) {
+ // tell the app
+ if (sendDelete) {
+ if (r.notification.deleteIntent != null) {
+ try {
+ r.notification.deleteIntent.send();
+ } catch (PendingIntent.CanceledException ex) {
+ // do nothing - there's no relevant way to recover, and
+ // no reason to let this propagate
+ Slog.w(TAG, "canceled PendingIntent for " + r.pkg, ex);
+ }
+ }
+ }
+
// status bar
if (r.notification.icon != 0) {
long identity = Binder.clearCallingIdentity();
@@ -904,7 +919,7 @@ public class NotificationManagerService extends INotificationManager.Stub
* and none of the {@code mustNotHaveFlags}.
*/
private void cancelNotification(String pkg, String tag, int id, int mustHaveFlags,
- int mustNotHaveFlags) {
+ int mustNotHaveFlags, boolean sendDelete) {
EventLog.writeEvent(EventLogTags.NOTIFICATION_CANCEL, pkg, id, mustHaveFlags);
synchronized (mNotificationList) {
@@ -921,7 +936,7 @@ public class NotificationManagerService extends INotificationManager.Stub
mNotificationList.remove(index);
- cancelNotificationLocked(r);
+ cancelNotificationLocked(r, sendDelete);
updateLightsLocked();
}
}
@@ -954,7 +969,7 @@ public class NotificationManagerService extends INotificationManager.Stub
return true;
}
mNotificationList.remove(i);
- cancelNotificationLocked(r);
+ cancelNotificationLocked(r, false);
}
if (canceledSomething) {
updateLightsLocked();
@@ -973,7 +988,7 @@ public class NotificationManagerService extends INotificationManager.Stub
// Don't allow client applications to cancel foreground service notis.
cancelNotification(pkg, tag, id, 0,
Binder.getCallingUid() == Process.SYSTEM_UID
- ? 0 : Notification.FLAG_FOREGROUND_SERVICE);
+ ? 0 : Notification.FLAG_FOREGROUND_SERVICE, false);
}
public void cancelAllNotifications(String pkg) {
@@ -1009,17 +1024,8 @@ public class NotificationManagerService extends INotificationManager.Stub
if ((r.notification.flags & (Notification.FLAG_ONGOING_EVENT
| Notification.FLAG_NO_CLEAR)) == 0) {
- if (r.notification.deleteIntent != null) {
- try {
- r.notification.deleteIntent.send();
- } catch (PendingIntent.CanceledException ex) {
- // do nothing - there's no relevant way to recover, and
- // no reason to let this propagate
- Slog.w(TAG, "canceled PendingIntent for " + r.pkg, ex);
- }
- }
mNotificationList.remove(i);
- cancelNotificationLocked(r);
+ cancelNotificationLocked(r, true);
}
}
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index ec05437..0c20064 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -9354,7 +9354,7 @@ public class WindowManagerService extends IWindowManager.Stub
// If the window has moved due to its containing
// content frame changing, then we'd like to animate
// it. The checks here are ordered by what is least
- //Êlikely to be true first.
+ // likely to be true first.
if (w.mContentChanged && !wasAnimating && !w.mLastHidden && !mDisplayFrozen
&& (w.mFrame.top != w.mLastFrame.top
|| w.mFrame.left != w.mLastFrame.left)
diff --git a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
index 96c90a2..9c738ec 100644
--- a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
@@ -149,8 +149,6 @@ public abstract class DataConnectionTracker extends Handler {
/** Slow poll when attempting connection recovery. */
protected static final int POLL_NETSTAT_SLOW_MILLIS = 5000;
- /** Default ping deadline, in seconds. */
- protected static final int DEFAULT_PING_DEADLINE = 5;
/** Default max failure count before attempting to network re-registration. */
protected static final int DEFAULT_MAX_PDP_RESET_FAIL = 3;
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index 06c7c1b..bbfdd31 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -81,7 +81,6 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
private boolean mReregisterOnReconnectFailure = false;
private ContentResolver mResolver;
- private boolean mPingTestActive = false;
// Count of PDP reset attempts; reset when we see incoming,
// call reRegisterNetwork, or pingTest succeeds.
private int mPdpResetCount = 0;
@@ -654,7 +653,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
@Override
protected void startNetStatPoll() {
- if (mState == State.CONNECTED && mPingTestActive == false && mNetStatPollEnabled == false) {
+ if (mState == State.CONNECTED && mNetStatPollEnabled == false) {
log("[DataConnection] Start poll NetStat");
resetPollStats();
mNetStatPollEnabled = true;
@@ -763,18 +762,9 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
POLL_NETSTAT_SLOW_MILLIS);
} else {
if (DBG) log("Sent " + String.valueOf(mSentSinceLastRecv) +
- " pkts since last received");
- // We've exceeded the threshold. Run ping test as a final check;
- // it will proceed with recovery if ping fails.
+ " pkts since last received start recovery process");
stopNetStatPoll();
- Thread pingTest = new Thread() {
- @Override
- public void run() {
- runPingTest();
- }
- };
- mPingTestActive = true;
- pingTest.start();
+ sendMessage(obtainMessage(EVENT_START_RECOVERY));
}
} else {
mNoRecvPollCount = 0;
@@ -794,37 +784,6 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
}
};
- private void runPingTest () {
- int status = -1;
- try {
- String address = Settings.Secure.getString(mResolver,
- Settings.Secure.PDP_WATCHDOG_PING_ADDRESS);
- int deadline = Settings.Secure.getInt(mResolver,
- Settings.Secure.PDP_WATCHDOG_PING_DEADLINE, DEFAULT_PING_DEADLINE);
- if (DBG) log("pinging " + address + " for " + deadline + "s");
- if (address != null && !NULL_IP.equals(address)) {
- Process p = Runtime.getRuntime()
- .exec("ping -c 1 -i 1 -w "+ deadline + " " + address);
- status = p.waitFor();
- }
- } catch (IOException e) {
- loge("ping failed: IOException");
- } catch (Exception e) {
- loge("exception trying to ping");
- }
-
- if (status == 0) {
- // ping succeeded. False alarm. Reset netStatPoll.
- // ("-1" for this event indicates a false alarm)
- EventLog.writeEvent(EventLogTags.PDP_RADIO_RESET, -1);
- mPdpResetCount = 0;
- sendMessage(obtainMessage(EVENT_START_NETSTAT_POLL));
- } else {
- // ping failed. Proceed with recovery.
- sendMessage(obtainMessage(EVENT_START_RECOVERY));
- }
- }
-
/**
* Returns true if the last fail cause is something that
* seems like it deserves an error notification.
@@ -1399,12 +1358,10 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
break;
case EVENT_START_NETSTAT_POLL:
- mPingTestActive = false;
startNetStatPoll();
break;
case EVENT_START_RECOVERY:
- mPingTestActive = false;
doRecovery();
break;
diff --git a/test-runner/src/android/test/IsolatedContext.java b/test-runner/src/android/test/IsolatedContext.java
index b483b82..bc00f68 100644
--- a/test-runner/src/android/test/IsolatedContext.java
+++ b/test-runner/src/android/test/IsolatedContext.java
@@ -87,6 +87,11 @@ public class IsolatedContext extends ContextWrapper {
}
@Override
+ public void unregisterReceiver(BroadcastReceiver receiver) {
+ // Ignore
+ }
+
+ @Override
public void sendBroadcast(Intent intent) {
mBroadcastIntents.add(intent);
}
diff --git a/tests/StatusBar/AndroidManifest.xml b/tests/StatusBar/AndroidManifest.xml
index c1ca618..b1734bb 100644
--- a/tests/StatusBar/AndroidManifest.xml
+++ b/tests/StatusBar/AndroidManifest.xml
@@ -21,6 +21,13 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
+ <activity android:name="NotificationBuilderTest" android:label="_Notify Builder">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
<activity android:name="ToastTest" android:label="_Toasts">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
@@ -35,6 +42,8 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
+ <activity android:name="ConfirmationActivity" android:theme="@android:style/Theme.Dialog">
+ </activity>
<activity android:name="TestAlertActivity" android:theme="@android:style/Theme.Dialog">
</activity>
</application>
diff --git a/tests/StatusBar/res/drawable-mdpi/pineapple.png b/tests/StatusBar/res/drawable-mdpi/pineapple.png
new file mode 100644
index 0000000..7377b96
--- /dev/null
+++ b/tests/StatusBar/res/drawable-mdpi/pineapple.png
Binary files differ
diff --git a/tests/StatusBar/res/layout/confirmation_activity.xml b/tests/StatusBar/res/layout/confirmation_activity.xml
new file mode 100644
index 0000000..50d1a49
--- /dev/null
+++ b/tests/StatusBar/res/layout/confirmation_activity.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:gravity="center_horizontal"
+ android:orientation="vertical"
+ >
+
+ <TextView android:id="@+id/text"
+ style="?android:attr/textAppearanceLarge"
+ android:padding="5dip"
+ android:singleLine="true"
+ android:ellipsize="end"
+ android:gravity="center"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <Button
+ android:id="@+id/ok"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="3"
+ android:onClick="dismiss"
+ android:text="Ok" />
+
+</LinearLayout>
diff --git a/tests/StatusBar/src/com/android/statusbartest/ConfirmationActivity.java b/tests/StatusBar/src/com/android/statusbartest/ConfirmationActivity.java
new file mode 100644
index 0000000..5ce8f3f
--- /dev/null
+++ b/tests/StatusBar/src/com/android/statusbartest/ConfirmationActivity.java
@@ -0,0 +1,32 @@
+package com.android.statusbartest;
+
+import android.app.Activity;
+import android.view.View;
+import android.widget.TextView;
+
+public class ConfirmationActivity extends Activity {
+ public static final String EXTRA_TITLE = "title";
+ public static final String EXTRA_TEXT = "text";
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ setContentView(R.layout.confirmation_activity);
+ setTitle(getTextExtra(EXTRA_TITLE, "Title"));
+ ((TextView)findViewById(R.id.text)).setText(getTextExtra(EXTRA_TEXT, "text"));
+ findViewById(R.id.ok).setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ finish();
+ }
+ });
+ }
+
+ private String getTextExtra(String extra, String def) {
+ final String text = getIntent().getStringExtra(extra);
+ if (text == null) {
+ return def;
+ } else {
+ return text;
+ }
+ }
+}
diff --git a/tests/StatusBar/src/com/android/statusbartest/NotificationBuilderTest.java b/tests/StatusBar/src/com/android/statusbartest/NotificationBuilderTest.java
new file mode 100644
index 0000000..3c26212
--- /dev/null
+++ b/tests/StatusBar/src/com/android/statusbartest/NotificationBuilderTest.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.statusbartest;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.ContentResolver;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
+import android.net.Uri;
+import android.os.Environment;
+import android.os.Vibrator;
+import android.os.Handler;
+import android.util.Log;
+import android.net.Uri;
+import android.os.SystemClock;
+import android.widget.RemoteViews;
+import android.os.PowerManager;
+
+public class NotificationBuilderTest extends TestActivity
+{
+ private final static String TAG = "NotificationTestList";
+
+ NotificationManager mNM;
+
+ @Override
+ protected String tag() {
+ return TAG;
+ }
+
+ @Override
+ protected Test[] tests() {
+ mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
+
+ return mTests;
+ }
+
+ private Test[] mTests = new Test[] {
+ new Test("Cancel (1)") {
+ public void run() {
+ mNM.cancel(1);
+ }
+ },
+
+ new Test("Basic Content (1)") {
+ public void run() {
+ int id = 1;
+ final Notification.Builder b = makeBasicBuilder(this, id);
+
+ mNM.notify(id, b.getNotification());
+ }
+ },
+
+ new Test("Content w/ Info (1)") {
+ public void run() {
+ int id = 1;
+ final Notification.Builder b = makeBasicBuilder(this, id);
+
+ b.setContentInfo("Snoozed");
+
+ mNM.notify(id, b.getNotification());
+ }
+ },
+
+ new Test("w/ Number (1)") {
+ public void run() {
+ int id = 1;
+ final Notification.Builder b = makeBasicBuilder(this, id);
+
+ b.setNumber(12345);
+
+ mNM.notify(id, b.getNotification());
+ }
+ },
+
+ new Test("w/ Number and Large Icon (1)") {
+ public void run() {
+ int id = 1;
+ final Notification.Builder b = makeBasicBuilder(this, id);
+
+ b.setNumber(42);
+
+ final BitmapDrawable bd = (BitmapDrawable)getResources().getDrawable(
+ R.drawable.pineapple);
+ b.setLargeIcon(Bitmap.createBitmap(bd.getBitmap()));
+
+ mNM.notify(id, b.getNotification());
+ }
+ },
+ };
+
+ private Notification.Builder makeBasicBuilder(Test t, int id) {
+ final Notification.Builder b = new Notification.Builder(this);
+
+ b.setWhen(System.currentTimeMillis());
+ b.setSmallIcon(R.drawable.ic_statusbar_chat);
+ b.setContentTitle("Notification builder Test");
+ b.setContentText(t.name + "\nhappy notifying");
+ b.setContentIntent(makeContentIntent(id));
+ b.setDeleteIntent(makeDeleteIntent(id));
+
+ return b;
+ }
+
+ private PendingIntent makeContentIntent(int id) {
+ Intent intent = new Intent(this, ConfirmationActivity.class);
+ intent.setData(Uri.fromParts("content", "//status_bar_test/content/" + id, null));
+ intent.putExtra(ConfirmationActivity.EXTRA_TITLE, "Content intent");
+ intent.putExtra(ConfirmationActivity.EXTRA_TEXT, "id: " + id);
+ return PendingIntent.getActivity(this, 0, intent, 0);
+ }
+
+ private PendingIntent makeDeleteIntent(int id) {
+ Intent intent = new Intent(this, ConfirmationActivity.class);
+ intent.setData(Uri.fromParts("content", "//status_bar_test/delete/" + id, null));
+ intent.putExtra(ConfirmationActivity.EXTRA_TITLE, "Delete intent");
+ intent.putExtra(ConfirmationActivity.EXTRA_TEXT, "id: " + id);
+ return PendingIntent.getActivity(this, 0, intent, 0);
+ }
+}
+
diff --git a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
index 2df97dc..0f0637f 100644
--- a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
+++ b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
@@ -135,95 +135,6 @@ public class NotificationTestList extends TestActivity
}
},
- new Test("Ticker 1 line & icon") {
- public void run() {
- Notification n = new Notification(R.drawable.icon1, "tick tick tick",
- mActivityCreateTime);
- n.setLatestEventInfo(NotificationTestList.this, "Persistent #1",
- "This is a notification!!!", makeIntent());
- n.tickerIcons = new Bitmap[1];
- n.tickerIcons[0] = loadBitmap(R.drawable.icon3);
- mNM.notify(1, n);
- }
- },
-
- new Test("Ticker 2 lines") {
- public void run() {
- Notification n = new Notification(R.drawable.icon1, "tick tick tick\ntock tock",
- mActivityCreateTime);
- n.setLatestEventInfo(NotificationTestList.this, "Persistent #1",
- "This is a notification!!!", makeIntent());
- mNM.notify(1, n);
- }
- },
-
- new Test("Ticker title") {
- public void run() {
- Notification n = new Notification(R.drawable.icon1, null,
- mActivityCreateTime);
- n.setLatestEventInfo(NotificationTestList.this, "Persistent #1",
- "This is a notification!!!", makeIntent());
- n.tickerTitle = "This is a title";
- mNM.notify(1, n);
- }
- },
-
- new Test("Ticker subtitle") {
- public void run() {
- Notification n = new Notification(R.drawable.icon1, null,
- mActivityCreateTime);
- n.setLatestEventInfo(NotificationTestList.this, "Persistent #1",
- "This is a notification!!!", makeIntent());
- n.tickerSubtitle = "and a subtitle";
- mNM.notify(1, n);
- }
- },
-
- new Test("Ticker title & subtitle") {
- public void run() {
- Notification n = new Notification(R.drawable.icon1, null,
- mActivityCreateTime);
- n.setLatestEventInfo(NotificationTestList.this, "Persistent #1",
- "This is a notification!!!", makeIntent());
- n.tickerTitle = "This is a title it is really really longggggg long long long long";
- n.tickerSubtitle = "and a subtitle it is really really longggggg long long long long long long long long long long long long long long long long";
- mNM.notify(1, n);
- }
- },
-
- new Test("Ticker text, title & subtitle") {
- public void run() {
- Notification n = new Notification(R.drawable.icon1, "not visible",
- mActivityCreateTime);
- n.setLatestEventInfo(NotificationTestList.this, "Persistent #1",
- "This is a notification!!!", makeIntent());
- n.tickerTitle = "This is a title";
- n.tickerSubtitle = "and a subtitle";
- mNM.notify(1, n);
- }
- },
-
- new Test("Ticker title, subtitle & 2 icons") {
- public void run() {
- Notification n = new Notification(R.drawable.icon1, null,
- mActivityCreateTime);
- n.setLatestEventInfo(NotificationTestList.this, "Persistent #1",
- "This is a notification!!!", makeIntent());
- n.tickerTitle = "This is a title";
- n.tickerSubtitle = "and a subtitle";
-
- n.tickerIcons = new Bitmap[2];
- n.tickerIcons[0] = loadBitmap(R.drawable.icon3);
- n.tickerIcons[1] = loadBitmap(R.drawable.app_gmail);
-
- mNM.notify(1, n);
- /*
- n.tickerIcons[0].recycle();
- n.tickerIcons[1].recycle();
- */
- }
- },
-
new Test("No view") {
public void run() {
Notification n = new Notification(R.drawable.icon1, "No view",