Merge korg/donut into korg/master
Jean-Baptiste Queru [Sun, 26 Jul 2009 03:44:56 +0000 (20:44 -0700)]
Conflicts:

src/com/android/providers/downloads/DownloadProvider.java
src/com/android/providers/downloads/Helpers.java

1  2 
src/com/android/providers/downloads/DownloadProvider.java
src/com/android/providers/downloads/Helpers.java
tests/permission/src/com/android/providers/downloads/permission/tests/DownloadProviderPermissionsTest.java

@@@ -77,19 -78,20 +77,20 @@@ public final class DownloadProvider ext
  
      private static final String[] sAppReadableColumnsArray = new String[] {
          Downloads._ID,
 -        Downloads.APP_DATA,
 +        Downloads.COLUMN_APP_DATA,
          Downloads._DATA,
 -        Downloads.MIMETYPE,
 -        Downloads.VISIBILITY,
 -        Downloads.DESTINATION,
 -        Downloads.CONTROL,
 -        Downloads.STATUS,
 -        Downloads.LAST_MODIFICATION,
 -        Downloads.NOTIFICATION_PACKAGE,
 -        Downloads.NOTIFICATION_CLASS,
 -        Downloads.TOTAL_BYTES,
 -        Downloads.CURRENT_BYTES,
 -        Downloads.TITLE,
 -        Downloads.DESCRIPTION
 +        Downloads.COLUMN_MIME_TYPE,
 +        Downloads.COLUMN_VISIBILITY,
++        Downloads.COLUMN_DESTINATION,
 +        Downloads.COLUMN_CONTROL,
 +        Downloads.COLUMN_STATUS,
 +        Downloads.COLUMN_LAST_MODIFICATION,
 +        Downloads.COLUMN_NOTIFICATION_PACKAGE,
 +        Downloads.COLUMN_NOTIFICATION_CLASS,
 +        Downloads.COLUMN_TOTAL_BYTES,
 +        Downloads.COLUMN_CURRENT_BYTES,
 +        Downloads.COLUMN_TITLE,
 +        Downloads.COLUMN_DESCRIPTION
      };
  
      private static HashSet<String> sAppReadableColumnsSet;
@@@ -426,11 -427,11 +426,11 @@@ public class Helpers 
                  Downloads.CONTENT_URI,
                  null,
                  "( " +
-                 Downloads.COLUMN_STATUS + " = " + Downloads.STATUS_SUCCESS + " AND " +
 -                Downloads.STATUS + " = '" + Downloads.STATUS_SUCCESS + "' AND " +
 -                Downloads.DESTINATION + " = '" + Downloads.DESTINATION_CACHE_PARTITION_PURGEABLE
 -                + "' )",
++                Downloads.COLUMN_STATUS + " = '" + Downloads.STATUS_SUCCESS + "' AND " +
 +                Downloads.COLUMN_DESTINATION +
-                         " = " + Downloads.DESTINATION_CACHE_PARTITION_PURGEABLE + " )",
++                        " = '" + Downloads.DESTINATION_CACHE_PARTITION_PURGEABLE + "' )",
                  null,
 -                Downloads.LAST_MODIFICATION);
 +                Downloads.COLUMN_LAST_MODIFICATION);
          if (cursor == null) {
              return false;
          }
index 0000000,020d1e4..0ea4da4
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,116 +1,116 @@@
+ /*
+  * Copyright (C) 2009 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.permission.tests;
+ import java.io.FileNotFoundException;
+ import java.io.FileOutputStream;
+ import java.io.IOException;
+ import android.content.ContentResolver;
+ import android.content.ContentValues;
+ import android.content.Intent;
+ import android.provider.Downloads;
+ import android.test.AndroidTestCase;
+ import android.test.suitebuilder.annotation.MediumTest;
+ /**
+  * Verify that protected Download provider actions require specific permissions.
+  *
+  * TODO: consider adding test where app has ACCESS_DOWNLOAD_MANAGER, but not
+  * ACCESS_DOWNLOAD_MANAGER_ADVANCED
+  */
+ public class DownloadProviderPermissionsTest extends AndroidTestCase {
+     private ContentResolver mContentResolver;
+     @Override
+     protected void setUp() throws Exception {
+         super.setUp();
+         mContentResolver = getContext().getContentResolver();
+     }
+     /**
+      * Test that an app cannot access the /cache filesystem
+      * <p>Tests Permission:
+      *   {@link com.android.providers.downloads.Manifest.permission#ACCESS_CACHE_FILESYSTEM}
+      */
+     @MediumTest
+     public void testAccessCacheFilesystem() throws IOException {
+         try {
+             String filePath = "/cache/this-should-not-exist.txt";
+             FileOutputStream strm = new FileOutputStream(filePath);
+             strm.write("Oops!".getBytes());
+             strm.flush();
+             strm.close();
+             fail("Was able to create and write to " + filePath);
+         } catch (SecurityException e) {
+             // expected
+         } catch (FileNotFoundException e) {
+             // also could be expected
+         }
+     }
+     /**
+      * Test that an untrusted app cannot read from the download provider
+      * <p>Tests Permission:
+      *   {@link com.android.providers.downloads.Manifest.permission#ACCESS_DOWNLOAD_MANAGER}
+      */
+     @MediumTest
+     public void testReadDownloadProvider() throws IOException {
+         try {
+             mContentResolver.query(Downloads.CONTENT_URI, null, null, null, null);
+             fail("read from provider did not throw SecurityException as expected.");
+         } catch (SecurityException e) {
+             // expected
+         }
+     }
+     /**
+      * Test that an untrusted app cannot write to the download provider
+      * <p>Tests Permission:
+      *   {@link com.android.providers.downloads.Manifest.permission#ACCESS_DOWNLOAD_MANAGER}
+      */
+     @MediumTest
+     public void testWriteDownloadProvider() throws IOException {
+         try {
+             ContentValues values = new ContentValues();
 -            values.put(Downloads.DESTINATION, "foo");
++            values.put(Downloads.COLUMN_DESTINATION, "foo");
+             mContentResolver.insert(Downloads.CONTENT_URI, values);
+             fail("write to provider did not throw SecurityException as expected.");
+         } catch (SecurityException e) {
+             // expected
+         }
+     }
+     /**
+      * Test that an untrusted app cannot access the download service
+      * <p>Tests Permission:
+      *   {@link com.android.providers.downloads.Manifest.permission#ACCESS_DOWNLOAD_MANAGER}
+      */
+     @MediumTest
+     public void testStartDownloadService() throws IOException {
+         try {
+             Intent downloadServiceIntent = new Intent();
+             downloadServiceIntent.setClassName("com.android.providers.downloads",
+                     "com.android.providers.downloads.DownloadService");
+             getContext().startService(downloadServiceIntent);
+             fail("starting download service did not throw SecurityException as expected.");
+         } catch (SecurityException e) {
+             // expected
+         }
+     }
+ }