summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/com/android/providers/downloads/DownloadNotification.java15
-rw-r--r--src/com/android/providers/downloads/DownloadReceiver.java5
-rw-r--r--src/com/android/providers/downloads/DownloadService.java10
-rw-r--r--src/com/android/providers/downloads/RealSystemFacade.java43
-rw-r--r--src/com/android/providers/downloads/SystemFacade.java32
-rw-r--r--tests/Android.mk2
-rw-r--r--tests/src/com/android/providers/downloads/AbstractDownloadProviderFunctionalTest.java28
-rw-r--r--tests/src/com/android/providers/downloads/FakeSystemFacade.java29
-rw-r--r--tests/src/com/android/providers/downloads/PublicApiFunctionalTest.java56
9 files changed, 108 insertions, 112 deletions
diff --git a/src/com/android/providers/downloads/DownloadNotification.java b/src/com/android/providers/downloads/DownloadNotification.java
index bbd39f6..f5778e7 100644
--- a/src/com/android/providers/downloads/DownloadNotification.java
+++ b/src/com/android/providers/downloads/DownloadNotification.java
@@ -17,6 +17,7 @@
package com.android.providers.downloads;
import android.app.Notification;
+import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ContentUris;
import android.content.Context;
@@ -38,9 +39,9 @@ import java.util.HashMap;
*/
class DownloadNotification {
- Context mContext;
- HashMap <String, NotificationItem> mNotifications;
- private SystemFacade mSystemFacade;
+ private Context mContext;
+ private NotificationManager mNotifManager;
+ private HashMap<String, NotificationItem> mNotifications;
/** Time when each {@link DownloadInfo#mId} was first shown. */
private SparseLongArray mFirstShown = new SparseLongArray();
@@ -102,7 +103,8 @@ class DownloadNotification {
*/
DownloadNotification(Context ctx, SystemFacade systemFacade) {
mContext = ctx;
- mSystemFacade = systemFacade;
+ mNotifManager = (NotificationManager) mContext.getSystemService(
+ Context.NOTIFICATION_SERVICE);
mNotifications = new HashMap<String, NotificationItem>();
}
@@ -207,8 +209,7 @@ class DownloadNotification {
builder.setContentIntent(PendingIntent.getBroadcast(mContext, 0, intent, 0));
- mSystemFacade.postNotification(item.mId, builder.getNotification());
-
+ mNotifManager.notify(item.mId, builder.build());
}
}
@@ -262,7 +263,7 @@ class DownloadNotification {
intent.setData(contentUri);
builder.setDeleteIntent(PendingIntent.getBroadcast(mContext, 0, intent, 0));
- mSystemFacade.postNotification(id, builder.getNotification());
+ mNotifManager.notify((int) id, builder.build());
}
private boolean isActiveAndVisible(DownloadInfo download) {
diff --git a/src/com/android/providers/downloads/DownloadReceiver.java b/src/com/android/providers/downloads/DownloadReceiver.java
index 26ad992..81ff404 100644
--- a/src/com/android/providers/downloads/DownloadReceiver.java
+++ b/src/com/android/providers/downloads/DownloadReceiver.java
@@ -17,6 +17,7 @@
package com.android.providers.downloads;
import android.app.DownloadManager;
+import android.app.NotificationManager;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.ContentUris;
@@ -120,7 +121,9 @@ public class DownloadReceiver extends BroadcastReceiver {
* @param cursor Cursor for reading the download's fields
*/
private void hideNotification(Context context, Uri uri, Cursor cursor) {
- mSystemFacade.cancelNotification(ContentUris.parseId(uri));
+ final NotificationManager notifManager = (NotificationManager) context.getSystemService(
+ Context.NOTIFICATION_SERVICE);
+ notifManager.cancel((int) ContentUris.parseId(uri));
int statusColumn = cursor.getColumnIndexOrThrow(Downloads.Impl.COLUMN_STATUS);
int status = cursor.getInt(statusColumn);
diff --git a/src/com/android/providers/downloads/DownloadService.java b/src/com/android/providers/downloads/DownloadService.java
index 55efefc..7030dea 100644
--- a/src/com/android/providers/downloads/DownloadService.java
+++ b/src/com/android/providers/downloads/DownloadService.java
@@ -19,6 +19,7 @@ package com.android.providers.downloads;
import static com.android.providers.downloads.Constants.TAG;
import android.app.AlarmManager;
+import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.ComponentName;
@@ -65,6 +66,7 @@ public class DownloadService extends Service {
/** Class to handle Notification Manager updates */
private DownloadNotification mNotifier;
+ private NotificationManager mNotifManager;
/**
* The Service's view of the list of downloads, mapping download IDs to the corresponding info
@@ -221,7 +223,9 @@ public class DownloadService extends Service {
mMediaScannerConnection = new MediaScannerConnection();
mNotifier = new DownloadNotification(this, mSystemFacade);
- mSystemFacade.cancelAllNotifications();
+ mNotifManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+ mNotifManager.cancelAll();
+
mStorageManager = StorageManager.getInstance(getApplicationContext());
updateFromProvider();
}
@@ -464,7 +468,7 @@ public class DownloadService extends Service {
!Downloads.Impl.isStatusCompleted(oldStatus)
&& Downloads.Impl.isStatusCompleted(info.mStatus);
if (lostVisibility || justCompleted) {
- mSystemFacade.cancelNotification(info.mId);
+ mNotifManager.cancel((int) info.mId);
}
info.startIfReady(now, mStorageManager);
@@ -487,7 +491,7 @@ public class DownloadService extends Service {
}
new File(info.mFileName).delete();
}
- mSystemFacade.cancelNotification(info.mId);
+ mNotifManager.cancel((int) info.mId);
mDownloads.remove(info.mId);
}
diff --git a/src/com/android/providers/downloads/RealSystemFacade.java b/src/com/android/providers/downloads/RealSystemFacade.java
index 6580f90..228c716 100644
--- a/src/com/android/providers/downloads/RealSystemFacade.java
+++ b/src/com/android/providers/downloads/RealSystemFacade.java
@@ -1,26 +1,35 @@
+/*
+ * 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.
+ */
+
package com.android.providers.downloads;
import android.app.DownloadManager;
-import android.app.Notification;
-import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
-import android.provider.Settings;
-import android.provider.Settings.SettingNotFoundException;
import android.telephony.TelephonyManager;
import android.util.Log;
class RealSystemFacade implements SystemFacade {
private Context mContext;
- private NotificationManager mNotificationManager;
public RealSystemFacade(Context context) {
mContext = context;
- mNotificationManager = (NotificationManager)
- mContext.getSystemService(Context.NOTIFICATION_SERVICE);
}
public long currentTimeMillis() {
@@ -85,26 +94,6 @@ class RealSystemFacade implements SystemFacade {
}
@Override
- public void postNotification(long id, Notification notification) {
- /**
- * TODO: The system notification manager takes ints, not longs, as IDs, but the download
- * manager uses IDs take straight from the database, which are longs. This will have to be
- * dealt with at some point.
- */
- mNotificationManager.notify((int) id, notification);
- }
-
- @Override
- public void cancelNotification(long id) {
- mNotificationManager.cancel((int) id);
- }
-
- @Override
- public void cancelAllNotifications() {
- mNotificationManager.cancelAll();
- }
-
- @Override
public void startThread(Thread thread) {
thread.start();
}
diff --git a/src/com/android/providers/downloads/SystemFacade.java b/src/com/android/providers/downloads/SystemFacade.java
index d143935..fda97e0 100644
--- a/src/com/android/providers/downloads/SystemFacade.java
+++ b/src/com/android/providers/downloads/SystemFacade.java
@@ -1,12 +1,25 @@
+/*
+ * 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.
+ */
package com.android.providers.downloads;
-import android.app.Notification;
import android.content.Intent;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.NetworkInfo;
-
interface SystemFacade {
/**
* @see System#currentTimeMillis()
@@ -50,21 +63,6 @@ interface SystemFacade {
public boolean userOwnsPackage(int uid, String pckg) throws NameNotFoundException;
/**
- * Post a system notification to the NotificationManager.
- */
- public void postNotification(long id, Notification notification);
-
- /**
- * Cancel a system notification.
- */
- public void cancelNotification(long id);
-
- /**
- * Cancel all system notifications.
- */
- public void cancelAllNotifications();
-
- /**
* Start a thread.
*/
public void startThread(Thread thread);
diff --git a/tests/Android.mk b/tests/Android.mk
index aaf32ba..ff3e1d4 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -8,7 +8,7 @@ LOCAL_MODULE_TAGS := tests
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_INSTRUMENTATION_FOR := DownloadProvider
LOCAL_JAVA_LIBRARIES := android.test.runner
-LOCAL_STATIC_JAVA_LIBRARIES := mockwebserver
+LOCAL_STATIC_JAVA_LIBRARIES := mockwebserver littlemock dexmaker
LOCAL_PACKAGE_NAME := DownloadProviderTests
LOCAL_CERTIFICATE := media
diff --git a/tests/src/com/android/providers/downloads/AbstractDownloadProviderFunctionalTest.java b/tests/src/com/android/providers/downloads/AbstractDownloadProviderFunctionalTest.java
index 1912e84..a65693f 100644
--- a/tests/src/com/android/providers/downloads/AbstractDownloadProviderFunctionalTest.java
+++ b/tests/src/com/android/providers/downloads/AbstractDownloadProviderFunctionalTest.java
@@ -16,6 +16,9 @@
package com.android.providers.downloads;
+import static com.google.testing.littlemock.LittleMock.mock;
+
+import android.app.NotificationManager;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
@@ -42,9 +45,6 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.UnknownHostException;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
public abstract class AbstractDownloadProviderFunctionalTest extends
ServiceTestCase<DownloadService> {
@@ -94,19 +94,14 @@ public abstract class AbstractDownloadProviderFunctionalTest extends
static class TestContext extends RenamingDelegatingContext {
private static final String FILENAME_PREFIX = "test.";
- private Context mRealContext;
- private Set<String> mAllowedSystemServices;
private ContentResolver mResolver;
+ private final NotificationManager mNotifManager;
boolean mHasServiceBeenStarted = false;
public TestContext(Context realContext) {
super(realContext, FILENAME_PREFIX);
- mRealContext = realContext;
- mAllowedSystemServices = new HashSet<String>(Arrays.asList(new String[] {
- Context.NOTIFICATION_SERVICE,
- Context.POWER_SERVICE,
- }));
+ mNotifManager = mock(NotificationManager.class);
}
public void setResolver(ContentResolver resolver) {
@@ -118,7 +113,6 @@ public abstract class AbstractDownloadProviderFunctionalTest extends
*/
@Override
public ContentResolver getContentResolver() {
- assert mResolver != null;
return mResolver;
}
@@ -127,9 +121,10 @@ public abstract class AbstractDownloadProviderFunctionalTest extends
*/
@Override
public Object getSystemService(String name) {
- if (mAllowedSystemServices.contains(name)) {
- return mRealContext.getSystemService(name);
+ if (Context.NOTIFICATION_SERVICE.equals(name)) {
+ return mNotifManager;
}
+
return super.getSystemService(name);
}
@@ -155,10 +150,13 @@ public abstract class AbstractDownloadProviderFunctionalTest extends
protected void setUp() throws Exception {
super.setUp();
- Context realContext = getContext();
+ // Since we're testing a system app, AppDataDirGuesser doesn't find our
+ // cache dir, so set it explicitly.
+ System.setProperty("dexmaker.dexcache", getContext().getCacheDir().toString());
+
+ final Context realContext = getContext();
mTestContext = new TestContext(realContext);
setupProviderAndResolver();
-
mTestContext.setResolver(mResolver);
setContext(mTestContext);
setupService();
diff --git a/tests/src/com/android/providers/downloads/FakeSystemFacade.java b/tests/src/com/android/providers/downloads/FakeSystemFacade.java
index c184de8..6898efd 100644
--- a/tests/src/com/android/providers/downloads/FakeSystemFacade.java
+++ b/tests/src/com/android/providers/downloads/FakeSystemFacade.java
@@ -1,17 +1,13 @@
package com.android.providers.downloads;
-import android.app.Notification;
import android.content.Intent;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
-import android.test.AssertionFailedError;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
-import java.util.Map;
import java.util.Queue;
public class FakeSystemFacade implements SystemFacade {
@@ -22,8 +18,6 @@ public class FakeSystemFacade implements SystemFacade {
Long mMaxBytesOverMobile = null;
Long mRecommendedMaxBytesOverMobile = null;
List<Intent> mBroadcastsSent = new ArrayList<Intent>();
- Map<Long,Notification> mActiveNotifications = new HashMap<Long,Notification>();
- List<Notification> mCanceledNotifications = new ArrayList<Notification>();
Queue<Thread> mStartedThreads = new LinkedList<Thread>();
private boolean returnActualTime = false;
@@ -73,29 +67,6 @@ public class FakeSystemFacade implements SystemFacade {
return true;
}
- @Override
- public void postNotification(long id, Notification notification) {
- if (notification == null) {
- throw new AssertionFailedError("Posting null notification");
- }
- mActiveNotifications.put(id, notification);
- }
-
- @Override
- public void cancelNotification(long id) {
- Notification notification = mActiveNotifications.remove(id);
- if (notification != null) {
- mCanceledNotifications.add(notification);
- }
- }
-
- @Override
- public void cancelAllNotifications() {
- for (long id : mActiveNotifications.keySet()) {
- cancelNotification(id);
- }
- }
-
public boolean startThreadsWithoutWaiting = false;
public void setStartThreadsWithoutWaiting(boolean flag) {
this.startThreadsWithoutWaiting = flag;
diff --git a/tests/src/com/android/providers/downloads/PublicApiFunctionalTest.java b/tests/src/com/android/providers/downloads/PublicApiFunctionalTest.java
index 2f5282a..34a69df 100644
--- a/tests/src/com/android/providers/downloads/PublicApiFunctionalTest.java
+++ b/tests/src/com/android/providers/downloads/PublicApiFunctionalTest.java
@@ -16,7 +16,17 @@
package com.android.providers.downloads;
+import static com.google.testing.littlemock.LittleMock.anyInt;
+import static com.google.testing.littlemock.LittleMock.atLeastOnce;
+import static com.google.testing.littlemock.LittleMock.isA;
+import static com.google.testing.littlemock.LittleMock.never;
+import static com.google.testing.littlemock.LittleMock.times;
+import static com.google.testing.littlemock.LittleMock.verify;
+
import android.app.DownloadManager;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.ConnectivityManager;
@@ -24,7 +34,6 @@ import android.net.Uri;
import android.os.Environment;
import android.provider.Downloads;
import android.test.suitebuilder.annotation.LargeTest;
-import android.util.Log;
import com.google.mockwebserver.MockResponse;
import com.google.mockwebserver.RecordedRequest;
@@ -37,12 +46,14 @@ import java.io.InputStream;
import java.net.MalformedURLException;
import java.util.List;
+
@LargeTest
public class PublicApiFunctionalTest extends AbstractPublicApiTest {
private static final String REDIRECTED_PATH = "/other_path";
private static final String ETAG = "my_etag";
protected File mTestDirectory;
+ private NotificationManager mNotifManager;
public PublicApiFunctionalTest() {
super(new FakeSystemFacade());
@@ -52,6 +63,9 @@ public class PublicApiFunctionalTest extends AbstractPublicApiTest {
protected void setUp() throws Exception {
super.setUp();
+ mNotifManager = (NotificationManager) getContext()
+ .getSystemService(Context.NOTIFICATION_SERVICE);
+
mTestDirectory = new File(Environment.getExternalStorageDirectory() + File.separator
+ "download_manager_functional_test");
if (mTestDirectory.exists()) {
@@ -501,24 +515,42 @@ public class PublicApiFunctionalTest extends AbstractPublicApiTest {
assertTrue(mResolver.mNotifyWasCalled);
}
- public void testNotifications() throws Exception {
- enqueueResponse(buildEmptyResponse(HTTP_OK));
+ public void testNotificationNever() throws Exception {
enqueueResponse(buildEmptyResponse(HTTP_OK));
- Download download = enqueueRequest(getRequest().setShowRunningNotification(false));
+ final Download download = enqueueRequest(
+ getRequest().setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN));
download.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
- assertEquals(0, mSystemFacade.mActiveNotifications.size());
- assertEquals(0, mSystemFacade.mCanceledNotifications.size());
+ runService();
+
+ verify(mNotifManager, never()).notify(anyInt(), isA(Notification.class));
+ // TODO: verify that it never cancels
+ }
+
+ public void testNotificationVisible() throws Exception {
+ enqueueResponse(buildEmptyResponse(HTTP_OK));
- download = enqueueRequest(getRequest()); // notifications by default
+ // only shows in-progress notifications
+ final Download download = enqueueRequest(getRequest());
download.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
- assertEquals(1, mSystemFacade.mActiveNotifications.size());
+ runService();
+
+ // TODO: verify different notif types with tags
+ verify(mNotifManager, atLeastOnce()).notify(anyInt(), isA(Notification.class));
+ verify(mNotifManager, times(1)).cancel(anyInt());
+ }
- // The notification doesn't actually get canceled until the UpdateThread runs again, which
- // gets triggered by the DownloadThread updating the status in the provider.
+ public void testNotificationVisibleComplete() throws Exception {
+ enqueueResponse(buildEmptyResponse(HTTP_OK));
+
+ final Download download = enqueueRequest(getRequest().setNotificationVisibility(
+ DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED));
+ download.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
runService();
- assertEquals(0, mSystemFacade.mActiveNotifications.size());
- assertEquals(1, mSystemFacade.mCanceledNotifications.size());
+
+ // TODO: verify different notif types with tags
+ verify(mNotifManager, atLeastOnce()).notify(anyInt(), isA(Notification.class));
+ verify(mNotifManager, times(1)).cancel(anyInt());
}
public void testRetryAfter() throws Exception {