michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: package org.mozilla.gecko; michael@0: michael@0: import java.io.File; michael@0: import java.util.Map; michael@0: import java.util.Map.Entry; michael@0: michael@0: import org.mozilla.gecko.GeckoProfileDirectories.NoMozillaDirectoryException; michael@0: import org.mozilla.gecko.db.BrowserContract; michael@0: michael@0: import android.content.ContentProvider; michael@0: import android.content.ContentValues; michael@0: import android.content.UriMatcher; michael@0: import android.database.Cursor; michael@0: import android.database.MatrixCursor; michael@0: import android.net.Uri; michael@0: import android.util.Log; michael@0: michael@0: /** michael@0: * This is not a per-profile provider. This provider allows read-only, michael@0: * restricted access to certain attributes of Fennec profiles. michael@0: */ michael@0: public class GeckoProfilesProvider extends ContentProvider { michael@0: private static final String LOG_TAG = "GeckoProfilesProvider"; michael@0: michael@0: private static final UriMatcher URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH); michael@0: michael@0: private static final int PROFILES = 100; michael@0: private static final int PROFILES_NAME = 101; michael@0: private static final int PROFILES_DEFAULT = 200; michael@0: michael@0: private static final String[] DEFAULT_ARGS = { michael@0: BrowserContract.Profiles.NAME, michael@0: BrowserContract.Profiles.PATH, michael@0: }; michael@0: michael@0: static { michael@0: URI_MATCHER.addURI(BrowserContract.PROFILES_AUTHORITY, "profiles", PROFILES); michael@0: URI_MATCHER.addURI(BrowserContract.PROFILES_AUTHORITY, "profiles/*", PROFILES_NAME); michael@0: URI_MATCHER.addURI(BrowserContract.PROFILES_AUTHORITY, "default", PROFILES_DEFAULT); michael@0: } michael@0: michael@0: @Override michael@0: public String getType(Uri uri) { michael@0: return null; michael@0: } michael@0: michael@0: @Override michael@0: public boolean onCreate() { michael@0: // Successfully loaded. michael@0: return true; michael@0: } michael@0: michael@0: private String[] profileValues(final String name, final String path, int len, int nameIndex, int pathIndex) { michael@0: final String[] values = new String[len]; michael@0: if (nameIndex >= 0) { michael@0: values[nameIndex] = name; michael@0: } michael@0: if (pathIndex >= 0) { michael@0: values[pathIndex] = path; michael@0: } michael@0: return values; michael@0: } michael@0: michael@0: protected void addRowForProfile(final MatrixCursor cursor, final int len, final int nameIndex, final int pathIndex, final String name, final String path) { michael@0: if (path == null || name == null) { michael@0: return; michael@0: } michael@0: michael@0: String[] values = new String[len]; michael@0: if (nameIndex >= 0) { michael@0: values[nameIndex] = name; michael@0: } michael@0: if (pathIndex >= 0) { michael@0: values[pathIndex] = path; michael@0: } michael@0: cursor.addRow(profileValues(name, path, len, nameIndex, pathIndex)); michael@0: } michael@0: michael@0: protected Cursor getCursorForProfiles(final String[] args, Map profiles) { michael@0: // Compute the projection. michael@0: int nameIndex = -1; michael@0: int pathIndex = -1; michael@0: for (int i = 0; i < args.length; ++i) { michael@0: if (BrowserContract.Profiles.NAME.equals(args[i])) { michael@0: nameIndex = i; michael@0: } else if (BrowserContract.Profiles.PATH.equals(args[i])) { michael@0: pathIndex = i; michael@0: } michael@0: } michael@0: michael@0: final MatrixCursor cursor = new MatrixCursor(args); michael@0: for (Entry entry : profiles.entrySet()) { michael@0: addRowForProfile(cursor, args.length, nameIndex, pathIndex, entry.getKey(), entry.getValue()); michael@0: } michael@0: return cursor; michael@0: } michael@0: michael@0: @Override michael@0: public Cursor query(Uri uri, String[] projection, String selection, michael@0: String[] selectionArgs, String sortOrder) { michael@0: michael@0: final String[] args = (projection == null) ? DEFAULT_ARGS : projection; michael@0: michael@0: final File mozillaDir; michael@0: try { michael@0: mozillaDir = GeckoProfileDirectories.getMozillaDirectory(getContext()); michael@0: } catch (NoMozillaDirectoryException e) { michael@0: Log.d(LOG_TAG, "No Mozilla directory; cannot query for profiles. Assuming there are none."); michael@0: return new MatrixCursor(projection); michael@0: } michael@0: michael@0: final Map matchingProfiles; michael@0: michael@0: final int match = URI_MATCHER.match(uri); michael@0: switch (match) { michael@0: case PROFILES: michael@0: // Return all profiles. michael@0: matchingProfiles = GeckoProfileDirectories.getAllProfiles(mozillaDir); michael@0: break; michael@0: case PROFILES_NAME: michael@0: // Return data about the specified profile. michael@0: final String name = uri.getLastPathSegment(); michael@0: matchingProfiles = GeckoProfileDirectories.getProfilesNamed(mozillaDir, michael@0: name); michael@0: break; michael@0: case PROFILES_DEFAULT: michael@0: matchingProfiles = GeckoProfileDirectories.getDefaultProfile(mozillaDir); michael@0: break; michael@0: default: michael@0: throw new UnsupportedOperationException("Unknown query URI " + uri); michael@0: } michael@0: michael@0: return getCursorForProfiles(args, matchingProfiles); michael@0: } michael@0: michael@0: @Override michael@0: public Uri insert(Uri uri, ContentValues values) { michael@0: throw new IllegalStateException("Inserts not supported."); michael@0: } michael@0: michael@0: @Override michael@0: public int delete(Uri uri, String selection, String[] selectionArgs) { michael@0: throw new IllegalStateException("Deletes not supported."); michael@0: } michael@0: michael@0: @Override michael@0: public int update(Uri uri, ContentValues values, String selection, michael@0: String[] selectionArgs) { michael@0: throw new IllegalStateException("Updates not supported."); michael@0: } michael@0: michael@0: }