1/* 2 * Copyright (C) 2008 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 17package android.provider; 18 19import android.content.ContentResolver; 20import android.content.ContentValues; 21import android.content.Context; 22import android.drm.mobile1.DrmRawContent; 23import android.drm.mobile1.DrmRights; 24import android.drm.mobile1.DrmRightsManager; 25import android.content.Intent; 26import android.content.pm.PackageManager; 27import android.net.Uri; 28import android.util.Log; 29 30import java.io.File; 31import java.io.FileInputStream; 32import java.io.InputStream; 33import java.io.IOException; 34import java.io.OutputStream; 35 36/** 37 * The DRM provider contains forward locked DRM content. 38 * 39 * @hide 40 */ 41public final class DrmStore 42{ 43 private static final String TAG = "DrmStore"; 44 45 public static final String AUTHORITY = "drm"; 46 47 /** 48 * This is in the Manifest class of the drm provider, but that isn't visible 49 * in the framework. 50 */ 51 private static final String ACCESS_DRM_PERMISSION = "android.permission.ACCESS_DRM"; 52 53 /** 54 * Fields for DRM database 55 */ 56 57 public interface Columns extends BaseColumns { 58 /** 59 * The data stream for the file 60 * <P>Type: DATA STREAM</P> 61 */ 62 public static final String DATA = "_data"; 63 64 /** 65 * The size of the file in bytes 66 * <P>Type: INTEGER (long)</P> 67 */ 68 public static final String SIZE = "_size"; 69 70 /** 71 * The title of the file content 72 * <P>Type: TEXT</P> 73 */ 74 public static final String TITLE = "title"; 75 76 /** 77 * The MIME type of the file 78 * <P>Type: TEXT</P> 79 */ 80 public static final String MIME_TYPE = "mime_type"; 81 82 } 83 84 public interface Images extends Columns { 85 86 public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/images"); 87 } 88 89 public interface Audio extends Columns { 90 91 public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/audio"); 92 } 93 94 /** 95 * Utility function for inserting a file into the DRM content provider. 96 * 97 * @param cr The content resolver to use 98 * @param file The file to insert 99 * @param title The title for the content (or null) 100 * @return uri to the DRM record or null 101 */ 102 public static final Intent addDrmFile(ContentResolver cr, File file, String title) { 103 FileInputStream fis = null; 104 Intent result = null; 105 106 try { 107 fis = new FileInputStream(file); 108 if (title == null) { 109 title = file.getName(); 110 int lastDot = title.lastIndexOf('.'); 111 if (lastDot > 0) { 112 title = title.substring(0, lastDot); 113 } 114 } 115 result = addDrmFile(cr, fis, title); 116 } catch (Exception e) { 117 Log.e(TAG, "pushing file failed", e); 118 } finally { 119 try { 120 if (fis != null) 121 fis.close(); 122 } catch (IOException e) { 123 Log.e(TAG, "IOException in DrmStore.addDrmFile()", e); 124 } 125 } 126 127 return result; 128 } 129 130 /** 131 * Utility function for inserting a file stream into the DRM content provider. 132 * 133 * @param cr The content resolver to use 134 * @param fis The FileInputStream to insert 135 * @param title The title for the content (or null) 136 * @return uri to the DRM record or null 137 */ 138 public static final Intent addDrmFile(ContentResolver cr, FileInputStream fis, String title) { 139 OutputStream os = null; 140 Intent result = null; 141 142 try { 143 DrmRawContent content = new DrmRawContent(fis, (int) fis.available(), 144 DrmRawContent.DRM_MIMETYPE_MESSAGE_STRING); 145 String mimeType = content.getContentType(); 146 long size = fis.getChannel().size(); 147 148 DrmRightsManager manager = manager = DrmRightsManager.getInstance(); 149 DrmRights rights = manager.queryRights(content); 150 InputStream stream = content.getContentInputStream(rights); 151 152 Uri contentUri = null; 153 if (mimeType.startsWith("audio/")) { 154 contentUri = DrmStore.Audio.CONTENT_URI; 155 } else if (mimeType.startsWith("image/")) { 156 contentUri = DrmStore.Images.CONTENT_URI; 157 } else { 158 Log.w(TAG, "unsupported mime type " + mimeType); 159 } 160 161 if (contentUri != null) { 162 ContentValues values = new ContentValues(3); 163 values.put(DrmStore.Columns.TITLE, title); 164 values.put(DrmStore.Columns.SIZE, size); 165 values.put(DrmStore.Columns.MIME_TYPE, mimeType); 166 167 Uri uri = cr.insert(contentUri, values); 168 if (uri != null) { 169 os = cr.openOutputStream(uri); 170 171 byte[] buffer = new byte[1000]; 172 int count; 173 174 while ((count = stream.read(buffer)) != -1) { 175 os.write(buffer, 0, count); 176 } 177 result = new Intent(); 178 result.setDataAndType(uri, mimeType); 179 180 } 181 } 182 } catch (Exception e) { 183 Log.e(TAG, "pushing file failed", e); 184 } finally { 185 try { 186 if (fis != null) 187 fis.close(); 188 if (os != null) 189 os.close(); 190 } catch (IOException e) { 191 Log.e(TAG, "IOException in DrmStore.addDrmFile()", e); 192 } 193 } 194 195 return result; 196 } 197 198 /** 199 * Utility function to enforce any permissions required to access DRM 200 * content. 201 * 202 * @param context A context used for checking calling permission. 203 */ 204 public static void enforceAccessDrmPermission(Context context) { 205 if (context.checkCallingOrSelfPermission(ACCESS_DRM_PERMISSION) != 206 PackageManager.PERMISSION_GRANTED) { 207 throw new SecurityException("Requires DRM permission"); 208 } 209 } 210 211} 212