Java 类android.provider.Downloads 实例源码

项目:SecureShareLib    文件:DownloadThread.java   
/**
 * Write a data buffer to the destination file.
 * @param data buffer containing the data to write
 * @param bytesRead how many bytes to write from the buffer
 */
private void writeDataToDestination(State state, byte[] data, int bytesRead, OutputStream out)
        throws StopRequestException {
    mStorageManager.verifySpaceBeforeWritingToFile(
            mInfo.mDestination, state.mFilename, bytesRead);

    boolean forceVerified = false;
    while (true) {
        try {
            out.write(data, 0, bytesRead);
            return;
        } catch (IOException ex) {
            // TODO: better differentiate between DRM and disk failures
            if (!forceVerified) {
                // couldn't write to file. are we out of space? check.
                mStorageManager.verifySpace(mInfo.mDestination, state.mFilename, bytesRead);
                forceVerified = true;
            } else {
                throw new StopRequestException(Downloads.Impl.STATUS_FILE_ERROR,
                        "Failed to write data: " + ex);
            }
        }
    }
}
项目:SecureShareLib    文件:StorageManager.java   
File locateDestinationDirectory(String mimeType, int destination, long contentLength)
        throws StopRequestException {
    switch (destination) {
        case Downloads.Impl.DESTINATION_CACHE_PARTITION:
        case Downloads.Impl.DESTINATION_CACHE_PARTITION_PURGEABLE:
        case Downloads.Impl.DESTINATION_CACHE_PARTITION_NOROAMING:
            return mTransferDataDir;
        case Downloads.Impl.DESTINATION_SYSTEMCACHE_PARTITION:
            return mSystemCacheDir;
        case Downloads.Impl.DESTINATION_EXTERNAL:
            File base = new File(mExternalStorageDir.getPath() + Constants.DEFAULT_DL_SUBDIR);
            if (!base.isDirectory() && !base.mkdir()) {
                // Can't create transfer directory, e.g. because a file called "transfer"
                // already exists at the root level, or the SD card filesystem is read-only.
                throw new StopRequestException(Downloads.Impl.STATUS_FILE_ERROR,
                        "unable to create external transfers directory " + base.getPath());
            }
            return base;
        default:
            throw new IllegalStateException("unexpected value for destination: " + destination);
    }
}
项目:SecureShareLib    文件:TransferProvider.java   
/**
 * Check that the file URI provided for DESTINATION_FILE_URI is valid.
 */
private void checkFileUriDestination(ContentValues values) {
    String fileUri = values.getAsString(Downloads.Impl.COLUMN_FILE_NAME_HINT);
    if (fileUri == null) {
        throw new IllegalArgumentException(
                "DESTINATION_FILE_URI must include a file URI under COLUMN_FILE_NAME_HINT");
    }
    Uri uri = Uri.parse(fileUri);
    String scheme = uri.getScheme();
    if (scheme == null || !scheme.equals("file")) {
        throw new IllegalArgumentException("Not a file URI: " + uri);
    }
    final String path = uri.getPath();
    if (path == null) {
        throw new IllegalArgumentException("Invalid file URI: " + uri);
    }
    try {
        final String canonicalPath = new File(path).getCanonicalPath();
        final String externalPath = Environment.getExternalStorageDirectory().getAbsolutePath();
        if (!canonicalPath.startsWith(externalPath)) {
            throw new SecurityException("Destination must be on external storage: " + uri);
        }
    } catch (IOException e) {
        throw new SecurityException("Problem resolving path: " + uri);
    }
}
项目:SecureShareLib    文件:TransferProvider.java   
/**
 * Insert request headers for a transfer into the DB.
 */
private void insertRequestHeaders(SQLiteDatabase db, long transferId, ContentValues values) {
    ContentValues rowValues = new ContentValues();
    rowValues.put(Downloads.Impl.RequestHeaders.COLUMN_DOWNLOAD_ID, transferId);
    for (Map.Entry<String, Object> entry : values.valueSet()) {
        String key = entry.getKey();
        if (key.startsWith(Downloads.Impl.RequestHeaders.INSERT_KEY_PREFIX)) {
            String headerLine = entry.getValue().toString();
            if (!headerLine.contains(":")) {
                throw new IllegalArgumentException("Invalid HTTP header line: " + headerLine);
            }
            String[] parts = headerLine.split(":", 2);
            rowValues.put(Downloads.Impl.RequestHeaders.COLUMN_HEADER, parts[0].trim());
            rowValues.put(Downloads.Impl.RequestHeaders.COLUMN_VALUE, parts[1].trim());
            db.insert(Downloads.Impl.RequestHeaders.HEADERS_DB_TABLE, null, rowValues);
        }
    }
}
项目:SecureShareLib    文件:TransferProvider.java   
private SqlSelection getWhereClause(final Uri uri, final String where, final String[] whereArgs,
        int uriMatch) {
    SqlSelection selection = new SqlSelection();
    selection.appendClause(where, whereArgs);
    if (uriMatch == MY_DOWNLOADS_ID || uriMatch == ALL_DOWNLOADS_ID ||
            uriMatch == PUBLIC_DOWNLOAD_ID) {
        selection.appendClause(Downloads.Impl._ID + " = ?", getTransferIdFromUri(uri));
    }
    if ((uriMatch == MY_DOWNLOADS || uriMatch == MY_DOWNLOADS_ID)
            && getContext().checkCallingPermission(Downloads.Impl.PERMISSION_ACCESS_ALL)
            != PackageManager.PERMISSION_GRANTED) {
        selection.appendClause(
                Constants.UID + "= ? OR " + Downloads.Impl.COLUMN_OTHER_UID + "= ?",
                Binder.getCallingUid(), Binder.getCallingUid());
    }
    return selection;
}
项目:SecureShareLib    文件:TransferInfo.java   
private void readRequestHeaders(TransferInfo info) {
    info.mRequestHeaders.clear();
    Uri headerUri = Uri.withAppendedPath(
            info.getAllDownloadsUri(), Downloads.Impl.RequestHeaders.URI_SEGMENT);
    Cursor cursor = mResolver.query(headerUri, null, null, null, null);
    try {
        int headerIndex =
                cursor.getColumnIndexOrThrow(Downloads.Impl.RequestHeaders.COLUMN_HEADER);
        int valueIndex =
                cursor.getColumnIndexOrThrow(Downloads.Impl.RequestHeaders.COLUMN_VALUE);
        for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
            addHeader(info, cursor.getString(headerIndex), cursor.getString(valueIndex));
        }
    } finally {
        cursor.close();
    }

    if (info.mCookies != null) {
        addHeader(info, "Cookie", info.mCookies);
    }
    if (info.mReferer != null) {
        addHeader(info, "Referer", info.mReferer);
    }
}
项目:SecureShareLib    文件:TransferInfo.java   
public void sendIntentIfRequested() {
    if (mPackage == null) {
        return;
    }

    Intent intent;
    if (mIsPublicApi) {
        intent = new Intent(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
        intent.setPackage(mPackage);
        intent.putExtra(DownloadManager.EXTRA_DOWNLOAD_ID, mId);
    } else { // legacy behavior
        if (mClass == null) {
            return;
        }
        intent = new Intent(Downloads.Impl.ACTION_DOWNLOAD_COMPLETED);
        intent.setClassName(mPackage, mClass);
        if (mExtras != null) {
            intent.putExtra(Downloads.Impl.COLUMN_NOTIFICATION_EXTRAS, mExtras);
        }
        // We only send the content: URI, for security reasons. Otherwise, malicious
        //     applications would have an easier time spoofing transfer results by
        //     sending spoofed intents.
        intent.setData(getMyDownloadsUri());
    }
    mSystemFacade.sendBroadcast(intent);
}
项目:SecureShareLib    文件:TransferInfo.java   
/**
 * Query and return status of requested transfer.
 */
public static int queryTransferStatus(ContentResolver resolver, long id) {
    final Cursor cursor = resolver.query(
            ContentUris.withAppendedId(Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI, id),
            new String[] { Downloads.Impl.COLUMN_STATUS }, null, null, null);
    try {
        if (cursor.moveToFirst()) {
            return cursor.getInt(0);
        } else {
            // TODO: increase strictness of value returned for unknown
            // transfers; this is safe default for now.
            return Downloads.Impl.STATUS_PENDING;
        }
    } finally {
        cursor.close();
    }
}
项目:SecureShareLib    文件:TransferThread.java   
/**
 * Check if current connectivity is valid for this request.
 */
private void checkConnectivity() throws StopRequestException {
    // checking connectivity will apply current policy
    mPolicyDirty = false;

    final NetworkState networkUsable = mInfo.checkCanUseNetwork();
    if (networkUsable != NetworkState.OK) {
        int status = Downloads.Impl.STATUS_WAITING_FOR_NETWORK;
        if (networkUsable == NetworkState.UNUSABLE_DUE_TO_SIZE) {
            status = Downloads.Impl.STATUS_QUEUED_FOR_WIFI;
            mInfo.notifyPauseDueToSize(true);
        } else if (networkUsable == NetworkState.RECOMMENDED_UNUSABLE_DUE_TO_SIZE) {
            status = Downloads.Impl.STATUS_QUEUED_FOR_WIFI;
            mInfo.notifyPauseDueToSize(false);
        }
        throw new StopRequestException(status, networkUsable.name());
    }
}
项目:SecureShareLib    文件:TransferThread.java   
/**
 * Check if the transfer has been paused or canceled, stopping the request appropriately if it
 * has been.
 */
private void checkPausedOrCanceled(State state) throws StopRequestException {
    synchronized (mInfo) {
        if (mInfo.mControl == Downloads.Impl.CONTROL_PAUSED) {
            throw new StopRequestException(
                    Downloads.Impl.STATUS_PAUSED_BY_APP, "transfer paused by owner");
        }
        if (mInfo.mStatus == Downloads.Impl.STATUS_CANCELED || mInfo.mDeleted) {
            throw new StopRequestException(Downloads.Impl.STATUS_CANCELED, "transfer canceled");
        }
    }

    // if policy has been changed, trigger connectivity check
    if (mPolicyDirty) {
        checkConnectivity();
    }
}
项目:SecureShareLib    文件:TransferThread.java   
/**
 * Called when we've reached the end of the HTTP response stream, to update the database and
 * check for consistency.
 */
private void handleEndOfStream(State state) throws StopRequestException {
    ContentValues values = new ContentValues();
    values.put(Downloads.Impl.COLUMN_CURRENT_BYTES, state.mCurrentBytes);
    if (state.mContentLength == -1) {
        values.put(Downloads.Impl.COLUMN_TOTAL_BYTES, state.mCurrentBytes);
    }
    mContext.getContentResolver().update(mInfo.getAllDownloadsUri(), values, null, null);

    final boolean lengthMismatched = (state.mContentLength != -1)
            && (state.mCurrentBytes != state.mContentLength);
    if (lengthMismatched) {
        if (cannotResume(state)) {
            throw new StopRequestException(STATUS_CANNOT_RESUME,
                    "mismatched content length; unable to resume");
        } else {
            throw new StopRequestException(STATUS_HTTP_DATA_ERROR,
                    "closed socket before end of file");
        }
    }
}
项目:SecureShareLib    文件:TransferThread.java   
/**
 * Read some data from the HTTP response stream, handling I/O errors.
 * @param data buffer to use to read data
 * @param entityStream stream for reading the HTTP response entity
 * @return the number of bytes actually read or -1 if the end of the stream has been reached
 */
private int readFromResponse(State state, byte[] data, InputStream entityStream)
        throws StopRequestException {
    try {
        return entityStream.read(data);
    } catch (IOException ex) {
        // TODO: handle stream errors the same as other retries
        if ("unexpected end of stream".equals(ex.getMessage())) {
            return -1;
        }

        ContentValues values = new ContentValues();
        values.put(Downloads.Impl.COLUMN_CURRENT_BYTES, state.mCurrentBytes);
        mContext.getContentResolver().update(mInfo.getAllDownloadsUri(), values, null, null);
        if (cannotResume(state)) {
            throw new StopRequestException(STATUS_CANNOT_RESUME,
                    "Failed reading response: " + ex + "; unable to resume", ex);
        } else {
            throw new StopRequestException(STATUS_HTTP_DATA_ERROR,
                    "Failed reading response: " + ex, ex);
        }
    }
}
项目:SecureShareLib    文件:TransferThread.java   
private void notifyThroughDatabase(
        State state, int finalStatus, String errorMsg, int numFailed) {
    ContentValues values = new ContentValues();
    values.put(Downloads.Impl.COLUMN_STATUS, finalStatus);
    values.put(Downloads.Impl._DATA, state.mFilename);
    values.put(Downloads.Impl.COLUMN_MIME_TYPE, state.mMimeType);
    values.put(Downloads.Impl.COLUMN_LAST_MODIFICATION, mSystemFacade.currentTimeMillis());
    values.put(Downloads.Impl.COLUMN_FAILED_CONNECTIONS, numFailed);
    values.put(Constants.RETRY_AFTER_X_REDIRECT_COUNT, state.mRetryAfter);

    if (!TextUtils.equals(mInfo.mUri, state.mRequestUri)) {
        values.put(Downloads.Impl.COLUMN_URI, state.mRequestUri);
    }

    // save the error message. could be useful to developers.
    if (!TextUtils.isEmpty(errorMsg)) {
        values.put(Downloads.Impl.COLUMN_ERROR_MSG, errorMsg);
    }
    mContext.getContentResolver().update(mInfo.getAllDownloadsUri(), values, null, null);
}
项目:SecureShareLib    文件:SizeLimitActivity.java   
private void showDialog(Cursor cursor) {
    int size = cursor.getInt(cursor.getColumnIndexOrThrow(Downloads.Impl.COLUMN_TOTAL_BYTES));
    String sizeString = Formatter.formatFileSize(this, size);
    String queueText = getString(R.string.button_queue_for_wifi);
    boolean isWifiRequired =
        mCurrentIntent.getExtras().getBoolean(TransferInfo.EXTRA_IS_WIFI_REQUIRED);

    AlertDialog.Builder builder = new AlertDialog.Builder(this, AlertDialog.THEME_HOLO_DARK);
    if (isWifiRequired) {
        builder.setTitle(R.string.wifi_required_title)
                .setMessage(getString(R.string.wifi_required_body, sizeString, queueText))
                .setPositiveButton(R.string.button_queue_for_wifi, this)
                .setNegativeButton(R.string.button_cancel_download, this);
    } else {
        builder.setTitle(R.string.wifi_recommended_title)
                .setMessage(getString(R.string.wifi_recommended_body, sizeString, queueText))
                .setPositiveButton(R.string.button_start_now, this)
                .setNegativeButton(R.string.button_queue_for_wifi, this);
    }
    mDialog = builder.setOnCancelListener(this).show();
}
项目:SecureShareLib    文件:DownloadThread.java   
/**
 * Called just before the thread finishes, regardless of status, to take any necessary action on
 * the transfered file.
 */
private void cleanupDestination(State state, int finalStatus) {
    if (state.mFilename != null && Downloads.Impl.isStatusError(finalStatus)) {
        if (Constants.LOGVV) {
            Log.d(TAG, "cleanupDestination() deleting " + state.mFilename);
        }
        new File(state.mFilename).delete();
        state.mFilename = null;
    }
}
项目:SecureShareLib    文件:StorageManager.java   
void verifySpace(int destination, String path, long length) throws StopRequestException {
    resetBytesTransferedSinceLastCheckOnSpace();
    File dir = null;
    if (Constants.LOGV) {
        Log.i(Constants.TAG, "in verifySpace, destination: " + destination +
                ", path: " + path + ", length: " + length);
    }
    if (path == null) {
        throw new IllegalArgumentException("path can't be null");
    }
    switch (destination) {
        case Downloads.Impl.DESTINATION_CACHE_PARTITION:
        case Downloads.Impl.DESTINATION_CACHE_PARTITION_NOROAMING:
        case Downloads.Impl.DESTINATION_CACHE_PARTITION_PURGEABLE:
            dir = mTransferDataDir;
            break;
        case Downloads.Impl.DESTINATION_EXTERNAL:
            dir = mExternalStorageDir;
            break;
        case Downloads.Impl.DESTINATION_SYSTEMCACHE_PARTITION:
            dir = mSystemCacheDir;
            break;
        case Downloads.Impl.DESTINATION_FILE_URI:
            if (path.startsWith(mExternalStorageDir.getPath())) {
                dir = mExternalStorageDir;
            } else if (path.startsWith(mTransferDataDir.getPath())) {
                dir = mTransferDataDir;
            } else if (path.startsWith(mSystemCacheDir.getPath())) {
                dir = mSystemCacheDir;
            }
            break;
     }
    if (dir == null) {
        throw new IllegalStateException("invalid combination of destination: " + destination +
                ", path: " + path);
    }
    findSpace(dir, length, destination);
}
项目:SecureShareLib    文件:TransferProvider.java   
/**
 * insert() now ensures these four columns are never null for new transfers, so this method
 * makes that true for existing columns, so that code can rely on this assumption.
 */
private void fillNullValues(SQLiteDatabase db) {
    ContentValues values = new ContentValues();
    values.put(Downloads.Impl.COLUMN_CURRENT_BYTES, 0);
    fillNullValuesForColumn(db, values);
    values.put(Downloads.Impl.COLUMN_TOTAL_BYTES, -1);
    fillNullValuesForColumn(db, values);
    values.put(Downloads.Impl.COLUMN_TITLE, "");
    fillNullValuesForColumn(db, values);
    values.put(Downloads.Impl.COLUMN_DESCRIPTION, "");
    fillNullValuesForColumn(db, values);
}
项目:SecureShareLib    文件:TransferProvider.java   
/**
 * Set all existing transfers to the cache partition to be invisible in the transfers UI.
 */
private void makeCacheDownloadsInvisible(SQLiteDatabase db) {
    ContentValues values = new ContentValues();
    values.put(Downloads.Impl.COLUMN_IS_VISIBLE_IN_DOWNLOADS_UI, false);
    String cacheSelection = Downloads.Impl.COLUMN_DESTINATION
            + " != " + Downloads.Impl.DESTINATION_EXTERNAL;
    db.update(DB_TABLE, values, cacheSelection, null);
}
项目:SecureShareLib    文件:TransferProvider.java   
private void createHeadersTable(SQLiteDatabase db) {
    db.execSQL("DROP TABLE IF EXISTS " + Downloads.Impl.RequestHeaders.HEADERS_DB_TABLE);
    db.execSQL("CREATE TABLE " + Downloads.Impl.RequestHeaders.HEADERS_DB_TABLE + "(" +
               "id INTEGER PRIMARY KEY AUTOINCREMENT," +
               Downloads.Impl.RequestHeaders.COLUMN_DOWNLOAD_ID + " INTEGER NOT NULL," +
               Downloads.Impl.RequestHeaders.COLUMN_HEADER + " TEXT NOT NULL," +
               Downloads.Impl.RequestHeaders.COLUMN_VALUE + " TEXT NOT NULL" +
               ");");
}
项目:SecureShareLib    文件:TransferProvider.java   
/**
 * Returns the content-provider-style MIME types of the various
 * types accessible through this content provider.
 */
@Override
public String getType(final Uri uri) {
    int match = sURIMatcher.match(uri);
    switch (match) {
        case MY_DOWNLOADS:
        case ALL_DOWNLOADS: {
            return DOWNLOAD_LIST_TYPE;
        }
        case MY_DOWNLOADS_ID:
        case ALL_DOWNLOADS_ID:
        case PUBLIC_DOWNLOAD_ID: {
            // return the mimetype of this id from the database
            final String id = getTransferIdFromUri(uri);
            final SQLiteDatabase db = mOpenHelper.getReadableDatabase();
            final String mimeType = DatabaseUtils.stringForQuery(db,
                    "SELECT " + Downloads.Impl.COLUMN_MIME_TYPE + " FROM " + DB_TABLE +
                    " WHERE " + Downloads.Impl._ID + " = ?",
                    new String[]{id});
            if (TextUtils.isEmpty(mimeType)) {
                return DOWNLOAD_TYPE;
            } else {
                return mimeType;
            }
        }
        default: {
            if (Constants.LOGV) {
                Log.v(Constants.TAG, "calling getType on an unknown URI: " + uri);
            }
            throw new IllegalArgumentException("Unknown URI: " + uri);
        }
    }
}
项目:SecureShareLib    文件:TransferProvider.java   
/**
 * Handle a query for the custom request headers registered for a transfer.
 */
private Cursor queryRequestHeaders(SQLiteDatabase db, Uri uri) {
    String where = Downloads.Impl.RequestHeaders.COLUMN_DOWNLOAD_ID + "="
                   + getTransferIdFromUri(uri);
    String[] projection = new String[] {Downloads.Impl.RequestHeaders.COLUMN_HEADER,
                                        Downloads.Impl.RequestHeaders.COLUMN_VALUE};
    return db.query(Downloads.Impl.RequestHeaders.HEADERS_DB_TABLE, projection, where,
                    null, null, null, null);
}
项目:SecureShareLib    文件:TransferProvider.java   
/**
 * Delete request headers for transfers matching the given query.
 */
private void deleteRequestHeaders(SQLiteDatabase db, String where, String[] whereArgs) {
    String[] projection = new String[] {Downloads.Impl._ID};
    Cursor cursor = db.query(DB_TABLE, projection, where, whereArgs, null, null, null, null);
    try {
        for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
            long id = cursor.getLong(0);
            String idWhere = Downloads.Impl.RequestHeaders.COLUMN_DOWNLOAD_ID + "=" + id;
            db.delete(Downloads.Impl.RequestHeaders.HEADERS_DB_TABLE, idWhere, null);
        }
    } finally {
        cursor.close();
    }
}
项目:SecureShareLib    文件:TransferProvider.java   
/**
 * Deletes a row in the database
 */
@Override
public int delete(final Uri uri, final String where,
        final String[] whereArgs) {

    Helpers.validateSelection(where, sAppReadableColumnsSet);

    SQLiteDatabase db = mOpenHelper.getWritableDatabase();
    int count;
    int match = sURIMatcher.match(uri);
    switch (match) {
        case MY_DOWNLOADS:
        case MY_DOWNLOADS_ID:
        case ALL_DOWNLOADS:
        case ALL_DOWNLOADS_ID:
            SqlSelection selection = getWhereClause(uri, where, whereArgs, match);
            deleteRequestHeaders(db, selection.getSelection(), selection.getParameters());

            final Cursor cursor = db.query(DB_TABLE, new String[] {
                    Downloads.Impl._ID }, selection.getSelection(), selection.getParameters(),
                    null, null, null);
            try {
                while (cursor.moveToNext()) {
                    final long id = cursor.getLong(0);
                    TransferStorageProvider.onTransferProviderDelete(getContext(), id);
                }
            } finally {
                IoUtils.closeQuietly(cursor);
            }

            count = db.delete(DB_TABLE, selection.getSelection(), selection.getParameters());
            break;

        default:
            Log.d(Constants.TAG, "deleting unknown/invalid URI: " + uri);
            throw new UnsupportedOperationException("Cannot delete URI: " + uri);
    }
    notifyContentChanged(uri, match);
    return count;
}
项目:SecureShareLib    文件:TransferProvider.java   
@Override
public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
    final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ", 120);

    pw.println("Downloads updated in last hour:");
    pw.increaseIndent();

    final SQLiteDatabase db = mOpenHelper.getReadableDatabase();
    final long modifiedAfter = mSystemFacade.currentTimeMillis() - DateUtils.HOUR_IN_MILLIS;
    final Cursor cursor = db.query(DB_TABLE, null,
            Downloads.Impl.COLUMN_LAST_MODIFICATION + ">" + modifiedAfter, null, null, null,
            Downloads.Impl._ID + " ASC");
    try {
        final String[] cols = cursor.getColumnNames();
        final int idCol = cursor.getColumnIndex(BaseColumns._ID);
        while (cursor.moveToNext()) {
            pw.println("Transfer #" + cursor.getInt(idCol) + ":");
            pw.increaseIndent();
            for (int i = 0; i < cols.length; i++) {
                // Omit sensitive data when dumping
                if (Downloads.Impl.COLUMN_COOKIE_DATA.equals(cols[i])) {
                    continue;
                }
                pw.printPair(cols[i], cursor.getString(i));
            }
            pw.println();
            pw.decreaseIndent();
        }
    } finally {
        cursor.close();
    }

    pw.decreaseIndent();
}
项目:SecureShareLib    文件:TransferProvider.java   
private void logVerboseOpenFileInfo(Uri uri, String mode) {
    Log.v(Constants.TAG, "openFile uri: " + uri + ", mode: " + mode
            + ", uid: " + Binder.getCallingUid());
    Cursor cursor = query(Downloads.Impl.CONTENT_URI,
            new String[] { "_id" }, null, null, "_id");
    if (cursor == null) {
        Log.v(Constants.TAG, "null cursor in openFile");
    } else {
        if (!cursor.moveToFirst()) {
            Log.v(Constants.TAG, "empty cursor in openFile");
        } else {
            do {
                Log.v(Constants.TAG, "row " + cursor.getInt(0) + " available");
            } while(cursor.moveToNext());
        }
        cursor.close();
    }
    cursor = query(uri, new String[] { "_data" }, null, null, null);
    if (cursor == null) {
        Log.v(Constants.TAG, "null cursor in openFile");
    } else {
        if (!cursor.moveToFirst()) {
            Log.v(Constants.TAG, "empty cursor in openFile");
        } else {
            String filename = cursor.getString(0);
            Log.v(Constants.TAG, "filename in openFile: " + filename);
            if (new java.io.File(filename).isFile()) {
                Log.v(Constants.TAG, "file exists in openFile");
            }
        }
        cursor.close();
    }
}
项目:SecureShareLib    文件:TransferInfo.java   
/**
 * Returns whether this transfer should be enqueued.
 */
private boolean isReadyToTransfer() {
    if (mControl == Downloads.Impl.CONTROL_PAUSED) {
        // the transfer is paused, so it's not going to start
        return false;
    }
    switch (mStatus) {
        case 0: // status hasn't been initialized yet, this is a new transfer
        case Downloads.Impl.STATUS_PENDING: // transfer is explicit marked as ready to start
        case Downloads.Impl.STATUS_RUNNING: // transfer interrupted (process killed etc) while
                                            // running, without a chance to update the database
            return true;

        case Downloads.Impl.STATUS_WAITING_FOR_NETWORK:
        case Downloads.Impl.STATUS_QUEUED_FOR_WIFI:
            return checkCanUseNetwork() == NetworkState.OK;

        case Downloads.Impl.STATUS_WAITING_TO_RETRY:
            // transfer was waiting for a delayed restart
            final long now = mSystemFacade.currentTimeMillis();
            return restartTime(now) <= now;
        case Downloads.Impl.STATUS_DEVICE_NOT_FOUND_ERROR:
            // is the media mounted?
            return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
        case Downloads.Impl.STATUS_INSUFFICIENT_SPACE_ERROR:
            // avoids repetition of retrying transfer
            return false;
    }
    return false;
}
项目:SecureShareLib    文件:TransferInfo.java   
/**
 * Returns whether this transfer has a visible notification after
 * completion.
 */
public boolean hasCompletionNotification() {
    if (!Downloads.Impl.isStatusCompleted(mStatus)) {
        return false;
    }
    if (mVisibility == Downloads.Impl.VISIBILITY_VISIBLE_NOTIFY_COMPLETED) {
        return true;
    }
    return false;
}
项目:SecureShareLib    文件:TransferInfo.java   
private boolean isRoamingAllowed() {
    if (mIsPublicApi) {
        return mAllowRoaming;
    } else { // legacy behavior
        return mDestination != Downloads.Impl.DESTINATION_CACHE_PARTITION_NOROAMING;
    }
}
项目:SecureShareLib    文件:TransferInfo.java   
/**
 * Return time when this transfer will be ready for its next action, in
 * milliseconds after given time.
 *
 * @return If {@code 0}, transfer is ready to proceed immediately. If
 *         {@link Long#MAX_VALUE}, then transfer has no future actions.
 */
public long nextActionMillis(long now) {
    if (Downloads.Impl.isStatusCompleted(mStatus)) {
        return Long.MAX_VALUE;
    }
    if (mStatus != Downloads.Impl.STATUS_WAITING_TO_RETRY) {
        return 0;
    }
    long when = restartTime(now);
    if (when <= now) {
        return 0;
    }
    return when - now;
}
项目:SecureShareLib    文件:TransferInfo.java   
/**
 * Returns whether a file should be scanned
 */
public boolean shouldScanFile() {
    return (mMediaScanned == 0)
            && (mDestination == Downloads.Impl.DESTINATION_EXTERNAL ||
                    mDestination == Downloads.Impl.DESTINATION_FILE_URI ||
                    mDestination == Downloads.Impl.DESTINATION_NON_DOWNLOADMANAGER_DOWNLOAD)
            && Downloads.Impl.isStatusSuccess(mStatus);
}
项目:SecureShareLib    文件:TransferReceiver.java   
/**
 * Mark the given {@link TransferManager#COLUMN_ID} as being acknowledged by
 * user so it's not renewed later.
 */
private void hideNotification(Context context, long id) {
    final int status;
    final int visibility;

    final Uri uri = ContentUris.withAppendedId(Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI, id);
    final Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
    try {
        if (cursor.moveToFirst()) {
            status = getInt(cursor, Downloads.Impl.COLUMN_STATUS);
            visibility = getInt(cursor, Downloads.Impl.COLUMN_VISIBILITY);
        } else {
            Log.w(TAG, "Missing details for transfer " + id);
            return;
        }
    } finally {
        cursor.close();
    }

    if (Downloads.Impl.isStatusCompleted(status) &&
            (visibility == VISIBILITY_VISIBLE_NOTIFY_COMPLETED
            || visibility == VISIBILITY_VISIBLE_NOTIFY_ONLY_COMPLETION)) {
        final ContentValues values = new ContentValues();
        values.put(Downloads.Impl.COLUMN_VISIBILITY,
                Downloads.Impl.VISIBILITY_VISIBLE);
        context.getContentResolver().update(uri, values, null, null);
    }
}
项目:SecureShareLib    文件:Helpers.java   
/**
 * Creates a filename (where the file should be saved) from info about a transfer.
 */
static String generateSaveFile(
        Context context,
        String url,
        String hint,
        String contentDisposition,
        String contentLocation,
        String mimeType,
        int destination,
        long contentLength,
        StorageManager storageManager) throws StopRequestException {
    if (contentLength < 0) {
        contentLength = 0;
    }
    String path;
    File base = null;
    if (destination == Downloads.Impl.DESTINATION_FILE_URI) {
        path = Uri.parse(hint).getPath();
    } else {
        base = storageManager.locateDestinationDirectory(mimeType, destination,
                contentLength);
        path = chooseFilename(url, hint, contentDisposition, contentLocation,
                                         destination);
    }
    storageManager.verifySpace(destination, path, contentLength);
    if (TransferDrmHelper.isDrmConvertNeeded(mimeType)) {
        path = TransferDrmHelper.modifyDrmFwLockFileExtension(path);
    }
    path = getFullPath(path, mimeType, destination, base);
    return path;
}
项目:SecureShareLib    文件:TransferScanner.java   
@Override
public void onScanCompleted(String path, Uri uri) {
    final ScanRequest req;
    synchronized (mConnection) {
        req = mPending.remove(path);
    }
    if (req == null) {
        Log.w(TAG, "Missing request for path " + path);
        return;
    }

    // Update scanned column, which will kick off a database update pass,
    // eventually deciding if overall service is ready for teardown.
    final ContentValues values = new ContentValues();
    values.put(Downloads.Impl.COLUMN_MEDIA_SCANNED, 1);
    if (uri != null) {
        values.put(Downloads.Impl.COLUMN_MEDIAPROVIDER_URI, uri.toString());
    }

    final ContentResolver resolver = mContext.getContentResolver();
    final Uri transferUri = ContentUris.withAppendedId(
            Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI, req.id);
    final int rows = resolver.update(transferUri, values, null, null);
    if (rows == 0) {
        // Local row disappeared during scan; transfer was probably deleted
        // so clean up now-orphaned media entry.
        resolver.delete(uri, null, null);
    }
}
项目:SecureShareLib    文件:TransferThread.java   
/**
 * Report transfer progress through the database if necessary.
 */
private void reportProgress(State state) {
    final long now = SystemClock.elapsedRealtime();

    final long sampleDelta = now - state.mSpeedSampleStart;
    if (sampleDelta > 500) {
        final long sampleSpeed = ((state.mCurrentBytes - state.mSpeedSampleBytes) * 1000)
                / sampleDelta;

        if (state.mSpeed == 0) {
            state.mSpeed = sampleSpeed;
        } else {
            state.mSpeed = ((state.mSpeed * 3) + sampleSpeed) / 4;
        }

        // Only notify once we have a full sample window
        if (state.mSpeedSampleStart != 0) {
            mNotifier.notifyTransferSpeed(mInfo.mId, state.mSpeed);
        }

        state.mSpeedSampleStart = now;
        state.mSpeedSampleBytes = state.mCurrentBytes;
    }

    if (state.mCurrentBytes - state.mBytesNotified > Constants.MIN_PROGRESS_STEP &&
        now - state.mTimeLastNotification > Constants.MIN_PROGRESS_TIME) {
        ContentValues values = new ContentValues();
        values.put(Downloads.Impl.COLUMN_CURRENT_BYTES, state.mCurrentBytes);
        mContext.getContentResolver().update(mInfo.getAllDownloadsUri(), values, null, null);
        state.mBytesNotified = state.mCurrentBytes;
        state.mTimeLastNotification = now;
    }
}
项目:SecureShareLib    文件:TransferThread.java   
/**
 * Update necessary database fields based on values of HTTP response headers that have been
 * read.
 */
private void updateDatabaseFromHeaders(State state) {
    ContentValues values = new ContentValues();
    values.put(Downloads.Impl._DATA, state.mFilename);
    if (state.mHeaderETag != null) {
        values.put(Constants.ETAG, state.mHeaderETag);
    }
    if (state.mMimeType != null) {
        values.put(Downloads.Impl.COLUMN_MIME_TYPE, state.mMimeType);
    }
    values.put(Downloads.Impl.COLUMN_TOTAL_BYTES, mInfo.mTotalBytes);
    mContext.getContentResolver().update(mInfo.getAllDownloadsUri(), values, null, null);
}
项目:SecureShareLib    文件:TransferThread.java   
/**
 * Stores information about the completed transfer, and notifies the initiating application.
 */
private void notifyTransferCompleted(
        State state, int finalStatus, String errorMsg, int numFailed) {
    notifyThroughDatabase(state, finalStatus, errorMsg, numFailed);
    if (Downloads.Impl.isStatusCompleted(finalStatus)) {
        mInfo.sendIntentIfRequested();
    }
}
项目:SecureShareLib    文件:TransferService.java   
/**
 * Initializes the service when it is first created
 */
@Override
public void onCreate() {
    super.onCreate();
    if (Constants.LOGVV) {
        Log.v(Constants.TAG, "Service onCreate");
    }

    if (mSystemFacade == null) {
        mSystemFacade = new RealSystemFacade(this);
    }

    mAlarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
    mStorageManager = new StorageManager(this);

    mUpdateThread = new HandlerThread(TAG + "-UpdateThread");
    mUpdateThread.start();
    mUpdateHandler = new Handler(mUpdateThread.getLooper(), mUpdateCallback);

    mScanner = new TransferScanner(this);

    mNotifier = new TransferNotifier(this);
    mNotifier.cancelAll();

    mObserver = new TransferManagerContentObserver();
    getContentResolver().registerContentObserver(Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI,
            true, mObserver);
}
项目:SecureShareLib    文件:TransferService.java   
/**
 * Removes the local copy of the info about a transfer.
 */
private void deleteTransferLocked(long id) {
    TransferInfo info = mTransfers.get(id);
    if (info.mStatus == Downloads.Impl.STATUS_RUNNING) {
        info.mStatus = Downloads.Impl.STATUS_CANCELED;
    }
    if (info.mDestination != Downloads.Impl.DESTINATION_EXTERNAL && info.mFileName != null) {
        if (Constants.LOGVV) {
            Log.d(TAG, "deleteTransferLocked() deleting " + info.mFileName);
        }
        deleteFileIfExists(info.mFileName);
    }
    mTransfers.remove(info.mId);
}
项目:SecureShareLib    文件:TransferNotifier.java   
/**
 * Build tag used for collapsing several {@link TransferInfo} into a single
 * {@link Notification}.
 */
private static String buildNotificationTag(TransferInfo info) {
    if (info.mStatus == Downloads.Impl.STATUS_QUEUED_FOR_WIFI) {
        return TYPE_WAITING + ":" + info.mPackage;
    } else if (isActiveAndVisible(info)) {
        return TYPE_ACTIVE + ":" + info.mPackage;
    } else if (isCompleteAndVisible(info)) {
        // Complete transfers always have unique notifs
        return TYPE_COMPLETE + ":" + info.mId;
    } else {
        return null;
    }
}
项目:SecureShareLib    文件:DownloadThread.java   
/**
 * Prepare the destination file to receive data.  If the file already exists, we'll set up
 * appropriately for resumption.
 */
private void setupDestinationFile(State state) throws StopRequestException {
    if (!TextUtils.isEmpty(state.mFilename)) { // only true if we've already run a thread for this transfer
        if (Constants.LOGV) {
            Log.i(Constants.TAG, "have run thread before for id: " + mInfo.mId +
                    ", and state.mFilename: " + state.mFilename);
        }
        if (!Helpers.isFilenameValid(state.mFilename,
                mStorageManager.getTransferDataDirectory())) {
            // this should never happen
            throw new StopRequestException(Downloads.Impl.STATUS_FILE_ERROR,
                    "found invalid internal destination filename");
        }
        // We're resuming a transfer that got interrupted
        File f = new File(state.mFilename);
        if (f.exists()) {
            if (Constants.LOGV) {
                Log.i(Constants.TAG, "resuming transfer for id: " + mInfo.mId +
                        ", and state.mFilename: " + state.mFilename);
            }
            long fileLength = f.length();
            if (fileLength == 0) {
                // The transfer hadn't actually started, we can restart from scratch
                if (Constants.LOGVV) {
                    Log.d(TAG, "setupDestinationFile() found fileLength=0, deleting "
                            + state.mFilename);
                }
                f.delete();
                state.mFilename = null;
                if (Constants.LOGV) {
                    Log.i(Constants.TAG, "resuming transfer for id: " + mInfo.mId +
                            ", BUT starting from scratch again: ");
                }
            } else if (mInfo.mETag == null && !mInfo.mNoIntegrity) {
                // This should've been caught upon failure
                if (Constants.LOGVV) {
                    Log.d(TAG, "setupDestinationFile() unable to resume transfer, deleting "
                            + state.mFilename);
                }
                f.delete();
                throw new StopRequestException(Downloads.Impl.STATUS_CANNOT_RESUME,
                        "Trying to resume a transfer that can't be resumed");
            } else {
                // All right, we'll be able to resume this transfer
                if (Constants.LOGV) {
                    Log.i(Constants.TAG, "resuming transfer for id: " + mInfo.mId +
                            ", and starting with file of length: " + fileLength);
                }
                state.mCurrentBytes = (int) fileLength;
                if (mInfo.mTotalBytes != -1) {
                    state.mContentLength = mInfo.mTotalBytes;
                }
                state.mHeaderETag = mInfo.mETag;
                state.mContinuingTransfer = true;
                if (Constants.LOGV) {
                    Log.i(Constants.TAG, "resuming transfer for id: " + mInfo.mId +
                            ", state.mCurrentBytes: " + state.mCurrentBytes +
                            ", and setting mContinuingTransfer to true: ");
                }
            }
        }
    }
}