All Downloads are FREE. Search and download functionalities are using the official Maven repository.

src.android.database.RedactingCursor Maven / Gradle / Ivy

Go to download

A library jar that provides APIs for Applications written for the Google Android Platform.

There is a newer version: 15-robolectric-12650502
Show newest version
/*
 * Copyright (C) 2018 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 android.database;

import android.annotation.NonNull;
import android.util.SparseArray;

import java.util.Map;

/**
 * Cursor that offers to redact values of requested columns.
 *
 * @hide
 */
public class RedactingCursor extends CrossProcessCursorWrapper {
    private final SparseArray mRedactions;

    private RedactingCursor(@NonNull Cursor cursor, SparseArray redactions) {
        super(cursor);
        mRedactions = redactions;
    }

    /**
     * Create a wrapped instance of the given {@link Cursor} which redacts the
     * requested columns so they always return specific values when accessed.
     * 

* If a redacted column appears multiple times in the underlying cursor, all * instances will be redacted. If none of the redacted columns appear in the * given cursor, the given cursor will be returned untouched to improve * performance. */ public static Cursor create(@NonNull Cursor cursor, @NonNull Map redactions) { final SparseArray internalRedactions = new SparseArray<>(); final String[] columns = cursor.getColumnNames(); for (int i = 0; i < columns.length; i++) { if (redactions.containsKey(columns[i])) { internalRedactions.put(i, redactions.get(columns[i])); } } if (internalRedactions.size() == 0) { return cursor; } else { return new RedactingCursor(cursor, internalRedactions); } } @Override public void fillWindow(int position, CursorWindow window) { // Fill window directly to ensure data is redacted DatabaseUtils.cursorFillWindow(this, position, window); } @Override public CursorWindow getWindow() { // Returning underlying window risks leaking redacted data return null; } @Override public Cursor getWrappedCursor() { throw new UnsupportedOperationException( "Returning underlying cursor risks leaking redacted data"); } @Override public double getDouble(int columnIndex) { final int i = mRedactions.indexOfKey(columnIndex); if (i >= 0) { return (double) mRedactions.valueAt(i); } else { return super.getDouble(columnIndex); } } @Override public float getFloat(int columnIndex) { final int i = mRedactions.indexOfKey(columnIndex); if (i >= 0) { return (float) mRedactions.valueAt(i); } else { return super.getFloat(columnIndex); } } @Override public int getInt(int columnIndex) { final int i = mRedactions.indexOfKey(columnIndex); if (i >= 0) { return (int) mRedactions.valueAt(i); } else { return super.getInt(columnIndex); } } @Override public long getLong(int columnIndex) { final int i = mRedactions.indexOfKey(columnIndex); if (i >= 0) { return (long) mRedactions.valueAt(i); } else { return super.getLong(columnIndex); } } @Override public short getShort(int columnIndex) { final int i = mRedactions.indexOfKey(columnIndex); if (i >= 0) { return (short) mRedactions.valueAt(i); } else { return super.getShort(columnIndex); } } @Override public String getString(int columnIndex) { final int i = mRedactions.indexOfKey(columnIndex); if (i >= 0) { return (String) mRedactions.valueAt(i); } else { return super.getString(columnIndex); } } @Override public void copyStringToBuffer(int columnIndex, CharArrayBuffer buffer) { final int i = mRedactions.indexOfKey(columnIndex); if (i >= 0) { buffer.data = ((String) mRedactions.valueAt(i)).toCharArray(); buffer.sizeCopied = buffer.data.length; } else { super.copyStringToBuffer(columnIndex, buffer); } } @Override public byte[] getBlob(int columnIndex) { final int i = mRedactions.indexOfKey(columnIndex); if (i >= 0) { return (byte[]) mRedactions.valueAt(i); } else { return super.getBlob(columnIndex); } } @Override public int getType(int columnIndex) { final int i = mRedactions.indexOfKey(columnIndex); if (i >= 0) { return DatabaseUtils.getTypeOfObject(mRedactions.valueAt(i)); } else { return super.getType(columnIndex); } } @Override public boolean isNull(int columnIndex) { final int i = mRedactions.indexOfKey(columnIndex); if (i >= 0) { return mRedactions.valueAt(i) == null; } else { return super.isNull(columnIndex); } } }