Home | History | Annotate | Download | only in public_api_access_tests
      1 /*
      2  * Copyright (C) 2009 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.providers.downloads.public_api_access_tests;
     18 
     19 import android.app.DownloadManager;
     20 import android.content.ContentResolver;
     21 import android.content.ContentValues;
     22 import android.net.Uri;
     23 import android.provider.Downloads;
     24 import android.test.AndroidTestCase;
     25 import android.test.suitebuilder.annotation.MediumTest;
     26 
     27 /**
     28  * DownloadProvider allows apps without permission ACCESS_DOWNLOAD_MANAGER to access it -- this is
     29  * how the public API works.  But such access is subject to strict constraints on what can be
     30  * inserted.  This test suite checks those constraints.
     31  */
     32 @MediumTest
     33 public class PublicApiAccessTest extends AndroidTestCase {
     34     private static final String[] DISALLOWED_COLUMNS = new String[] {
     35                     Downloads.Impl.COLUMN_COOKIE_DATA,
     36                     Downloads.Impl.COLUMN_REFERER,
     37                     Downloads.Impl.COLUMN_USER_AGENT,
     38                     Downloads.Impl.COLUMN_NO_INTEGRITY,
     39                     Downloads.Impl.COLUMN_NOTIFICATION_CLASS,
     40                     Downloads.Impl.COLUMN_NOTIFICATION_EXTRAS,
     41                     Downloads.Impl.COLUMN_OTHER_UID,
     42                     Downloads.Impl.COLUMN_APP_DATA,
     43                     Downloads.Impl.COLUMN_CONTROL,
     44                     Downloads.Impl.COLUMN_STATUS,
     45             };
     46 
     47     private ContentResolver mContentResolver;
     48     private DownloadManager mManager;
     49 
     50     @Override
     51     protected void setUp() throws Exception {
     52         super.setUp();
     53         mContentResolver = getContext().getContentResolver();
     54         mManager = new DownloadManager(getContext());
     55     }
     56 
     57     @Override
     58     protected void tearDown() throws Exception {
     59         if (mContentResolver != null) {
     60             mContentResolver.delete(Downloads.Impl.CONTENT_URI, null, null);
     61         }
     62         super.tearDown();
     63     }
     64 
     65     public void testMinimalValidWrite() {
     66         mContentResolver.insert(Downloads.Impl.CONTENT_URI, buildValidValues());
     67     }
     68 
     69     public void testMaximalValidWrite() {
     70         ContentValues values = buildValidValues();
     71         values.put(Downloads.Impl.COLUMN_TITLE, "foo");
     72         values.put(Downloads.Impl.COLUMN_DESCRIPTION, "foo");
     73         values.put(Downloads.Impl.COLUMN_MIME_TYPE, "foo");
     74         values.put(Downloads.Impl.COLUMN_NOTIFICATION_PACKAGE, "foo");
     75         values.put(Downloads.Impl.COLUMN_ALLOWED_NETWORK_TYPES, 0);
     76         values.put(Downloads.Impl.COLUMN_ALLOW_ROAMING, true);
     77         values.put(Downloads.Impl.RequestHeaders.INSERT_KEY_PREFIX + "0", "X-Some-Header: value");
     78         mContentResolver.insert(Downloads.Impl.CONTENT_URI, values);
     79     }
     80 
     81     private ContentValues buildValidValues() {
     82         ContentValues values = new ContentValues();
     83         values.put(Downloads.Impl.COLUMN_URI, "foo");
     84         values.put(Downloads.Impl.COLUMN_DESTINATION,
     85                 Downloads.Impl.DESTINATION_CACHE_PARTITION_PURGEABLE);
     86         values.put(Downloads.Impl.COLUMN_VISIBILITY, Downloads.Impl.VISIBILITY_VISIBLE);
     87         values.put(Downloads.Impl.COLUMN_IS_PUBLIC_API, true);
     88         return values;
     89     }
     90 
     91     public void testNoPublicApi() {
     92         ContentValues values = buildValidValues();
     93         values.remove(Downloads.Impl.COLUMN_IS_PUBLIC_API);
     94         testInvalidValues(values);
     95     }
     96 
     97     public void testInvalidDestination() {
     98         ContentValues values = buildValidValues();
     99         values.put(Downloads.Impl.COLUMN_DESTINATION, Downloads.Impl.DESTINATION_EXTERNAL);
    100         testInvalidValues(values);
    101         values.put(Downloads.Impl.COLUMN_DESTINATION, Downloads.Impl.DESTINATION_CACHE_PARTITION);
    102         testInvalidValues(values);
    103     }
    104 
    105     public void testInvalidVisibility() {
    106         ContentValues values = buildValidValues();
    107         values.put(Downloads.Impl.COLUMN_VISIBILITY,
    108                 Downloads.Impl.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
    109         testInvalidValues(values);
    110 
    111         values.put(Downloads.Impl.COLUMN_VISIBILITY, Downloads.Impl.VISIBILITY_HIDDEN);
    112         testInvalidValues(values);
    113 
    114         values.remove(Downloads.Impl.COLUMN_VISIBILITY);
    115         testInvalidValues(values);
    116     }
    117 
    118     public void testDisallowedColumns() {
    119         for (String column : DISALLOWED_COLUMNS) {
    120             ContentValues values = buildValidValues();
    121             values.put(column, 1);
    122             testInvalidValues(values);
    123         }
    124     }
    125 
    126     public void testFileUriWithoutExternalPermission() {
    127         ContentValues values = buildValidValues();
    128         values.put(Downloads.Impl.COLUMN_DESTINATION, Downloads.Impl.DESTINATION_FILE_URI);
    129         values.put(Downloads.Impl.COLUMN_FILE_NAME_HINT, "file:///sdcard/foo");
    130         testInvalidValues(values);
    131     }
    132 
    133     private void testInvalidValues(ContentValues values) {
    134         try {
    135             mContentResolver.insert(Downloads.Impl.CONTENT_URI, values);
    136             fail("Didn't get SecurityException as expected");
    137         } catch (SecurityException exc) {
    138             // expected
    139         }
    140     }
    141 
    142     public void testDownloadManagerRequest() {
    143         // first try a minimal request
    144         DownloadManager.Request request = new DownloadManager.Request(Uri.parse("http://localhost/path"));
    145         mManager.enqueue(request);
    146 
    147         // now set everything we can, save for external destintion (for which we lack permission)
    148         request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);
    149         request.setAllowedOverRoaming(false);
    150         request.setTitle("test");
    151         request.setDescription("test");
    152         request.setMimeType("text/html");
    153         request.addRequestHeader("X-Some-Header", "value");
    154         mManager.enqueue(request);
    155     }
    156 }
    157