summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.xml110
-rw-r--r--cmds/stagefright/record.cpp60
-rw-r--r--core/java/android/app/ActivityThread.java11
-rw-r--r--core/java/android/database/sqlite/SQLiteDebug.java2
-rw-r--r--core/java/android/os/RecoverySystem.java15
-rw-r--r--core/java/android/provider/Downloads.java8
-rw-r--r--core/java/android/provider/Settings.java9
-rw-r--r--core/java/android/webkit/WebView.java19
-rw-r--r--[-rwxr-xr-x]core/res/res/drawable-hdpi/btn_circle_disable.pngbin2601 -> 2727 bytes
-rw-r--r--[-rwxr-xr-x]core/res/res/drawable-hdpi/btn_circle_disable_focused.pngbin2729 -> 2330 bytes
-rw-r--r--[-rwxr-xr-x]core/res/res/drawable-hdpi/expander_ic_maximized.9.pngbin2993 -> 2955 bytes
-rw-r--r--[-rwxr-xr-x]core/res/res/drawable-hdpi/expander_ic_minimized.9.pngbin2955 -> 2993 bytes
-rw-r--r--core/res/res/drawable-hdpi/jog_tab_left_confirm_gray.pngbin6964 -> 5415 bytes
-rw-r--r--core/res/res/drawable-hdpi/jog_tab_left_confirm_green.pngbin11428 -> 5929 bytes
-rw-r--r--core/res/res/drawable-hdpi/jog_tab_left_confirm_yellow.pngbin11501 -> 5861 bytes
-rw-r--r--core/res/res/drawable-hdpi/jog_tab_left_normal.pngbin10304 -> 5013 bytes
-rw-r--r--core/res/res/drawable-hdpi/jog_tab_left_pressed.pngbin9897 -> 5240 bytes
-rw-r--r--core/res/res/drawable-hdpi/jog_tab_right_confirm_gray.pngbin6402 -> 5297 bytes
-rw-r--r--core/res/res/drawable-hdpi/jog_tab_right_confirm_green.pngbin10627 -> 5735 bytes
-rw-r--r--core/res/res/drawable-hdpi/jog_tab_right_confirm_yellow.pngbin10912 -> 5681 bytes
-rw-r--r--core/res/res/drawable-hdpi/jog_tab_right_normal.pngbin9768 -> 4765 bytes
-rw-r--r--core/res/res/drawable-hdpi/jog_tab_right_pressed.pngbin9250 -> 5039 bytes
-rw-r--r--[-rwxr-xr-x]core/res/res/drawable-hdpi/popup_center_dark.9.pngbin1139 -> 1151 bytes
-rw-r--r--[-rwxr-xr-x]core/res/res/drawable-hdpi/stat_notify_chat.pngbin1663 -> 1625 bytes
-rw-r--r--core/res/res/drawable-mdpi/expander_ic_maximized.9.pngbin1150 -> 1929 bytes
-rw-r--r--core/res/res/drawable-mdpi/expander_ic_minimized.9.pngbin1167 -> 1982 bytes
-rw-r--r--core/res/res/drawable-mdpi/jog_tab_left_confirm_gray.pngbin4306 -> 4963 bytes
-rw-r--r--core/res/res/drawable-mdpi/jog_tab_left_confirm_green.pngbin6753 -> 5516 bytes
-rw-r--r--core/res/res/drawable-mdpi/jog_tab_left_confirm_yellow.pngbin6879 -> 5310 bytes
-rw-r--r--core/res/res/drawable-mdpi/jog_tab_left_normal.pngbin6227 -> 4204 bytes
-rw-r--r--core/res/res/drawable-mdpi/jog_tab_left_pressed.pngbin5994 -> 4399 bytes
-rw-r--r--core/res/res/drawable-mdpi/jog_tab_right_confirm_gray.pngbin3959 -> 4887 bytes
-rw-r--r--core/res/res/drawable-mdpi/jog_tab_right_confirm_green.pngbin6278 -> 5472 bytes
-rw-r--r--core/res/res/drawable-mdpi/jog_tab_right_confirm_yellow.pngbin6392 -> 5181 bytes
-rw-r--r--core/res/res/drawable-mdpi/jog_tab_right_normal.pngbin5750 -> 4135 bytes
-rw-r--r--core/res/res/drawable-mdpi/jog_tab_right_pressed.pngbin5626 -> 4221 bytes
-rw-r--r--core/tests/coretests/AndroidManifest.xml1
-rw-r--r--core/tests/coretests/src/android/net/DownloadManagerBaseTest.java31
-rw-r--r--core/tests/coretests/src/android/net/DownloadManagerIntegrationTest.java264
-rw-r--r--core/tests/hosttests/src/android/net/DownloadManagerHostTests.java27
-rw-r--r--core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/DownloadManagerTestApp.java57
-rw-r--r--core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/DownloadManagerTestRunner.java2
-rw-r--r--media/java/android/media/AudioEffect.java68
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_3g.pngbin4228 -> 1732 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_3g_fully.pngbin4240 -> 1742 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_data_in_3g.pngbin4423 -> 1861 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_data_in_3g_fully.pngbin4458 -> 1896 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_data_inandout_3g.pngbin4515 -> 1911 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_data_inandout_3g_fully.pngbin4534 -> 1966 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_data_out_3g.pngbin4429 -> 1891 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_data_out_3g_fully.pngbin4454 -> 1917 bytes
-rw-r--r--services/java/com/android/server/WifiService.java33
-rw-r--r--wifi/java/android/net/wifi/IWifiManager.aidl2
-rw-r--r--wifi/java/android/net/wifi/WifiManager.java6
54 files changed, 601 insertions, 124 deletions
diff --git a/api/current.xml b/api/current.xml
index e6df68759a79..1d6feb5d6ff3 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -84729,6 +84729,39 @@
<parameter name="value" type="short">
</parameter>
</method>
+<field name="ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.media.action.CLOSE_AUDIO_EFFECT_CONTROL_SESSION&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.media.action.DISPLAY_AUDIO_EFFECT_CONTROL_PANEL&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.media.action.OPEN_AUDIO_EFFECT_CONTROL_SESSION&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="ALREADY_EXISTS"
type="int"
transient="false"
@@ -84740,6 +84773,50 @@
visibility="public"
>
</field>
+<field name="CONTENT_TYPE_GAME"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="CONTENT_TYPE_MOVIE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="CONTENT_TYPE_MUSIC"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="0"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="CONTENT_TYPE_VOICE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="3"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="EFFECT_AUXILIARY"
type="java.lang.String"
transient="false"
@@ -84888,6 +84965,39 @@
visibility="public"
>
</field>
+<field name="EXTRA_AUDIO_SESSION"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.media.extra.AUDIO_SESSION&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_CONTENT_TYPE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.media.extra.CONTENT_TYPE&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_PACKAGE_NAME"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.media.extra.PACKAGE_NAME&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="NATIVE_EVENT_CONTROL_STATUS"
type="int"
transient="false"
diff --git a/cmds/stagefright/record.cpp b/cmds/stagefright/record.cpp
index c4242817bf4e..b7182991eaea 100644
--- a/cmds/stagefright/record.cpp
+++ b/cmds/stagefright/record.cpp
@@ -36,24 +36,30 @@ static const int32_t kFramerate = 24; // fps
static const int32_t kIFramesIntervalSec = 1;
static const int32_t kVideoBitRate = 512 * 1024;
static const int32_t kAudioBitRate = 12200;
-static const int32_t kColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
static const int64_t kDurationUs = 10000000LL; // 10 seconds
#if 1
class DummySource : public MediaSource {
public:
- DummySource(int width, int height)
+ DummySource(int width, int height, int colorFormat)
: mWidth(width),
mHeight(height),
+ mColorFormat(colorFormat),
mSize((width * height * 3) / 2) {
mGroup.add_buffer(new MediaBuffer(mSize));
+
+ // Check the color format to make sure
+ // that the buffer size mSize it set correctly above.
+ CHECK(colorFormat == OMX_COLOR_FormatYUV420SemiPlanar ||
+ colorFormat == OMX_COLOR_FormatYUV420Planar);
}
virtual sp<MetaData> getFormat() {
sp<MetaData> meta = new MetaData;
meta->setInt32(kKeyWidth, mWidth);
meta->setInt32(kKeyHeight, mHeight);
+ meta->setInt32(kKeyColorFormat, mColorFormat);
meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
return meta;
@@ -100,6 +106,7 @@ protected:
private:
MediaBufferGroup mGroup;
int mWidth, mHeight;
+ int mColorFormat;
size_t mSize;
int64_t mNumFramesOutput;;
@@ -139,20 +146,47 @@ sp<MediaSource> createSource(const char *filename) {
return source;
}
+enum {
+ kYUV420SP = 0,
+ kYUV420P = 1,
+};
+
+// returns -1 if mapping of the given color is unsuccessful
+// returns an omx color enum value otherwise
+static int translateColorToOmxEnumValue(int color) {
+ switch (color) {
+ case kYUV420SP:
+ return OMX_COLOR_FormatYUV420SemiPlanar;
+ case kYUV420P:
+ return OMX_COLOR_FormatYUV420Planar;
+ default:
+ fprintf(stderr, "Unsupported color: %d\n", color);
+ return -1;
+ }
+}
+
int main(int argc, char **argv) {
android::ProcessState::self()->startThreadPool();
DataSource::RegisterDefaultSniffers();
#if 1
- if (argc != 2) {
- fprintf(stderr, "usage: %s filename\n", argv[0]);
+ if (argc != 3) {
+ fprintf(stderr, "usage: %s <filename> <input_color_format>\n", argv[0]);
+ fprintf(stderr, " <input_color_format>: 0 (YUV420SP) or 1 (YUV420P)\n");
return 1;
}
+ int colorFormat = translateColorToOmxEnumValue(atoi(argv[2]));
+ if (colorFormat == -1) {
+ fprintf(stderr, "input color format must be 0 (YUV420SP) or 1 (YUV420P)\n");
+ return 1;
+ }
OMXClient client;
CHECK_EQ(client.connect(), OK);
+ status_t err = OK;
+
#if 0
sp<MediaSource> source = createSource(argv[1]);
@@ -173,7 +207,7 @@ int main(int argc, char **argv) {
#else
int width = 720;
int height = 480;
- sp<MediaSource> decoder = new DummySource(width, height);
+ sp<MediaSource> decoder = new DummySource(width, height, colorFormat);
#endif
sp<MetaData> enc_meta = new MetaData;
@@ -187,7 +221,7 @@ int main(int argc, char **argv) {
enc_meta->setInt32(kKeyStride, width);
enc_meta->setInt32(kKeySliceHeight, height);
enc_meta->setInt32(kKeyIFramesInterval, kIFramesIntervalSec);
- enc_meta->setInt32(kKeyColorFormat, kColorFormat);
+ enc_meta->setInt32(kKeyColorFormat, colorFormat);
sp<MediaSource> encoder =
OMXCodec::Create(
@@ -197,14 +231,14 @@ int main(int argc, char **argv) {
sp<MPEG4Writer> writer = new MPEG4Writer("/sdcard/output.mp4");
writer->addSource(encoder);
writer->setMaxFileDuration(kDurationUs);
- writer->start();
+ CHECK_EQ(OK, writer->start());
while (!writer->reachedEOS()) {
fprintf(stderr, ".");
usleep(100000);
}
- writer->stop();
+ err = writer->stop();
#else
- encoder->start();
+ CHECK_EQ(OK, encoder->start());
MediaBuffer *buffer;
while (encoder->read(&buffer) == OK) {
@@ -222,7 +256,7 @@ int main(int argc, char **argv) {
buffer = NULL;
}
- encoder->stop();
+ err = encoder->stop();
#endif
printf("$\n");
@@ -247,12 +281,16 @@ int main(int argc, char **argv) {
buffer = NULL;
}
- source->stop();
+ err = source->stop();
delete source;
source = NULL;
#endif
+ if (err != OK && err != ERROR_END_OF_STREAM) {
+ fprintf(stderr, "record failed: %d\n", err);
+ return 1;
+ }
return 0;
}
#else
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index d8b525346362..3c7bebfa5d7b 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -363,7 +363,8 @@ public final class ActivityThread {
private static final String HEAP_COLUMN = "%17s %8s %8s %8s %8s";
private static final String ONE_COUNT_COLUMN = "%17s %8d";
private static final String TWO_COUNT_COLUMNS = "%17s %8d %17s %8d";
- private static final String DB_INFO_FORMAT = " %8d %8d %10d %s";
+ private static final String TWO_COUNT_COLUMNS_DB = "%20s %8d %20s %8d";
+ private static final String DB_INFO_FORMAT = " %8d %8d %14d %s";
// Formatting for checkin service - update version if row format changes
private static final int ACTIVITY_THREAD_CHECKIN_VERSION = 1;
@@ -806,15 +807,15 @@ public final class ActivityThread {
// SQLite mem info
pw.println(" ");
pw.println(" SQL");
- printRow(pw, TWO_COUNT_COLUMNS, "heap:", sqliteAllocated, "memoryUsed:",
+ printRow(pw, TWO_COUNT_COLUMNS_DB, "heap:", sqliteAllocated, "MEMORY_USED:",
stats.memoryUsed / 1024);
- printRow(pw, TWO_COUNT_COLUMNS, "pageCacheOverflo:", stats.pageCacheOverflo / 1024,
- "largestMemAlloc:", stats.largestMemAlloc / 1024);
+ printRow(pw, TWO_COUNT_COLUMNS_DB, "PAGECACHE_OVERFLOW:",
+ stats.pageCacheOverflo / 1024, "MALLOC_SIZE:", stats.largestMemAlloc / 1024);
pw.println(" ");
int N = stats.dbStats.size();
if (N > 0) {
pw.println(" DATABASES");
- printRow(pw, " %8s %8s %10s %s", "Pagesize", "Dbsize", "Lookaside", "Dbname");
+ printRow(pw, " %8s %8s %14s %s", "pgsz", "dbsz", "Lookaside(b)", "Dbname");
for (int i = 0; i < N; i++) {
DbStats dbStats = stats.dbStats.get(i);
printRow(pw, DB_INFO_FORMAT, dbStats.pageSize, dbStats.dbSize,
diff --git a/core/java/android/database/sqlite/SQLiteDebug.java b/core/java/android/database/sqlite/SQLiteDebug.java
index 89c3f96a7783..b2a166b06fdf 100644
--- a/core/java/android/database/sqlite/SQLiteDebug.java
+++ b/core/java/android/database/sqlite/SQLiteDebug.java
@@ -134,7 +134,7 @@ public final class SQLiteDebug {
public DbStats(String dbName, long pageCount, long pageSize, int lookaside) {
this.dbName = dbName;
- this.pageSize = pageSize;
+ this.pageSize = pageSize / 1024;
dbSize = (pageCount * pageSize) / 1024;
this.lookaside = lookaside;
}
diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java
index 5fea6fec453f..e56e25774d0f 100644
--- a/core/java/android/os/RecoverySystem.java
+++ b/core/java/android/os/RecoverySystem.java
@@ -307,8 +307,10 @@ public class RecoverySystem {
* Requires the {@link android.Manifest.permission#REBOOT} permission.
*
* @param context the Context to use
- * @param packageFile the update package to install. Currently
- * must be on the /cache or /data partitions.
+ * @param packageFile the update package to install. Must be on
+ * a partition mountable by recovery. (The set of partitions
+ * known to recovery may vary from device to device. Generally,
+ * /cache and /data are safe.)
*
* @throws IOException if writing the recovery command file
* fails, or if the reboot itself fails.
@@ -316,15 +318,6 @@ public class RecoverySystem {
public static void installPackage(Context context, File packageFile)
throws IOException {
String filename = packageFile.getCanonicalPath();
-
- if (filename.startsWith("/cache/")) {
- filename = "CACHE:" + filename.substring(7);
- } else if (filename.startsWith("/data/")) {
- filename = "DATA:" + filename.substring(6);
- } else {
- throw new IllegalArgumentException(
- "Must start with /cache or /data: " + filename);
- }
Log.w(TAG, "!!! REBOOTING TO INSTALL " + filename + " !!!");
String arg = "--update_package=" + filename;
bootCommand(context, arg);
diff --git a/core/java/android/provider/Downloads.java b/core/java/android/provider/Downloads.java
index 871a04413f6e..1e358c9d0281 100644
--- a/core/java/android/provider/Downloads.java
+++ b/core/java/android/provider/Downloads.java
@@ -895,6 +895,14 @@ public final class Downloads {
*/
public static final String COLUMN_IS_VISIBLE_IN_DOWNLOADS_UI = "is_visible_in_downloads_ui";
+ /**
+ * If true, the user has confirmed that this download can proceed over the mobile network
+ * even though it exceeds the recommended maximum size.
+ * <P>Type: BOOLEAN</P>
+ */
+ public static final String COLUMN_BYPASS_RECOMMENDED_SIZE_LIMIT =
+ "bypass_recommended_size_limit";
+
/*
* Lists the destinations that an application can specify for a download.
*/
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index fd601159981d..69151dff34d0 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3428,6 +3428,15 @@ public final class Settings {
"download_manager_max_bytes_over_mobile";
/**
+ * The recommended maximum size, in bytes, of a download that the download manager should
+ * transfer over a non-wifi connection. Over this size, the use will be warned, but will
+ * have the option to start the download over the mobile connection anyway.
+ * @hide
+ */
+ public static final String DOWNLOAD_RECOMMENDED_MAX_BYTES_OVER_MOBILE =
+ "download_manager_recommended_max_bytes_over_mobile";
+
+ /**
* ms during which to consume extra events related to Inet connection condition
* after a transtion to fully-connected
* @hide
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 456e0d9dd6e2..c9835a01003f 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -1284,13 +1284,18 @@ public class WebView extends AbsoluteLayout
return mDatabase.getHttpAuthUsernamePassword(host, realm);
}
+ private void clearHelpers() {
+ clearTextEntry(false);
+ selectionDone();
+ }
+
/**
* Destroy the internal state of the WebView. This method should be called
* after the WebView has been removed from the view system. No other
* methods may be called on a WebView after destroy.
*/
public void destroy() {
- clearTextEntry(false);
+ clearHelpers();
if (mWebViewCore != null) {
// Set the handlers to null before destroying WebViewCore so no
// more messages will be posted.
@@ -1608,7 +1613,7 @@ public class WebView extends AbsoluteLayout
arg.mUrl = url;
arg.mExtraHeaders = extraHeaders;
mWebViewCore.sendMessage(EventHub.LOAD_URL, arg);
- clearTextEntry(false);
+ clearHelpers();
}
/**
@@ -1637,7 +1642,7 @@ public class WebView extends AbsoluteLayout
arg.mUrl = url;
arg.mPostData = postData;
mWebViewCore.sendMessage(EventHub.POST_URL, arg);
- clearTextEntry(false);
+ clearHelpers();
} else {
loadUrl(url);
}
@@ -1693,7 +1698,7 @@ public class WebView extends AbsoluteLayout
arg.mEncoding = encoding;
arg.mHistoryUrl = historyUrl;
mWebViewCore.sendMessage(EventHub.LOAD_DATA, arg);
- clearTextEntry(false);
+ clearHelpers();
}
/**
@@ -1710,7 +1715,7 @@ public class WebView extends AbsoluteLayout
* Reload the current url.
*/
public void reload() {
- clearTextEntry(false);
+ clearHelpers();
switchOutDrawHistory();
mWebViewCore.sendMessage(EventHub.RELOAD);
}
@@ -1790,7 +1795,7 @@ public class WebView extends AbsoluteLayout
private void goBackOrForward(int steps, boolean ignoreSnapshot) {
if (steps != 0) {
- clearTextEntry(false);
+ clearHelpers();
mWebViewCore.sendMessage(EventHub.GO_BACK_FORWARD, steps,
ignoreSnapshot ? 1 : 0);
}
@@ -4421,7 +4426,7 @@ public class WebView extends AbsoluteLayout
@Override
protected void onDetachedFromWindow() {
- clearTextEntry(false);
+ clearHelpers();
dismissZoomControl();
if (hasWindowFocus()) setActive(false);
super.onDetachedFromWindow();
diff --git a/core/res/res/drawable-hdpi/btn_circle_disable.png b/core/res/res/drawable-hdpi/btn_circle_disable.png
index 3f859cb57a64..39652a855800 100755..100644
--- a/core/res/res/drawable-hdpi/btn_circle_disable.png
+++ b/core/res/res/drawable-hdpi/btn_circle_disable.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_circle_disable_focused.png b/core/res/res/drawable-hdpi/btn_circle_disable_focused.png
index 66251b87bb74..1aa7ffe69b11 100755..100644
--- a/core/res/res/drawable-hdpi/btn_circle_disable_focused.png
+++ b/core/res/res/drawable-hdpi/btn_circle_disable_focused.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/expander_ic_maximized.9.png b/core/res/res/drawable-hdpi/expander_ic_maximized.9.png
index 0c19bb782a60..2ec27afa7725 100755..100644
--- a/core/res/res/drawable-hdpi/expander_ic_maximized.9.png
+++ b/core/res/res/drawable-hdpi/expander_ic_maximized.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/expander_ic_minimized.9.png b/core/res/res/drawable-hdpi/expander_ic_minimized.9.png
index 2ec27afa7725..0c19bb782a60 100755..100644
--- a/core/res/res/drawable-hdpi/expander_ic_minimized.9.png
+++ b/core/res/res/drawable-hdpi/expander_ic_minimized.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/jog_tab_left_confirm_gray.png b/core/res/res/drawable-hdpi/jog_tab_left_confirm_gray.png
index 34992082225d..f8dc42ae1a24 100644
--- a/core/res/res/drawable-hdpi/jog_tab_left_confirm_gray.png
+++ b/core/res/res/drawable-hdpi/jog_tab_left_confirm_gray.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/jog_tab_left_confirm_green.png b/core/res/res/drawable-hdpi/jog_tab_left_confirm_green.png
index 91eaec88c243..92b24b0d9fdf 100644
--- a/core/res/res/drawable-hdpi/jog_tab_left_confirm_green.png
+++ b/core/res/res/drawable-hdpi/jog_tab_left_confirm_green.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/jog_tab_left_confirm_yellow.png b/core/res/res/drawable-hdpi/jog_tab_left_confirm_yellow.png
index e5bc5f69a9b0..8208b20d6697 100644
--- a/core/res/res/drawable-hdpi/jog_tab_left_confirm_yellow.png
+++ b/core/res/res/drawable-hdpi/jog_tab_left_confirm_yellow.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/jog_tab_left_normal.png b/core/res/res/drawable-hdpi/jog_tab_left_normal.png
index 5326c7c4f0c7..4c877434b915 100644
--- a/core/res/res/drawable-hdpi/jog_tab_left_normal.png
+++ b/core/res/res/drawable-hdpi/jog_tab_left_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/jog_tab_left_pressed.png b/core/res/res/drawable-hdpi/jog_tab_left_pressed.png
index 7b906dfe147b..150c73507e3f 100644
--- a/core/res/res/drawable-hdpi/jog_tab_left_pressed.png
+++ b/core/res/res/drawable-hdpi/jog_tab_left_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/jog_tab_right_confirm_gray.png b/core/res/res/drawable-hdpi/jog_tab_right_confirm_gray.png
index ea8c3157f173..11ab30c10f4f 100644
--- a/core/res/res/drawable-hdpi/jog_tab_right_confirm_gray.png
+++ b/core/res/res/drawable-hdpi/jog_tab_right_confirm_gray.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/jog_tab_right_confirm_green.png b/core/res/res/drawable-hdpi/jog_tab_right_confirm_green.png
index aa0ceb943dbd..a9122855b24d 100644
--- a/core/res/res/drawable-hdpi/jog_tab_right_confirm_green.png
+++ b/core/res/res/drawable-hdpi/jog_tab_right_confirm_green.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/jog_tab_right_confirm_yellow.png b/core/res/res/drawable-hdpi/jog_tab_right_confirm_yellow.png
index 3cfeb67e6e63..0dd84fa487b2 100644
--- a/core/res/res/drawable-hdpi/jog_tab_right_confirm_yellow.png
+++ b/core/res/res/drawable-hdpi/jog_tab_right_confirm_yellow.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/jog_tab_right_normal.png b/core/res/res/drawable-hdpi/jog_tab_right_normal.png
index da7726b262cf..e0f1a0a04876 100644
--- a/core/res/res/drawable-hdpi/jog_tab_right_normal.png
+++ b/core/res/res/drawable-hdpi/jog_tab_right_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/jog_tab_right_pressed.png b/core/res/res/drawable-hdpi/jog_tab_right_pressed.png
index 450a325b27aa..f41d6f59c5fc 100644
--- a/core/res/res/drawable-hdpi/jog_tab_right_pressed.png
+++ b/core/res/res/drawable-hdpi/jog_tab_right_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/popup_center_dark.9.png b/core/res/res/drawable-hdpi/popup_center_dark.9.png
index e2e983f3f0a2..ac1f92dfff88 100755..100644
--- a/core/res/res/drawable-hdpi/popup_center_dark.9.png
+++ b/core/res/res/drawable-hdpi/popup_center_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_notify_chat.png b/core/res/res/drawable-hdpi/stat_notify_chat.png
index 097a979a5c7b..71ea8de6b682 100755..100644
--- a/core/res/res/drawable-hdpi/stat_notify_chat.png
+++ b/core/res/res/drawable-hdpi/stat_notify_chat.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/expander_ic_maximized.9.png b/core/res/res/drawable-mdpi/expander_ic_maximized.9.png
index 465cabd7e929..d5c32766cece 100644
--- a/core/res/res/drawable-mdpi/expander_ic_maximized.9.png
+++ b/core/res/res/drawable-mdpi/expander_ic_maximized.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/expander_ic_minimized.9.png b/core/res/res/drawable-mdpi/expander_ic_minimized.9.png
index 9967ecbd6c1e..4515b42177bb 100644
--- a/core/res/res/drawable-mdpi/expander_ic_minimized.9.png
+++ b/core/res/res/drawable-mdpi/expander_ic_minimized.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/jog_tab_left_confirm_gray.png b/core/res/res/drawable-mdpi/jog_tab_left_confirm_gray.png
index e8544ff9515a..b5d3290b4a9b 100644
--- a/core/res/res/drawable-mdpi/jog_tab_left_confirm_gray.png
+++ b/core/res/res/drawable-mdpi/jog_tab_left_confirm_gray.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/jog_tab_left_confirm_green.png b/core/res/res/drawable-mdpi/jog_tab_left_confirm_green.png
index d0ba8f8fbed5..e4cff64100f5 100644
--- a/core/res/res/drawable-mdpi/jog_tab_left_confirm_green.png
+++ b/core/res/res/drawable-mdpi/jog_tab_left_confirm_green.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/jog_tab_left_confirm_yellow.png b/core/res/res/drawable-mdpi/jog_tab_left_confirm_yellow.png
index 861e17a7f173..d50181447e01 100644
--- a/core/res/res/drawable-mdpi/jog_tab_left_confirm_yellow.png
+++ b/core/res/res/drawable-mdpi/jog_tab_left_confirm_yellow.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/jog_tab_left_normal.png b/core/res/res/drawable-mdpi/jog_tab_left_normal.png
index 7af1b855006b..42f7e39d2d54 100644
--- a/core/res/res/drawable-mdpi/jog_tab_left_normal.png
+++ b/core/res/res/drawable-mdpi/jog_tab_left_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/jog_tab_left_pressed.png b/core/res/res/drawable-mdpi/jog_tab_left_pressed.png
index b76e83e9573e..888f19b5e7fc 100644
--- a/core/res/res/drawable-mdpi/jog_tab_left_pressed.png
+++ b/core/res/res/drawable-mdpi/jog_tab_left_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/jog_tab_right_confirm_gray.png b/core/res/res/drawable-mdpi/jog_tab_right_confirm_gray.png
index 814a50d25756..7fc930ebf931 100644
--- a/core/res/res/drawable-mdpi/jog_tab_right_confirm_gray.png
+++ b/core/res/res/drawable-mdpi/jog_tab_right_confirm_gray.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/jog_tab_right_confirm_green.png b/core/res/res/drawable-mdpi/jog_tab_right_confirm_green.png
index cf157fc837ed..1a08be8a81e2 100644
--- a/core/res/res/drawable-mdpi/jog_tab_right_confirm_green.png
+++ b/core/res/res/drawable-mdpi/jog_tab_right_confirm_green.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/jog_tab_right_confirm_yellow.png b/core/res/res/drawable-mdpi/jog_tab_right_confirm_yellow.png
index 66557319d14f..2aa40363aec7 100644
--- a/core/res/res/drawable-mdpi/jog_tab_right_confirm_yellow.png
+++ b/core/res/res/drawable-mdpi/jog_tab_right_confirm_yellow.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/jog_tab_right_normal.png b/core/res/res/drawable-mdpi/jog_tab_right_normal.png
index 479c9a5f2f52..10710fbb01c6 100644
--- a/core/res/res/drawable-mdpi/jog_tab_right_normal.png
+++ b/core/res/res/drawable-mdpi/jog_tab_right_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/jog_tab_right_pressed.png b/core/res/res/drawable-mdpi/jog_tab_right_pressed.png
index 454aaf2216de..021e96ba2c42 100644
--- a/core/res/res/drawable-mdpi/jog_tab_right_pressed.png
+++ b/core/res/res/drawable-mdpi/jog_tab_right_pressed.png
Binary files differ
diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml
index f09421bca74f..487a00daa66c 100644
--- a/core/tests/coretests/AndroidManifest.xml
+++ b/core/tests/coretests/AndroidManifest.xml
@@ -35,6 +35,7 @@
android:label="@string/permlab_testDenied"
android:description="@string/permdesc_testDenied" />
+ <uses-permission android:name="android.permission.ACCESS_CACHE_FILESYSTEM" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
diff --git a/core/tests/coretests/src/android/net/DownloadManagerBaseTest.java b/core/tests/coretests/src/android/net/DownloadManagerBaseTest.java
index ee0f5f14516d..a7ec7d5fd523 100644
--- a/core/tests/coretests/src/android/net/DownloadManagerBaseTest.java
+++ b/core/tests/coretests/src/android/net/DownloadManagerBaseTest.java
@@ -27,6 +27,7 @@ import android.net.NetworkInfo;
import android.net.DownloadManager.Query;
import android.net.DownloadManager.Request;
import android.net.wifi.WifiManager;
+import android.os.Bundle;
import android.os.Environment;
import android.os.ParcelFileDescriptor;
import android.os.SystemClock;
@@ -43,9 +44,12 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.TimeoutException;
+import java.util.Collections;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
+import java.util.Set;
import java.util.Vector;
import junit.framework.AssertionFailedError;
@@ -67,6 +71,7 @@ public class DownloadManagerBaseTest extends InstrumentationTestCase {
protected static final String LOG_TAG = "android.net.DownloadManagerBaseTest";
protected static final int HTTP_OK = 200;
+ protected static final int HTTP_REDIRECT = 307;
protected static final int HTTP_PARTIAL_CONTENT = 206;
protected static final int HTTP_NOT_FOUND = 404;
protected static final int HTTP_SERVICE_UNAVAILABLE = 503;
@@ -119,6 +124,7 @@ public class DownloadManagerBaseTest extends InstrumentationTestCase {
public static class MultipleDownloadsCompletedReceiver extends BroadcastReceiver {
private volatile int mNumDownloadsCompleted = 0;
+ private Set<Long> downloadIds = Collections.synchronizedSet(new HashSet<Long>());
/**
* {@inheritDoc}
@@ -129,6 +135,8 @@ public class DownloadManagerBaseTest extends InstrumentationTestCase {
++mNumDownloadsCompleted;
Log.i(LOG_TAG, "MultipleDownloadsCompletedReceiver got intent: " +
intent.getAction() + " --> total count: " + mNumDownloadsCompleted);
+ Bundle extras = intent.getExtras();
+ downloadIds.add(new Long(extras.getLong(DownloadManager.EXTRA_DOWNLOAD_ID)));
}
}
@@ -142,6 +150,18 @@ public class DownloadManagerBaseTest extends InstrumentationTestCase {
public int numDownloadsCompleted() {
return mNumDownloadsCompleted;
}
+
+ /**
+ * Gets the list of download IDs.
+ * @return A Set<Long> with the ids of the completed downloads.
+ */
+ public Set<Long> getDownloadIds() {
+ synchronized(downloadIds) {
+ Set<Long> returnIds = new HashSet<Long>(downloadIds);
+ return returnIds;
+ }
+ }
+
}
public static class WiFiChangedReceiver extends BroadcastReceiver {
@@ -196,6 +216,17 @@ public class DownloadManagerBaseTest extends InstrumentationTestCase {
}
/**
+ * Helper to enqueue a response from the MockWebServer with no body.
+ *
+ * @param status The HTTP status code to return for this response
+ * @return Returns the mock web server response that was queued (which can be modified)
+ */
+ protected MockResponse enqueueResponse(int status) {
+ return doEnqueueResponse(status);
+
+ }
+
+ /**
* Helper to enqueue a response from the MockWebServer.
*
* @param status The HTTP status code to return for this response
diff --git a/core/tests/coretests/src/android/net/DownloadManagerIntegrationTest.java b/core/tests/coretests/src/android/net/DownloadManagerIntegrationTest.java
index be3cbf729458..a61f02d637df 100644
--- a/core/tests/coretests/src/android/net/DownloadManagerIntegrationTest.java
+++ b/core/tests/coretests/src/android/net/DownloadManagerIntegrationTest.java
@@ -21,6 +21,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.Cursor;
+import android.net.DownloadManager;
import android.net.DownloadManager.Query;
import android.net.DownloadManager.Request;
import android.net.DownloadManagerBaseTest.DataType;
@@ -28,6 +29,7 @@ import android.net.DownloadManagerBaseTest.MultipleDownloadsCompletedReceiver;
import android.net.wifi.WifiManager;
import android.os.Environment;
import android.os.ParcelFileDescriptor;
+import android.os.StatFs;
import android.os.SystemClock;
import android.test.InstrumentationTestCase;
import android.test.suitebuilder.annotation.LargeTest;
@@ -36,10 +38,13 @@ import android.test.suitebuilder.annotation.SmallTest;
import android.util.Log;
import java.io.File;
+import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.net.URL;
+import java.util.Iterator;
import java.util.Random;
+import java.util.Set;
import junit.framework.AssertionFailedError;
@@ -51,8 +56,11 @@ import coretestutils.http.MockWebServer;
*/
public class DownloadManagerIntegrationTest extends DownloadManagerBaseTest {
- private static String LOG_TAG = "android.net.DownloadManagerIntegrationTest";
- private static String PROHIBITED_DIRECTORY = "/system";
+ private final static String LOG_TAG = "android.net.DownloadManagerIntegrationTest";
+ private final static String PROHIBITED_DIRECTORY =
+ Environment.getRootDirectory().getAbsolutePath();
+ private final static String CACHE_DIR =
+ Environment.getDownloadCacheDirectory().getAbsolutePath();
protected MultipleDownloadsCompletedReceiver mReceiver = null;
/**
@@ -74,25 +82,48 @@ public class DownloadManagerIntegrationTest extends DownloadManagerBaseTest {
public void tearDown() throws Exception {
super.tearDown();
setWiFiStateOn(true);
+ removeAllCurrentDownloads();
if (mReceiver != null) {
mContext.unregisterReceiver(mReceiver);
mReceiver = null;
- removeAllCurrentDownloads();
}
}
/**
* Helper that does the actual basic download verification.
*/
- protected void doBasicDownload(byte[] blobData) throws Exception {
+ protected long doBasicDownload(byte[] blobData) throws Exception {
long dlRequest = doStandardEnqueue(blobData);
// wait for the download to complete
waitForDownloadOrTimeout(dlRequest);
- verifyAndCleanupSingleFileDownload(dlRequest, blobData);
assertEquals(1, mReceiver.numDownloadsCompleted());
+ return dlRequest;
+ }
+
+ /**
+ * Verifies a particular error code was received from a download
+ *
+ * @param uri The uri to enqueue to the DownloadManager
+ * @param error The error code expected
+ * @throws an Exception if the test fails
+ */
+ @LargeTest
+ public void doErrorTest(Uri uri, int error) throws Exception {
+ Request request = new Request(uri);
+ request.setTitle(DEFAULT_FILENAME);
+
+ long dlRequest = mDownloadManager.enqueue(request);
+ waitForDownloadOrTimeout(dlRequest);
+
+ Cursor cursor = getCursor(dlRequest);
+ try {
+ verifyInt(cursor, DownloadManager.COLUMN_ERROR_CODE, error);
+ } finally {
+ cursor.close();
+ }
}
/**
@@ -103,7 +134,8 @@ public class DownloadManagerIntegrationTest extends DownloadManagerBaseTest {
int fileSize = 500 * 1024; // 500k
byte[] blobData = generateData(fileSize, DataType.BINARY);
- doBasicDownload(blobData);
+ long dlRequest = doBasicDownload(blobData);
+ verifyAndCleanupSingleFileDownload(dlRequest, blobData);
}
/**
@@ -114,7 +146,8 @@ public class DownloadManagerIntegrationTest extends DownloadManagerBaseTest {
int fileSize = 300000;
byte[] blobData = generateData(fileSize, DataType.TEXT);
- doBasicDownload(blobData);
+ long dlRequest = doBasicDownload(blobData);
+ verifyAndCleanupSingleFileDownload(dlRequest, blobData);
}
/**
@@ -348,34 +381,209 @@ public class DownloadManagerIntegrationTest extends DownloadManagerBaseTest {
}
/**
- * Tests trying to download two large files (50M bytes, followed by 60M bytes)
+ * Tests downloading a file to cache when there isn't enough space in the cache to hold the
+ * entire file.
*/
@LargeTest
- public void testInsufficientSpaceSingleFiles() throws Exception {
- long fileSize1 = 50000000L;
- long fileSize2 = 60000000L;
- File largeFile1 = createFileOnSD(null, fileSize1, DataType.TEXT, null);
- File largeFile2 = createFileOnSD(null, fileSize2, DataType.TEXT, null);
+ public void testDownloadToCache_whenFull() throws Exception {
+ int DOWNLOAD_FILE_SIZE = 500000;
+
+ StatFs fs = new StatFs(CACHE_DIR);
+ Log.i(LOG_TAG, "getAvailableBlocks: " + fs.getAvailableBlocks());
+ Log.i(LOG_TAG, "getBlockSize: " + fs.getBlockSize());
+
+ int blockSize = fs.getBlockSize();
+ int availableBlocks = fs.getAvailableBlocks();
+ int availableBytes = blockSize * availableBlocks;
+ File outFile = null;
try {
- long dlRequest = doStandardEnqueue(largeFile1);
- waitForDownloadOrTimeout(dlRequest);
- ParcelFileDescriptor pfd = mDownloadManager.openDownloadedFile(dlRequest);
- verifyFileContents(pfd, largeFile1);
- verifyFileSize(pfd, largeFile1.length());
+ // fill cache to ensure we don't have enough space - take half the size of the
+ // download size, and leave that much freespace left on the cache partition
+ if (DOWNLOAD_FILE_SIZE <= availableBytes) {
+ int writeSizeBytes = availableBytes - (DOWNLOAD_FILE_SIZE / 2);
+
+ int writeSizeBlocks = writeSizeBytes / blockSize;
+ int remainderSizeBlocks = availableBlocks - writeSizeBlocks;
+
+ FileOutputStream fo = null;
+ try {
+ outFile = File.createTempFile("DM_TEST", null, new File(CACHE_DIR));
+ Log.v(LOG_TAG, "writing " + writeSizeBlocks + " blocks to file "
+ + outFile.getAbsolutePath());
+
+ fo = new FileOutputStream(outFile);
+
+ byte[] buffer = new byte[blockSize];
+ while (fs.getAvailableBlocks() >= remainderSizeBlocks) {
+ fo.write(buffer);
+ fs.restat(CACHE_DIR);
+ }
+ } catch (IOException e) {
+ Log.e(LOG_TAG, "error filling file: ", e);
+ throw e;
+ } finally {
+ if (fo != null) {
+ fo.close();
+ }
+ }
+ }
- dlRequest = doStandardEnqueue(largeFile2);
- waitForDownloadOrTimeout(dlRequest);
- Cursor cursor = getCursor(dlRequest);
- try {
- verifyInt(cursor, DownloadManager.COLUMN_ERROR_CODE,
- DownloadManager.ERROR_INSUFFICIENT_SPACE);
- } finally {
- cursor.close();
+ assertTrue(DOWNLOAD_FILE_SIZE > (fs.getAvailableBlocks() * blockSize));
+ byte[] blobData = generateData(DOWNLOAD_FILE_SIZE, DataType.TEXT);
+ long dlRequest = doBasicDownload(blobData);
+ verifyAndCleanupSingleFileDownload(dlRequest, blobData);
+
+ } finally {
+ if (outFile != null) {
+ outFile.delete();
}
+ }
+ }
+
+ /**
+ * Tests that files are not deleted when DOWNLOAD_CACHE_NON_PURGEABLE is set, even if we've
+ * run out of space.
+ */
+ @LargeTest
+ public void testDownloadCacheNonPurgeable() throws Exception {
+ int fileSize = 10000000;
+ byte[] blobData = generateData(fileSize, DataType.BINARY);
+ long dlRequest = -1;
+
+ // Fill up the cache partition until there's not enough room for another download.
+ // Note that we need to initiate a download first, then check for the available space. This
+ // is b/c there could be some files that are still left in the cache that can (and will be)
+ // cleared out, but not until DM gets a request for a download and reclaims that
+ // space first.
+ boolean spaceAvailable = true;
+ while (spaceAvailable) {
+ dlRequest = doStandardEnqueue(blobData);
+ waitForDownloadOrTimeout(dlRequest);
+
+ // Check if we've filled up the cache yet
+ StatFs fs = new StatFs(CACHE_DIR);
+ Log.i(LOG_TAG, "getAvailableBlocks: " + fs.getAvailableBlocks());
+ Log.i(LOG_TAG, "getBlockSize: " + fs.getBlockSize());
+ int availableBytes = fs.getBlockSize() * fs.getAvailableBlocks();
+ spaceAvailable = (availableBytes > fileSize) ? true : false;
+ }
+
+ // Now add one more download (should not fit in the space left over)
+ dlRequest = doStandardEnqueue(blobData);
+ waitForDownloadOrTimeout(dlRequest);
+
+ // For the last download we should have failed b/c there is not enough space left in cache
+ Cursor cursor = getCursor(dlRequest);
+ try {
+ verifyInt(cursor, DownloadManager.COLUMN_ERROR_CODE,
+ DownloadManager.ERROR_INSUFFICIENT_SPACE);
+ } finally {
+ cursor.close();
+ }
+ }
+
+ /**
+ * Tests that we get the correct download ID from the download notification.
+ */
+ @LargeTest
+ public void testGetDownloadIdOnNotification() throws Exception {
+ byte[] blobData = generateData(3000, DataType.TEXT); // file size = 3000 bytes
+
+ MockResponse response = enqueueResponse(HTTP_OK, blobData);
+ long dlRequest = doCommonStandardEnqueue();
+ waitForDownloadOrTimeout(dlRequest);
+
+ Set<Long> ids = mReceiver.getDownloadIds();
+ assertEquals(1, ids.size());
+ Iterator<Long> it = ids.iterator();
+ assertEquals("Download ID received from notification does not match initial id!",
+ dlRequest, it.next().longValue());
+ }
+
+ /**
+ * Tests the download failure error after too many redirects (>5).
+ */
+ @LargeTest
+ public void testErrorTooManyRedirects() throws Exception {
+ Uri uri = getServerUri(DEFAULT_FILENAME);
+
+ // force 6 redirects
+ for (int i = 0; i < 6; ++i) {
+ MockResponse response = enqueueResponse(HTTP_REDIRECT);
+ response.addHeader("Location", uri.toString());
+ }
+ doErrorTest(uri, DownloadManager.ERROR_TOO_MANY_REDIRECTS);
+ }
+
+ /**
+ * Tests the download failure error from an unhandled HTTP status code
+ */
+ @LargeTest
+ public void testErrorUnhandledHttpCode() throws Exception {
+ Uri uri = getServerUri(DEFAULT_FILENAME);
+ MockResponse response = enqueueResponse(HTTP_PARTIAL_CONTENT);
+
+ doErrorTest(uri, DownloadManager.ERROR_UNHANDLED_HTTP_CODE);
+ }
+
+ /**
+ * Tests the download failure error from an unhandled HTTP status code
+ */
+ @LargeTest
+ public void testErrorHttpDataError_invalidRedirect() throws Exception {
+ Uri uri = getServerUri(DEFAULT_FILENAME);
+ MockResponse response = enqueueResponse(HTTP_REDIRECT);
+ response.addHeader("Location", "://blah.blah.blah.com");
+
+ doErrorTest(uri, DownloadManager.ERROR_HTTP_DATA_ERROR);
+ }
+
+ /**
+ * Tests that we can remove a download from the download manager.
+ */
+ @LargeTest
+ public void testRemoveDownload() throws Exception {
+ int fileSize = 100 * 1024; // 100k
+ byte[] blobData = generateData(fileSize, DataType.BINARY);
+
+ long dlRequest = doBasicDownload(blobData);
+ Cursor cursor = mDownloadManager.query(new Query().setFilterById(dlRequest));
+ try {
+ assertEquals("The count of downloads with this ID is not 1!", 1, cursor.getCount());
+ mDownloadManager.remove(dlRequest);
+ cursor.requery();
+ assertEquals("The count of downloads with this ID is not 0!", 0, cursor.getCount());
+ } finally {
+ cursor.close();
+ }
+ }
+
+ /**
+ * Tests that we can set the title of a download.
+ */
+ @LargeTest
+ public void testSetTitle() throws Exception {
+ int fileSize = 50 * 1024; // 50k
+ byte[] blobData = generateData(fileSize, DataType.BINARY);
+ MockResponse response = enqueueResponse(HTTP_OK, blobData);
+
+ // An arbitrary unicode string title
+ final String title = "\u00a5123;\"\u0152\u017d \u054b \u0a07 \ucce0 \u6820\u03a8\u5c34" +
+ "\uf4ad\u0da9\uc0c5\uc1a8 \uf4c5 \uf4aa\u0023\'";
+
+ Uri uri = getServerUri(DEFAULT_FILENAME);
+ Request request = new Request(uri);
+ request.setTitle(title);
+
+ long dlRequest = mDownloadManager.enqueue(request);
+ waitForDownloadOrTimeout(dlRequest);
+
+ Cursor cursor = getCursor(dlRequest);
+ try {
+ verifyString(cursor, DownloadManager.COLUMN_TITLE, title);
} finally {
- largeFile1.delete();
- largeFile2.delete();
+ cursor.close();
}
}
}
diff --git a/core/tests/hosttests/src/android/net/DownloadManagerHostTests.java b/core/tests/hosttests/src/android/net/DownloadManagerHostTests.java
index ed280c916ec4..df781bf46676 100644
--- a/core/tests/hosttests/src/android/net/DownloadManagerHostTests.java
+++ b/core/tests/hosttests/src/android/net/DownloadManagerHostTests.java
@@ -54,8 +54,10 @@ public class DownloadManagerHostTests extends DeviceTestCase {
private static final String EXTERNAL_DOWNLOAD_URI_KEY = "external_download_uri";
// Note: External environment variable ANDROID_TEST_EXTERNAL_URI must be set to point to the
// external URI under which the files downloaded by the tests can be found. Note that the Uri
- // must be accessible by the device during a test run.
- private static String EXTERNAL_DOWNLOAD_URI_VALUE = null;
+ // must be accessible by the device during a test run. Correspondingly,
+ // ANDROID_TEST_EXTERNAL_LARGE_URI should point to the external URI of the folder containing
+ // large files.
+ private static String externalDownloadUriValue = null;
Hashtable<String, String> mExtraParams = null;
@@ -69,8 +71,8 @@ public class DownloadManagerHostTests extends DeviceTestCase {
// ensure apk path has been set before test is run
assertNotNull(getTestAppPath());
mPMUtils = new PackageManagerHostTestUtils(getDevice());
- EXTERNAL_DOWNLOAD_URI_VALUE = System.getenv("ANDROID_TEST_EXTERNAL_URI");
- assertNotNull(EXTERNAL_DOWNLOAD_URI_VALUE);
+ externalDownloadUriValue = System.getenv("ANDROID_TEST_EXTERNAL_URI");
+ assertNotNull(externalDownloadUriValue);
mExtraParams = getExtraParams();
}
@@ -79,7 +81,7 @@ public class DownloadManagerHostTests extends DeviceTestCase {
*/
protected Hashtable<String, String> getExtraParams() {
Hashtable<String, String> extraParams = new Hashtable<String, String>();
- extraParams.put(EXTERNAL_DOWNLOAD_URI_KEY, EXTERNAL_DOWNLOAD_URI_VALUE);
+ extraParams.put(EXTERNAL_DOWNLOAD_URI_KEY, externalDownloadUriValue);
return extraParams;
}
@@ -198,4 +200,19 @@ public class DownloadManagerHostTests extends DeviceTestCase {
DOWNLOAD_TEST_RUNNER_NAME, mExtraParams);
assertTrue(testPassed);
}
+
+ /**
+ * Spawns a device-based function to test 15 concurrent downloads of 5,000,000-byte files
+ *
+ * @throws Exception if the test failed at any point
+ */
+ public void testDownloadMultipleSimultaneously() throws Exception {
+ mPMUtils.installAppAndVerifyExistsOnDevice(String.format("%s%s%s", getTestAppPath(),
+ File.separator, FILE_DOWNLOAD_APK), FILE_DOWNLOAD_PKG, true);
+
+ boolean testPassed = mPMUtils.runDeviceTestsDidAllTestsPass(FILE_DOWNLOAD_PKG,
+ FILE_DOWNLOAD_CLASS, "runDownloadMultipleSimultaneously",
+ DOWNLOAD_TEST_RUNNER_NAME, mExtraParams);
+ assertTrue(testPassed);
+ }
}
diff --git a/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/DownloadManagerTestApp.java b/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/DownloadManagerTestApp.java
index ef8135398583..0293ded853c1 100644
--- a/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/DownloadManagerTestApp.java
+++ b/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/DownloadManagerTestApp.java
@@ -35,6 +35,7 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
+import java.util.HashSet;
import coretestutils.http.MockResponse;
import coretestutils.http.MockWebServer;
@@ -55,8 +56,13 @@ public class DownloadManagerTestApp extends DownloadManagerBaseTest {
protected static String DOWNLOAD_10MB_FILENAME = "External10mb.apk";
protected static long DOWNLOAD_10MB_FILESIZE = 10258741;
+ private static final String FILE_CONCURRENT_DOWNLOAD_FILE_PREFIX = "file";
+ private static final String FILE_CONCURRENT_DOWNLOAD_FILE_EXTENSION = ".bin";
+ protected static long CONCURRENT_DOWNLOAD_FILESIZE = 1000000;
+
// Values to be obtained from TestRunner
private String externalDownloadUriValue = null;
+ private String externalLargeDownloadUriValue = null;
/**
* {@inheritDoc }
@@ -65,12 +71,24 @@ public class DownloadManagerTestApp extends DownloadManagerBaseTest {
public void setUp() throws Exception {
super.setUp();
DownloadManagerTestRunner mRunner = (DownloadManagerTestRunner)getInstrumentation();
- externalDownloadUriValue = mRunner.externalDownloadUriValue;
+ externalDownloadUriValue = normalizeUri(mRunner.externalDownloadUriValue);
assertNotNull(externalDownloadUriValue);
- if (!externalDownloadUriValue.endsWith("/")) {
- externalDownloadUriValue += "/";
+ externalLargeDownloadUriValue = normalizeUri(mRunner.externalDownloadUriValue);
+ assertNotNull(externalLargeDownloadUriValue);
+ }
+
+ /**
+ * Normalizes a uri to ensure it ends with a "/"
+ *
+ * @param uri The uri to normalize (or null)
+ * @return The normalized uri, or null if null was passed in
+ */
+ public String normalizeUri(String uri) {
+ if (uri != null && !uri.endsWith("/")) {
+ uri += "/";
}
+ return uri;
}
/**
@@ -460,4 +478,37 @@ public class DownloadManagerTestApp extends DownloadManagerBaseTest {
downloadedFile.delete();
}
}
+
+ /**
+ * Tests 15 concurrent downloads of 1,000,000-byte files.
+ *
+ * @throws Exception if test failed
+ */
+ public void runDownloadMultipleSimultaneously() throws Exception {
+ final int TOTAL_DOWNLOADS = 15;
+ HashSet<Long> downloadIds = new HashSet<Long>(TOTAL_DOWNLOADS);
+ MultipleDownloadsCompletedReceiver receiver = registerNewMultipleDownloadsReceiver();
+
+ // Make sure there are no pending downloads currently going on
+ removeAllCurrentDownloads();
+
+ try {
+ for (int i = 0; i < TOTAL_DOWNLOADS; ++i) {
+ long dlRequest = -1;
+ String filename = FILE_CONCURRENT_DOWNLOAD_FILE_PREFIX + i
+ + FILE_CONCURRENT_DOWNLOAD_FILE_EXTENSION;
+ Uri remoteUri = getExternalFileUri(filename);
+ Request request = new Request(remoteUri);
+ request.setTitle(filename);
+ dlRequest = mDownloadManager.enqueue(request);
+ assertTrue(dlRequest != -1);
+ downloadIds.add(dlRequest);
+ }
+
+ waitForDownloadsOrTimeout(DEFAULT_WAIT_POLL_TIME, 15 * 60 * 2000); // wait 15 mins max
+ assertEquals(TOTAL_DOWNLOADS, receiver.numDownloadsCompleted());
+ } finally {
+ removeAllCurrentDownloads();
+ }
+ }
}
diff --git a/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/DownloadManagerTestRunner.java b/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/DownloadManagerTestRunner.java
index 0f166195b4be..27bf7e1e2497 100644
--- a/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/DownloadManagerTestRunner.java
+++ b/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/DownloadManagerTestRunner.java
@@ -30,7 +30,7 @@ import junit.framework.TestSuite;
*
* To run the download manager tests:
*
- * adb shell am instrument -e external_download_1mb_uri <uri> external_download_500k_uri <uri> \
+ * adb shell am instrument -e external_download_uri <uri> external_large_download_uri <uri> \
* -w com.android.frameworks.downloadmanagertests/.DownloadManagerTestRunner
*/
diff --git a/media/java/android/media/AudioEffect.java b/media/java/android/media/AudioEffect.java
index ae67114a27fb..ed7601eb19c4 100644
--- a/media/java/android/media/AudioEffect.java
+++ b/media/java/android/media/AudioEffect.java
@@ -847,39 +847,40 @@ public class AudioEffect {
// -------------------------------------------------------------------------
/**
- * This intent launches an audio effect control panel UI. The goal of this intent is to enable
- * separate implementations of music/media player applications and audio effect control
- * application or services. This will allow platform vendors to offer more advanced control
- * options for standard effects or control for platform specific effects.
+ * Intent to launch an audio effect control panel UI.
+ * <p>The goal of this intent is to enable separate implementations of music/media player
+ * applications and audio effect control application or services.
+ * This will allow platform vendors to offer more advanced control options for standard effects
+ * or control for platform specific effects.
* <p>The intent carries a number of extras used by the player application to communicate
* necessary pieces of information to the control panel application.
* <p>The calling application must use the
* {@link android.app.Activity#startActivityForResult(Intent, int)} method to launch the
* control panel so that its package name is indicated and used by the control panel
* application to keep track of changes for this particular application.
- * <p>The android.media.EXTRA_AUDIO_SESSION extra will indicate an audio session to which the
+ * <p>The {@link #EXTRA_AUDIO_SESSION} extra will indicate an audio session to which the
* audio effects should be applied. If no audio session is specified, either one of the
* follownig will happen:
- * - If an audio session was previously opened by the calling application with
+ * <p>- If an audio session was previously opened by the calling application with
* {@link #ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION} intent, the effect changes will
* be applied to that session.
- * - If no audio session is opened, the changes will be stored in the package specific storage
- * area and applied whenever a new audio session is opened by this application.
- * <p>The android.media.EXTRA_CONTENT_TYPE extra will help the control panel application
+ * <p>- If no audio session is opened, the changes will be stored in the package specific
+ * storage area and applied whenever a new audio session is opened by this application.
+ * <p>The {@link #EXTRA_CONTENT_TYPE} extra will help the control panel application
* customize both the UI layout and the default audio effect settings if none are already
* stored for the calling application.
- * {@hide} pending API council approval
*/
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL =
"android.media.action.DISPLAY_AUDIO_EFFECT_CONTROL_PANEL";
/**
- * This intent indicates to the effect control application or service that a new audio session
- * is opened and requires audio effects to be applied. This is different from
- * {@link #ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL} in that no UI should be displayed in
- * this case. Music player applications can broadcast this intent before starting playback
- * to make sure that any audio effect settings previously selected by the user are applied.
+ * Intent to signal to the effect control application or service that a new audio session
+ * is opened and requires audio effects to be applied.
+ * <p>This is different from {@link #ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL} in that no
+ * UI should be displayed in this case. Music player applications can broadcast this intent
+ * before starting playback to make sure that any audio effect settings previously selected
+ * by the user are applied.
* <p>The effect control application receiving this intent will look for previously stored
* settings for the calling application, create all required audio effects and apply the
* effect settings to the specified audio session.
@@ -888,48 +889,50 @@ public class AudioEffect {
* <p>If no stored settings are found for the calling application, default settings for the
* content type indicated by {@link #EXTRA_CONTENT_TYPE} will be applied. The default settings
* for a given content type are platform specific.
- * {@hide} pending API council approval
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION =
"android.media.action.OPEN_AUDIO_EFFECT_CONTROL_SESSION";
/**
- * This intent indicates to the effect control application or service that an audio session
+ * Intent to signal to the effect control application or service that an audio session
* is closed and that effects should not be applied anymore.
- * <p>The effect control application receiving this intent will delete all effects on this
- * session and store current settings in package specific storage.
+ * <p>The effect control application receiving this intent will delete all effects on
+ * this session and store current settings in package specific storage.
* <p>The calling package name is indicated by the {@link #EXTRA_PACKAGE_NAME} extra and the
* audio session ID by the {@link #EXTRA_AUDIO_SESSION} extra. Both extras are mandatory.
* <p>It is good practice for applications to broadcast this intent when music playback stops
* and/or when exiting to free system resources consumed by audio effect engines.
- * {@hide} pending API council approval
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION =
"android.media.action.CLOSE_AUDIO_EFFECT_CONTROL_SESSION";
/**
- * This extra indicates the ID of the audio session the effects should be applied to.
+ * Contains the ID of the audio session the effects should be applied to.
+ * <p>This extra is for use with {@link #ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL},
+ * {@link #ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION} and
+ * {@link #ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION} intents.
* <p>The extra value is of type int and is the audio session ID.
- * @see android.media.MediaPlayer#setAudioSessionId(int) for details on audio sessions.
- * {@hide} pending API council approval
+ *
+ * @see android.media.MediaPlayer#setAudioSessionId(int)
*/
public static final String EXTRA_AUDIO_SESSION = "android.media.extra.AUDIO_SESSION";
/**
- * This extra indicates the package name of the calling application for
- * {@link #ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION} and
+ * Contains the package name of the calling application.
+ * <p>This extra is for use with {@link #ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION} and
* {@link #ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION} intents.
* <p>The extra value is a string containing the full package name.
- * {@hide} pending API council approval
*/
public static final String EXTRA_PACKAGE_NAME = "android.media.extra.PACKAGE_NAME";
/**
- * This extra indicates which type of content is played by the application. This information is
- * used by the effect control application to customize UI and default effect settings.
- * The content type is one of the following:
+ * Indicates which type of content is played by the application.
+ * <p>This extra is for use with {@link #ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL} and
+ * {@link #ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION} intents.
+ * <p>This information is used by the effect control application to customize UI and select
+ * appropriate default effect settings. The content type is one of the following:
* <ul>
* <li>{@link #CONTENT_TYPE_MUSIC}</li>
* <li>{@link #CONTENT_TYPE_MOVIE}</li>
@@ -937,28 +940,23 @@ public class AudioEffect {
* <li>{@link #CONTENT_TYPE_VOICE}</li>
* </ul>
* If omitted, the content type defaults to {@link #CONTENT_TYPE_MUSIC}.
- * {@hide} pending API council approval
*/
public static final String EXTRA_CONTENT_TYPE = "android.media.extra.CONTENT_TYPE";
/**
* Value for {@link #EXTRA_CONTENT_TYPE} when the type of content played is music
- * {@hide} pending API council approval
*/
public static final int CONTENT_TYPE_MUSIC = 0;
/**
- * Value for {@link #EXTRA_CONTENT_TYPE} when the type of content played is video of movie
- * {@hide} pending API council approval
+ * Value for {@link #EXTRA_CONTENT_TYPE} when the type of content played is video or movie
*/
public static final int CONTENT_TYPE_MOVIE = 1;
/**
* Value for {@link #EXTRA_CONTENT_TYPE} when the type of content played is game audio
- * {@hide} pending API council approval
*/
public static final int CONTENT_TYPE_GAME = 2;
/**
* Value for {@link #EXTRA_CONTENT_TYPE} when the type of content played is voice audio
- * {@hide} pending API council approval
*/
public static final int CONTENT_TYPE_VOICE = 3;
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_3g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_3g.png
index d0d13457b112..95866b12e611 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_3g.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_3g_fully.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_3g_fully.png
index 5af2b050cb9e..5524e26ac7eb 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_3g_fully.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_3g_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_in_3g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_in_3g.png
index 11ee0f289511..07ea499fb741 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_in_3g.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_in_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_in_3g_fully.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_in_3g_fully.png
index 31c976a0d6cc..a8411fc6b552 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_in_3g_fully.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_in_3g_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_inandout_3g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_inandout_3g.png
index dba9675cd963..95bb3cd92510 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_inandout_3g.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_inandout_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_inandout_3g_fully.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_inandout_3g_fully.png
index 3903545edde0..f7dda73f14b2 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_inandout_3g_fully.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_inandout_3g_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_out_3g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_out_3g.png
index 04ec59e36d32..cac78027f574 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_out_3g.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_out_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_out_3g_fully.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_out_3g_fully.png
index d44a4cfc1177..eb5150fac33d 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_out_3g_fully.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_out_3g_fully.png
Binary files differ
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index 87329e3156ad..c047e1052962 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -173,6 +173,7 @@ public class WifiService extends IWifiManager.Stub {
private static final int MESSAGE_STOP_ACCESS_POINT = 7;
private static final int MESSAGE_SET_CHANNELS = 8;
private static final int MESSAGE_ENABLE_NETWORKS = 9;
+ private static final int MESSAGE_START_SCAN = 10;
private final WifiHandler mWifiHandler;
@@ -385,23 +386,12 @@ public class WifiService extends IWifiManager.Stub {
/**
* see {@link android.net.wifi.WifiManager#startScan()}
- * @return {@code true} if the operation succeeds
*/
- public boolean startScan(boolean forceActive) {
+ public void startScan(boolean forceActive) {
enforceChangePermission();
+ if (mWifiHandler == null) return;
- switch (mWifiStateTracker.getSupplicantState()) {
- case DISCONNECTED:
- case INACTIVE:
- case SCANNING:
- case DORMANT:
- break;
- default:
- mWifiStateTracker.setScanResultHandling(
- WifiStateTracker.SUPPL_SCAN_HANDLING_LIST_ONLY);
- break;
- }
- return mWifiStateTracker.scan(forceActive);
+ Message.obtain(mWifiHandler, MESSAGE_START_SCAN, forceActive ? 1 : 0, 0).sendToTarget();
}
/**
@@ -2001,6 +1991,21 @@ public class WifiService extends IWifiManager.Stub {
mWifiStateTracker.enableAllNetworks(getConfiguredNetworks());
break;
+ case MESSAGE_START_SCAN:
+ boolean forceActive = (msg.arg1 == 1);
+ switch (mWifiStateTracker.getSupplicantState()) {
+ case DISCONNECTED:
+ case INACTIVE:
+ case SCANNING:
+ case DORMANT:
+ break;
+ default:
+ mWifiStateTracker.setScanResultHandling(
+ WifiStateTracker.SUPPL_SCAN_HANDLING_LIST_ONLY);
+ break;
+ }
+ mWifiStateTracker.scan(forceActive);
+ break;
}
}
}
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index 0ee559e7c228..198b1e6b44d6 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -42,7 +42,7 @@ interface IWifiManager
boolean pingSupplicant();
- boolean startScan(boolean forceActive);
+ void startScan(boolean forceActive);
List<ScanResult> getScanResults();
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index dd162f212cbd..f8835881347a 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -570,7 +570,8 @@ public class WifiManager {
*/
public boolean startScan() {
try {
- return mService.startScan(false);
+ mService.startScan(false);
+ return true;
} catch (RemoteException e) {
return false;
}
@@ -588,7 +589,8 @@ public class WifiManager {
*/
public boolean startScanActive() {
try {
- return mService.startScan(true);
+ mService.startScan(true);
+ return true;
} catch (RemoteException e) {
return false;
}