Search in sources :

Example 41 with MatrixCursor

use of android.database.MatrixCursor in project XPrivacy by M66B.

the class XContentResolver method handleUriAfter.

@SuppressLint("DefaultLocale")
private void handleUriAfter(XParam param) throws Throwable {
    // Check URI
    if (param.args.length > 1 && param.args[0] instanceof Uri && param.getResult() != null) {
        String uri = ((Uri) param.args[0]).toString().toLowerCase();
        String[] projection = (param.args[1] instanceof String[] ? (String[]) param.args[1] : null);
        String selection = (param.args[2] instanceof String ? (String) param.args[2] : null);
        Cursor cursor = (Cursor) param.getResult();
        if (uri.startsWith("content://applications")) {
            // Applications provider: allow selected applications
            if (isRestrictedExtra(param, PrivacyManager.cSystem, "ApplicationsProvider", uri)) {
                MatrixCursor result = new MatrixCursor(cursor.getColumnNames());
                while (cursor.moveToNext()) {
                    int colPackage = cursor.getColumnIndex("package");
                    String packageName = (colPackage < 0 ? null : cursor.getString(colPackage));
                    if (packageName != null && XPackageManager.isPackageAllowed(0, packageName))
                        copyColumns(cursor, result);
                }
                result.respond(cursor.getExtras());
                param.setResult(result);
                cursor.close();
            }
        } else if (uri.startsWith("content://com.google.android.gsf.gservices")) {
            // Google services provider: block only android_id
            if (param.args.length > 3 && param.args[3] != null) {
                List<String> listSelection = Arrays.asList((String[]) param.args[3]);
                if (listSelection.contains("android_id"))
                    if (isRestrictedExtra(param, PrivacyManager.cIdentification, "GservicesProvider", uri)) {
                        int ikey = cursor.getColumnIndex("key");
                        int ivalue = cursor.getColumnIndex("value");
                        if (ikey == 0 && ivalue == 1 && cursor.getColumnCount() == 2) {
                            MatrixCursor result = new MatrixCursor(cursor.getColumnNames());
                            while (cursor.moveToNext()) {
                                if ("android_id".equals(cursor.getString(ikey)) && cursor.getString(ivalue) != null)
                                    result.addRow(new Object[] { "android_id", PrivacyManager.getDefacedProp(Binder.getCallingUid(), "GSF_ID") });
                                else
                                    copyColumns(cursor, result);
                            }
                            result.respond(cursor.getExtras());
                            param.setResult(result);
                            cursor.close();
                        } else
                            Util.log(this, Log.ERROR, "Unexpected result uri=" + uri + " columns=" + cursor.getColumnNames());
                    }
            }
        } else if (uri.startsWith("content://com.android.contacts/contacts/name_phone_or_email")) {
        // Do nothing
        } else if (uri.startsWith("content://com.android.contacts/") && !uri.equals("content://com.android.contacts/")) {
            // Contacts provider: allow selected contacts
            String[] components = uri.replace("content://com.android.", "").split("/");
            String methodName = components[0] + "/" + components[1].split("\\?")[0];
            if (methodName.equals("contacts/contacts") || methodName.equals("contacts/data") || methodName.equals("contacts/phone_lookup") || methodName.equals("contacts/raw_contacts")) {
                if (isRestrictedExtra(param, PrivacyManager.cContacts, methodName, uri)) {
                    // Get ID from URL if any
                    int urlid = -1;
                    if ((methodName.equals("contacts/contacts") || methodName.equals("contacts/phone_lookup")) && components.length > 2 && TextUtils.isDigitsOnly(components[2]))
                        urlid = Integer.parseInt(components[2]);
                    // Modify column names back
                    Object column_added = param.getObjectExtra("column_added");
                    boolean added = (column_added == null ? false : (Boolean) param.getObjectExtra("column_added"));
                    List<String> listColumn = new ArrayList<String>();
                    listColumn.addAll(Arrays.asList(cursor.getColumnNames()));
                    if (added)
                        listColumn.remove(listColumn.size() - 1);
                    // Get blacklist setting
                    int uid = Binder.getCallingUid();
                    boolean blacklist = PrivacyManager.getSettingBool(-uid, PrivacyManager.cSettingBlacklist, false);
                    MatrixCursor result = new MatrixCursor(listColumn.toArray(new String[0]));
                    // Filter rows
                    String cid = getIdForUri(uri);
                    int iid = (cid == null ? -1 : cursor.getColumnIndex(cid));
                    if (iid >= 0 || urlid >= 0)
                        while (cursor.moveToNext()) {
                            // Check if allowed
                            long id = (urlid >= 0 ? urlid : cursor.getLong(iid));
                            boolean allowed = PrivacyManager.getSettingBool(-uid, Meta.cTypeContact, Long.toString(id), false);
                            if (blacklist)
                                allowed = !allowed;
                            if (allowed)
                                copyColumns(cursor, result, listColumn.size());
                        }
                    else
                        Util.log(this, Log.WARN, "ID missing URI=" + uri + " added=" + added + "/" + cid + " columns=" + TextUtils.join(",", cursor.getColumnNames()) + " projection=" + (projection == null ? "null" : TextUtils.join(",", projection)) + " selection=" + selection);
                    result.respond(cursor.getExtras());
                    param.setResult(result);
                    cursor.close();
                }
            } else {
                methodName = null;
                if (uri.startsWith("content://com.android.contacts/profile"))
                    methodName = "contacts/profile";
                else
                    // fall-back
                    methodName = "ContactsProvider2";
                if (methodName != null)
                    if (isRestrictedExtra(param, PrivacyManager.cContacts, methodName, uri)) {
                        // Return empty cursor
                        MatrixCursor result = new MatrixCursor(cursor.getColumnNames());
                        result.respond(cursor.getExtras());
                        param.setResult(result);
                        cursor.close();
                    }
            }
        } else {
            // Other uri restrictions
            String restrictionName = null;
            String methodName = null;
            if (uri.startsWith("content://browser")) {
                restrictionName = PrivacyManager.cBrowser;
                methodName = "BrowserProvider2";
            } else if (uri.startsWith("content://com.android.calendar")) {
                restrictionName = PrivacyManager.cCalendar;
                methodName = "CalendarProvider2";
            } else if (uri.startsWith("content://call_log")) {
                restrictionName = PrivacyManager.cCalling;
                methodName = "CallLogProvider";
            } else if (uri.startsWith("content://contacts/people")) {
                restrictionName = PrivacyManager.cContacts;
                methodName = "contacts/people";
            } else if (uri.startsWith("content://downloads")) {
                restrictionName = PrivacyManager.cBrowser;
                methodName = "Downloads";
            } else if (uri.startsWith("content://com.android.email.provider")) {
                restrictionName = PrivacyManager.cEMail;
                methodName = "EMailProvider";
            } else if (uri.startsWith("content://com.google.android.gm")) {
                restrictionName = PrivacyManager.cEMail;
                methodName = "GMailProvider";
            } else if (uri.startsWith("content://icc")) {
                restrictionName = PrivacyManager.cContacts;
                methodName = "IccProvider";
            } else if (uri.startsWith("content://mms")) {
                restrictionName = PrivacyManager.cMessages;
                methodName = "MmsProvider";
            } else if (uri.startsWith("content://mms-sms")) {
                restrictionName = PrivacyManager.cMessages;
                methodName = "MmsSmsProvider";
            } else if (uri.startsWith("content://sms")) {
                restrictionName = PrivacyManager.cMessages;
                methodName = "SmsProvider";
            } else if (uri.startsWith("content://telephony")) {
                restrictionName = PrivacyManager.cPhone;
                methodName = "TelephonyProvider";
            } else if (uri.startsWith("content://user_dictionary")) {
                restrictionName = PrivacyManager.cDictionary;
                methodName = "UserDictionary";
            } else if (uri.startsWith("content://com.android.voicemail")) {
                restrictionName = PrivacyManager.cMessages;
                methodName = "VoicemailContentProvider";
            }
            // Check if know / restricted
            if (restrictionName != null && methodName != null) {
                if (isRestrictedExtra(param, restrictionName, methodName, uri)) {
                    // Return empty cursor
                    MatrixCursor result = new MatrixCursor(cursor.getColumnNames());
                    result.respond(cursor.getExtras());
                    param.setResult(result);
                    cursor.close();
                }
            }
        }
    }
}
Also used : ArrayList(java.util.ArrayList) List(java.util.List) MatrixCursor(android.database.MatrixCursor) Cursor(android.database.Cursor) Uri(android.net.Uri) MatrixCursor(android.database.MatrixCursor) SuppressLint(android.annotation.SuppressLint) SuppressLint(android.annotation.SuppressLint)

Example 42 with MatrixCursor

use of android.database.MatrixCursor in project Android-Developers-Samples by johnjohndoe.

the class MyCloudProvider method querySearchDocuments.

// END_INCLUDE(query_recent_documents)
// BEGIN_INCLUDE(query_search_documents)
@Override
public Cursor querySearchDocuments(String rootId, String query, String[] projection) throws FileNotFoundException {
    Log.v(TAG, "querySearchDocuments");
    // Create a cursor with the requested projection, or the default projection.
    final MatrixCursor result = new MatrixCursor(resolveDocumentProjection(projection));
    final File parent = getFileForDocId(rootId);
    // This example implementation searches file names for the query and doesn't rank search
    // results, so we can stop as soon as we find a sufficient number of matches.  Other
    // implementations might use other data about files, rather than the file name, to
    // produce a match; it might also require a network call to query a remote server.
    // Iterate through all files in the file structure under the root until we reach the
    // desired number of matches.
    final LinkedList<File> pending = new LinkedList<File>();
    // Start by adding the parent to the list of files to be processed
    pending.add(parent);
    // Do while we still have unexamined files, and fewer than the max search results
    while (!pending.isEmpty() && result.getCount() < MAX_SEARCH_RESULTS) {
        // Take a file from the list of unprocessed files
        final File file = pending.removeFirst();
        if (file.isDirectory()) {
            // If it's a directory, add all its children to the unprocessed list
            Collections.addAll(pending, file.listFiles());
        } else {
            // If it's a file and it matches, add it to the result cursor.
            if (file.getName().toLowerCase().contains(query)) {
                includeFile(result, null, file);
            }
        }
    }
    return result;
}
Also used : File(java.io.File) MatrixCursor(android.database.MatrixCursor) LinkedList(java.util.LinkedList)

Example 43 with MatrixCursor

use of android.database.MatrixCursor in project Android-Developers-Samples by johnjohndoe.

the class MyCloudProvider method queryChildDocuments.

// END_INCLUDE(query_document)
// BEGIN_INCLUDE(query_child_documents)
@Override
public Cursor queryChildDocuments(String parentDocumentId, String[] projection, String sortOrder) throws FileNotFoundException {
    Log.v(TAG, "queryChildDocuments, parentDocumentId: " + parentDocumentId + " sortOrder: " + sortOrder);
    final MatrixCursor result = new MatrixCursor(resolveDocumentProjection(projection));
    final File parent = getFileForDocId(parentDocumentId);
    for (File file : parent.listFiles()) {
        includeFile(result, null, file);
    }
    return result;
}
Also used : File(java.io.File) MatrixCursor(android.database.MatrixCursor)

Example 44 with MatrixCursor

use of android.database.MatrixCursor in project Android-Developers-Samples by johnjohndoe.

the class MyCloudProvider method includeFile.

/**
     * Add a representation of a file to a cursor.
     *
     * @param result the cursor to modify
     * @param docId  the document ID representing the desired file (may be null if given file)
     * @param file   the File object representing the desired file (may be null if given docID)
     * @throws java.io.FileNotFoundException
     */
private void includeFile(MatrixCursor result, String docId, File file) throws FileNotFoundException {
    if (docId == null) {
        docId = getDocIdForFile(file);
    } else {
        file = getFileForDocId(docId);
    }
    int flags = 0;
    if (file.isDirectory()) {
        // Add FLAG_DIR_SUPPORTS_CREATE if the file is a writable directory.
        if (file.isDirectory() && file.canWrite()) {
            flags |= Document.FLAG_DIR_SUPPORTS_CREATE;
        }
    } else if (file.canWrite()) {
        // If the file is writable set FLAG_SUPPORTS_WRITE and
        // FLAG_SUPPORTS_DELETE
        flags |= Document.FLAG_SUPPORTS_WRITE;
        flags |= Document.FLAG_SUPPORTS_DELETE;
    }
    final String displayName = file.getName();
    final String mimeType = getTypeForFile(file);
    if (mimeType.startsWith("image/")) {
        // Allow the image to be represented by a thumbnail rather than an icon
        flags |= Document.FLAG_SUPPORTS_THUMBNAIL;
    }
    final MatrixCursor.RowBuilder row = result.newRow();
    row.add(Document.COLUMN_DOCUMENT_ID, docId);
    row.add(Document.COLUMN_DISPLAY_NAME, displayName);
    row.add(Document.COLUMN_SIZE, file.length());
    row.add(Document.COLUMN_MIME_TYPE, mimeType);
    row.add(Document.COLUMN_LAST_MODIFIED, file.lastModified());
    row.add(Document.COLUMN_FLAGS, flags);
    // Add a custom icon
    row.add(Document.COLUMN_ICON, R.drawable.ic_launcher);
}
Also used : Point(android.graphics.Point) MatrixCursor(android.database.MatrixCursor)

Example 45 with MatrixCursor

use of android.database.MatrixCursor in project Android-Developers-Samples by johnjohndoe.

the class MyCloudProvider method queryRecentDocuments.

// END_INCLUDE(query_roots)
// BEGIN_INCLUDE(query_recent_documents)
@Override
public Cursor queryRecentDocuments(String rootId, String[] projection) throws FileNotFoundException {
    Log.v(TAG, "queryRecentDocuments");
    // This example implementation walks a local file structure to find the most recently
    // modified files.  Other implementations might include making a network call to query a
    // server.
    // Create a cursor with the requested projection, or the default projection.
    final MatrixCursor result = new MatrixCursor(resolveDocumentProjection(projection));
    final File parent = getFileForDocId(rootId);
    // Create a queue to store the most recent documents, which orders by last modified.
    PriorityQueue<File> lastModifiedFiles = new PriorityQueue<File>(5, new Comparator<File>() {

        public int compare(File i, File j) {
            return Long.compare(i.lastModified(), j.lastModified());
        }
    });
    // Iterate through all files and directories in the file structure under the root.  If
    // the file is more recent than the least recently modified, add it to the queue,
    // limiting the number of results.
    final LinkedList<File> pending = new LinkedList<File>();
    // Start by adding the parent to the list of files to be processed
    pending.add(parent);
    // Do while we still have unexamined files
    while (!pending.isEmpty()) {
        // Take a file from the list of unprocessed files
        final File file = pending.removeFirst();
        if (file.isDirectory()) {
            // If it's a directory, add all its children to the unprocessed list
            Collections.addAll(pending, file.listFiles());
        } else {
            // If it's a file, add it to the ordered queue.
            lastModifiedFiles.add(file);
        }
    }
    // Add the most recent files to the cursor, not exceeding the max number of results.
    for (int i = 0; i < Math.min(MAX_LAST_MODIFIED + 1, lastModifiedFiles.size()); i++) {
        final File file = lastModifiedFiles.remove();
        includeFile(result, null, file);
    }
    return result;
}
Also used : PriorityQueue(java.util.PriorityQueue) File(java.io.File) MatrixCursor(android.database.MatrixCursor) LinkedList(java.util.LinkedList) Point(android.graphics.Point)

Aggregations

MatrixCursor (android.database.MatrixCursor)259 Cursor (android.database.Cursor)37 DirectoryResult (com.android.documentsui.DirectoryResult)35 RowBuilder (android.database.MatrixCursor.RowBuilder)30 File (java.io.File)30 MergeCursor (android.database.MergeCursor)18 Uri (android.net.Uri)18 Test (org.junit.Test)17 Setting (com.android.providers.settings.SettingsState.Setting)15 FileNotFoundException (java.io.FileNotFoundException)15 ArrayList (java.util.ArrayList)13 Bundle (android.os.Bundle)10 BitSet (java.util.BitSet)10 Random (java.util.Random)10 IOException (java.io.IOException)7 LinkedList (java.util.LinkedList)7 ContentValues (android.content.ContentValues)6 HashSet (java.util.HashSet)6 Map (java.util.Map)6 SQLiteQueryBuilder (android.database.sqlite.SQLiteQueryBuilder)5