下面列出了android.content.ContentValues#getAsString ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* {@link Cols.Package#NAME} is not included in the database here, because
* it is included only in the {@link PackageTable}, since there are large
* cross-table queries needed to handle the complexity of multiple repos
* potentially serving the same apps.
*/
@Override
public Uri insert(@NonNull Uri uri, ContentValues values) {
if (MATCHER.match(uri) != CODE_LIST) {
throw new UnsupportedOperationException("Insert not supported for " + uri + ".");
}
if (!values.containsKey(Cols.Package.NAME)) {
throw new IllegalStateException("Package name not provided to InstalledAppProvider");
}
String packageName = values.getAsString(Cols.Package.NAME);
long packageId = PackageProvider.Helper.ensureExists(getContext(), packageName);
values.remove(Cols.Package.NAME);
values.put(Cols.PACKAGE_ID, packageId);
verifyVersionNameNotNull(values);
db().replaceOrThrow(getTableName(), null, values);
AppProvider.Helper.calcSuggestedApk(getContext(), packageName);
return getAppUri(values.getAsString(Cols.Package.NAME));
}
private long addBookmark(ContentValues values) {
String url = values.getAsString(BookmarkColumns.URL);
String title = values.getAsString(BookmarkColumns.TITLE);
boolean isFolder = false;
if (values.containsKey(BOOKMARK_IS_FOLDER_PARAM)) {
isFolder = values.getAsBoolean(BOOKMARK_IS_FOLDER_PARAM);
}
long parentId = INVALID_BOOKMARK_ID;
if (values.containsKey(BOOKMARK_PARENT_ID_PARAM)) {
parentId = values.getAsLong(BOOKMARK_PARENT_ID_PARAM);
}
long id = nativeAddBookmark(mNativeChromeBrowserProvider, url, title, isFolder, parentId);
if (id == INVALID_BOOKMARK_ID) return id;
if (isFolder) {
updateLastModifiedBookmarkFolder(id);
} else {
updateLastModifiedBookmarkFolder(parentId);
}
return id;
}
@Override
public DateTime getFrom(ContentValues values)
{
Long timestamp = values.getAsLong(mTimestampField);
if (timestamp == null)
{
// if the time stamp is null we return null
return null;
}
// create a new Time for the given time zone, falling back to UTC if none is given
String timezone = mTzField == null ? null : values.getAsString(mTzField);
DateTime value = new DateTime(timezone == null ? DateTime.UTC : TimeZone.getTimeZone(timezone), timestamp);
// cache mAlldayField locally
String allDayField = mAllDayField;
// set the allday flag appropriately
Integer allDayInt = allDayField == null ? null : values.getAsInteger(allDayField);
if ((allDayInt != null && allDayInt != 0) || (allDayField == null && mAllDayDefault))
{
value = value.toAllDay();
}
return value;
}
private void handleTransfer(ContentValues contentValues, XC_LoadPackage.LoadPackageParam lpparam) throws IOException, XmlPullParserException, PackageManager.NameNotFoundException, InterruptedException, JSONException {
if (!PreferencesUtils.receiveTransfer()) {
return;
}
JSONObject wcpayinfo = new XmlToJson.Builder(contentValues.getAsString("content")).build()
.getJSONObject("msg").getJSONObject("appmsg").getJSONObject("wcpayinfo");
int paysubtype = wcpayinfo.getInt("paysubtype");
if (paysubtype != 1) {
return;
}
String transactionId = wcpayinfo.getString("transcationid");
String transferId = wcpayinfo.getString("transferid");
int invalidtime = wcpayinfo.getInt("invalidtime");
if (null == requestCaller) {
Class networkRequestClass = XposedHelpers.findClass(HookParams.getInstance().NetworkRequestClassName, lpparam.classLoader);
requestCaller = callStaticMethod(networkRequestClass, HookParams.getInstance().GetNetworkByModelMethod);
}
String talker = contentValues.getAsString("talker");
Class getTransferRequestClass = XposedHelpers.findClass(HookParams.getInstance().GetTransferRequestClassName, lpparam.classLoader);
callMethod(requestCaller, HookParams.getInstance().RequestCallerMethod, newInstance(getTransferRequestClass, transactionId, transferId, 0, "confirm", talker, invalidtime), 0);
}
public String addAlarmCSV_row( ContentValues alarm )
{
String quote = "\"";
String separator = ", ";
//noinspection UnnecessaryLocalVariable
String line = alarm.getAsString(KEY_ALARM_TYPE) + separator +
alarm.getAsInteger(KEY_ALARM_ENABLED) + separator +
alarm.getAsLong(KEY_ALARM_DATETIME_ADJUSTED) + separator +
alarm.getAsLong(KEY_ALARM_DATETIME) + separator +
alarm.getAsInteger(KEY_ALARM_DATETIME_HOUR) + separator +
alarm.getAsInteger(KEY_ALARM_DATETIME_MINUTE) + separator +
quote + alarm.getAsString(KEY_ALARM_LABEL) + quote + separator +
alarm.getAsInteger(KEY_ALARM_REPEATING) + separator +
quote + alarm.getAsString(KEY_ALARM_REPEATING_DAYS) + quote + separator +
alarm.getAsString(KEY_ALARM_SOLAREVENT) + separator +
alarm.getAsString(KEY_ALARM_TIMEZONE) + separator +
quote + alarm.getAsString(KEY_ALARM_PLACELABEL) + quote + separator +
alarm.getAsString(KEY_ALARM_LATITUDE) + separator +
alarm.getAsString(KEY_ALARM_LONGITUDE) + separator +
alarm.getAsString(KEY_ALARM_ALTITUDE) + separator +
alarm.getAsInteger(KEY_ALARM_VIBRATE) + separator +
alarm.getAsString(KEY_ALARM_RINGTONE_NAME) + separator +
alarm.getAsString(KEY_ALARM_RINGTONE_URI);
return line;
}
private long addBookmark(ContentValues values) {
String url = values.getAsString(BookmarkColumns.URL);
String title = values.getAsString(BookmarkColumns.TITLE);
boolean isFolder = false;
if (values.containsKey(BOOKMARK_IS_FOLDER_PARAM)) {
isFolder = values.getAsBoolean(BOOKMARK_IS_FOLDER_PARAM);
}
long parentId = INVALID_BOOKMARK_ID;
if (values.containsKey(BOOKMARK_PARENT_ID_PARAM)) {
parentId = values.getAsLong(BOOKMARK_PARENT_ID_PARAM);
}
long id = nativeAddBookmark(mNativeChromeBrowserProvider, url, title, isFolder, parentId);
if (id == INVALID_BOOKMARK_ID) return id;
if (isFolder) {
updateLastModifiedBookmarkFolder(id);
} else {
updateLastModifiedBookmarkFolder(parentId);
}
return id;
}
/**
* Create a WordListMetadata from the contents of a ContentValues.
*
* If this lacks any required field, IllegalArgumentException is thrown.
*/
public static WordListMetadata createFromContentValues(@Nonnull final ContentValues values) {
final String id = values.getAsString(MetadataDbHelper.WORDLISTID_COLUMN);
final Integer type = values.getAsInteger(MetadataDbHelper.TYPE_COLUMN);
final String description = values.getAsString(MetadataDbHelper.DESCRIPTION_COLUMN);
final Long lastUpdate = values.getAsLong(MetadataDbHelper.DATE_COLUMN);
final Long fileSize = values.getAsLong(MetadataDbHelper.FILESIZE_COLUMN);
final String rawChecksum = values.getAsString(MetadataDbHelper.RAW_CHECKSUM_COLUMN);
final String checksum = values.getAsString(MetadataDbHelper.CHECKSUM_COLUMN);
final int retryCount = values.getAsInteger(MetadataDbHelper.RETRY_COUNT_COLUMN);
final String localFilename = values.getAsString(MetadataDbHelper.LOCAL_FILENAME_COLUMN);
final String remoteFilename = values.getAsString(MetadataDbHelper.REMOTE_FILENAME_COLUMN);
final Integer version = values.getAsInteger(MetadataDbHelper.VERSION_COLUMN);
final Integer formatVersion = values.getAsInteger(MetadataDbHelper.FORMATVERSION_COLUMN);
final Integer flags = values.getAsInteger(MetadataDbHelper.FLAGS_COLUMN);
final String locale = values.getAsString(MetadataDbHelper.LOCALE_COLUMN);
if (null == id
|| null == type
|| null == description
|| null == lastUpdate
|| null == fileSize
|| null == checksum
|| null == localFilename
|| null == remoteFilename
|| null == version
|| null == formatVersion
|| null == flags
|| null == locale) {
throw new IllegalArgumentException();
}
return new WordListMetadata(id, type, description, lastUpdate, fileSize, rawChecksum,
checksum, retryCount, localFilename, remoteFilename, version, formatVersion,
flags, locale);
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
Log.d(TAG, "update caller=" + getCallingPackageName() + " table=" + uri.getLastPathSegment()
+ " name=" + values.getAsString("name") + " value=" + values.getAsString("value"));
if (uri.equals(MAIN_URI)) {
databaseHelper.put("main", values);
} else if (uri.equals(OVERRIDE_URI)) {
databaseHelper.put("override", values);
}
String name = values.getAsString("name");
cache.remove(name);
Iterator<String> iterator = cachedPrefixes.iterator();
while (iterator.hasNext()) if (name.startsWith(iterator.next())) iterator.remove();
return 1;
}
@Override
public Uri insert(Uri arg0, ContentValues values) {
String key = values.getAsString("key");
String value = values.getAsString("value");
getContext().getSharedPreferences(MODEL_KEY, Context.MODE_PRIVATE).edit().putString(key, value).apply();
return null;
}
public AlarmClockItem(@Nullable Context context, ContentValues alarm)
{
rowID = alarm.getAsLong(AlarmDatabaseAdapter.KEY_ROWID);
type = AlarmType.valueOf(alarm.getAsString(AlarmDatabaseAdapter.KEY_ALARM_TYPE), AlarmType.ALARM);
enabled = (alarm.getAsInteger(AlarmDatabaseAdapter.KEY_ALARM_ENABLED) == 1);
label = alarm.getAsString(AlarmDatabaseAdapter.KEY_ALARM_LABEL);
repeating = (alarm.getAsInteger(AlarmDatabaseAdapter.KEY_ALARM_REPEATING) == 1);
setRepeatingDays(alarm.getAsString(AlarmDatabaseAdapter.KEY_ALARM_REPEATING_DAYS));
alarmtime = alarm.getAsLong(AlarmDatabaseAdapter.KEY_ALARM_DATETIME_ADJUSTED);
timestamp = alarm.getAsLong(AlarmDatabaseAdapter.KEY_ALARM_DATETIME);
hour = alarm.getAsInteger(AlarmDatabaseAdapter.KEY_ALARM_DATETIME_HOUR);
minute = alarm.getAsInteger(AlarmDatabaseAdapter.KEY_ALARM_DATETIME_MINUTE);
offset = alarm.getAsLong(AlarmDatabaseAdapter.KEY_ALARM_DATETIME_OFFSET);
String locLat = alarm.getAsString(AlarmDatabaseAdapter.KEY_ALARM_LATITUDE);
String locLon = alarm.getAsString(AlarmDatabaseAdapter.KEY_ALARM_LONGITUDE);
if (locLat != null && locLon != null)
{
String locLabel = alarm.getAsString(AlarmDatabaseAdapter.KEY_ALARM_PLACELABEL);
String locAlt = alarm.getAsString(AlarmDatabaseAdapter.KEY_ALARM_ALTITUDE);
location = new Location(locLabel, locLat, locLon, locAlt);
if (context != null) {
location.setUseAltitude(WidgetSettings.loadLocationAltitudeEnabledPref(context, 0));
}
} else location = null;
String eventString = alarm.getAsString(AlarmDatabaseAdapter.KEY_ALARM_SOLAREVENT);
event = SolarEvents.valueOf(eventString, null);
timezone = alarm.getAsString(AlarmDatabaseAdapter.KEY_ALARM_TIMEZONE);
vibrate = (alarm.getAsInteger(AlarmDatabaseAdapter.KEY_ALARM_VIBRATE) == 1);
ringtoneName = alarm.getAsString(AlarmDatabaseAdapter.KEY_ALARM_RINGTONE_NAME);
ringtoneURI = alarm.getAsString(AlarmDatabaseAdapter.KEY_ALARM_RINGTONE_URI);
}
@Override
public Uri insert(Uri uri, ContentValues values) {
if (!contentProviderEnabled()) return null;
if (mContentUriMatcher.match(uri) != REQUESTED) return null;
String url = values.getAsString("url");
if (requestInsert(url)) {
// TODO(aberent): If we ever make the 'requested' table readable then we might want to
// change this to a more conventional content URI (with a row number).
return uri.buildUpon().appendPath(url).build();
} else {
return null;
}
}
static BookmarkRow fromContentValues(ContentValues values) {
BookmarkRow row = new BookmarkRow();
if (values.containsKey(BookmarkColumns.URL)) {
row.mUrl = values.getAsString(BookmarkColumns.URL);
}
if (values.containsKey(BookmarkColumns.BOOKMARK)) {
row.mIsBookmark = values.getAsInteger(BookmarkColumns.BOOKMARK) != 0;
}
if (values.containsKey(BookmarkColumns.CREATED)) {
row.mCreated = values.getAsLong(BookmarkColumns.CREATED);
}
if (values.containsKey(BookmarkColumns.DATE)) {
row.mDate = values.getAsLong(BookmarkColumns.DATE);
}
if (values.containsKey(BookmarkColumns.FAVICON)) {
row.mFavicon = values.getAsByteArray(BookmarkColumns.FAVICON);
// We need to know that the caller set the favicon column.
if (row.mFavicon == null) {
row.mFavicon = new byte[0];
}
}
if (values.containsKey(BookmarkColumns.TITLE)) {
row.mTitle = values.getAsString(BookmarkColumns.TITLE);
}
if (values.containsKey(BookmarkColumns.VISITS)) {
row.mVisits = values.getAsInteger(BookmarkColumns.VISITS);
}
if (values.containsKey(BOOKMARK_PARENT_ID_PARAM)) {
row.mParentId = values.getAsLong(BOOKMARK_PARENT_ID_PARAM);
}
return row;
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
if (!canHandleContentProviderApiCall() || !hasWriteAccess()) return 0;
// Check for invalid id values if provided.
long bookmarkId = getContentUriId(uri);
if (bookmarkId == INVALID_CONTENT_PROVIDER_ID) return 0;
int match = mUriMatcher.match(uri);
int result;
switch (match) {
case URI_MATCH_BOOKMARKS_ID:
String url = null;
if (values.containsKey(BookmarkColumns.URL)) {
url = values.getAsString(BookmarkColumns.URL);
}
String title = values.getAsString(BookmarkColumns.TITLE);
long parentId = INVALID_BOOKMARK_ID;
if (values.containsKey(BOOKMARK_PARENT_ID_PARAM)) {
parentId = values.getAsLong(BOOKMARK_PARENT_ID_PARAM);
}
result = nativeUpdateBookmark(mNativeChromeBrowserProvider, bookmarkId, url, title,
parentId);
updateLastModifiedBookmarkFolder(parentId);
break;
case URL_MATCH_API_BOOKMARK_ID:
result = updateBookmarkFromAPI(values, buildWhereClause(bookmarkId, selection),
selectionArgs);
break;
case URL_MATCH_API_BOOKMARK:
result = updateBookmarkFromAPI(values, selection, selectionArgs);
break;
case URL_MATCH_API_SEARCHES_ID:
result = updateSearchTermFromAPI(values, buildWhereClause(bookmarkId, selection),
selectionArgs);
break;
case URL_MATCH_API_SEARCHES:
result = updateSearchTermFromAPI(values, selection, selectionArgs);
break;
case URL_MATCH_API_HISTORY_CONTENT:
result = updateBookmarkFromAPI(values, buildHistoryWhereClause(selection),
selectionArgs);
break;
case URL_MATCH_API_HISTORY_CONTENT_ID:
result = updateBookmarkFromAPI(values,
buildHistoryWhereClause(bookmarkId, selection), selectionArgs);
break;
case URL_MATCH_API_BOOKMARK_CONTENT:
result = updateBookmarkFromAPI(values, buildBookmarkWhereClause(selection),
selectionArgs);
break;
case URL_MATCH_API_BOOKMARK_CONTENT_ID:
result = updateBookmarkFromAPI(values,
buildBookmarkWhereClause(bookmarkId, selection), selectionArgs);
break;
default:
throw new IllegalArgumentException(TAG + ": update - unknown URL " + uri);
}
if (result != 0) notifyChange(uri);
return result;
}
@Override
protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
super.onQueryComplete(token, cookie, cursor);
if (token == TOKEN_CHECK_SAVED_STATUS) {
ContentValues values = ((ContentValues) cookie);
if (cursor != null && cursor.getCount() != 0) {
String url = values.getAsString(OfflinerDBHelper.REQUEST_URL);
// request already saved for offline, update associated json.
this.startUpdate(
TOKEN_UPDATE_ALREADY_SAVED_REQUEST,
null,
getUri(OfflinerDBHelper.TABLE_CACHE),
values,
OfflinerDBHelper.REQUEST_URL + " = '" + url + "'", null);
if (mDebug) {
Log.d(TAG, "---> ASYNC UPDATE FOR OFFLINE ");
}
} else {
// request never saved, add associated json body for offline usage.
this.startInsert(
TOKEN_SAVE_NEW_REQUEST,
null,
getUri(OfflinerDBHelper.TABLE_CACHE),
values
);
if (mDebug) {
Log.d(TAG, "---> ASYNC INSERT FOR OFFLINE ");
}
}
}
if (mDebug) {
Log.d(TAG, "Key : " + ((ContentValues) cookie).getAsString(OfflinerDBHelper.REQUEST_URL));
Log.d(TAG, "Value : " + ((ContentValues) cookie).getAsString(OfflinerDBHelper.REQUEST_RESULT));
}
if (cursor != null) {
cursor.close();
}
}
@Override
public Uri insert(Uri uri, ContentValues values) {
if (DEBUG) {
Slog.v(LOG_TAG, "insert() for user: " + UserHandle.getCallingUserId());
}
String table = getValidTableOrThrow(uri);
// If a legacy table that is gone, done.
if (REMOVED_LEGACY_TABLES.contains(table)) {
return null;
}
String name = values.getAsString(Settings.Secure.NAME);
if (!isKeyValid(name)) {
return null;
}
String value = values.getAsString(Settings.Secure.VALUE);
switch (table) {
case TABLE_GLOBAL: {
if (insertGlobalSetting(name, value, null, false,
UserHandle.getCallingUserId(), false)) {
return Uri.withAppendedPath(Settings.Global.CONTENT_URI, name);
}
} break;
case TABLE_SECURE: {
if (insertSecureSetting(name, value, null, false,
UserHandle.getCallingUserId(), false)) {
return Uri.withAppendedPath(Settings.Secure.CONTENT_URI, name);
}
} break;
case TABLE_SYSTEM: {
if (insertSystemSetting(name, value, UserHandle.getCallingUserId())) {
return Uri.withAppendedPath(Settings.System.CONTENT_URI, name);
}
} break;
default: {
throw new IllegalArgumentException("Bad Uri path:" + uri);
}
}
return null;
}
private boolean parseProviderList(Uri url, ContentValues initialValues, int desiredUser) {
String value = initialValues.getAsString(Settings.Secure.VALUE);
String newProviders = null;
if (value != null && value.length() > 1) {
char prefix = value.charAt(0);
if (prefix == '+' || prefix == '-') {
// skip prefix
value = value.substring(1);
// read list of enabled providers into "providers"
String providers = "";
String[] columns = {Settings.Secure.VALUE};
String where = Settings.Secure.NAME + "=\'" + Settings.Secure.LOCATION_PROVIDERS_ALLOWED + "\'";
Cursor cursor = queryForUser(url, columns, where, null, null, desiredUser);
if (cursor != null && cursor.getCount() == 1) {
try {
cursor.moveToFirst();
providers = cursor.getString(0);
} finally {
cursor.close();
}
}
int index = providers.indexOf(value);
int end = index + value.length();
// check for commas to avoid matching on partial string
if (index > 0 && providers.charAt(index - 1) != ',') index = -1;
if (end < providers.length() && providers.charAt(end) != ',') index = -1;
if (prefix == '+' && index < 0) {
// append the provider to the list if not present
if (providers.length() == 0) {
newProviders = value;
} else {
newProviders = providers + ',' + value;
}
} else if (prefix == '-' && index >= 0) {
// remove the provider from the list if present
// remove leading or trailing comma
if (index > 0) {
index--;
} else if (end < providers.length()) {
end++;
}
newProviders = providers.substring(0, index);
if (end < providers.length()) {
newProviders += providers.substring(end);
}
} else {
// nothing changed, so no need to update the database
return false;
}
if (newProviders != null) {
initialValues.put(Settings.Secure.VALUE, newProviders);
}
}
}
return true;
}
/**
* 在目标插件进程中运行
* @param uri
* @param values
* @return
*/
public static final Uri stubPlugin(Uri uri, ContentValues values) {
//
if (LOG) {
LogDebug.d(PLUGIN_TAG, "stubPlugin values=" + values);
}
String method = values.getAsString(KEY_METHOD);
if (TextUtils.equals(method, METHOD_START_PROCESS)) {
//
Uri rc = new Uri.Builder().scheme("content").authority("process").encodedPath("status").encodedQuery(URL_PARAM_KEY_LOADED + "=" + 1).build();
if (LOG) {
LogDebug.d(PLUGIN_TAG, "plugin provider: return uri=" + rc);
}
long cookie = values.getAsLong(KEY_COOKIE);
// 首次
if (PluginMgrFacade.sPluginMgr.mLocalCookie == 0L) {
if (LOG) {
LogDebug.d(PLUGIN_TAG, "set cookie: " + cookie);
}
//
PluginMgrFacade.sPluginMgr.mLocalCookie = cookie;
} else {
// 常驻进程重新启动了
if (PluginMgrFacade.sPluginMgr.mLocalCookie != cookie) {
if (LOG) {
LogDebug.d(PLUGIN_TAG, "reset cookie: " + cookie);
}
//
PluginMgrFacade.sPluginMgr.mLocalCookie = cookie;
//
PluginProcessMain.installHost();
}
}
return rc;
}
return null;
}
/**
* Installs a word list if it has never been requested.
*
* This is called when a word list is requested, and is available but not installed. It checks
* the conditions for auto-installation: if the dictionary is a main dictionary for this
* language, and it has never been opted out through the dictionary interface, then we start
* installing it. For the user who enables a language and uses it for the first time, the
* dictionary should magically start being used a short time after they start typing.
* The mayPrompt argument indicates whether we should prompt the user for a decision to
* download or not, in case we decide we are in the case where we should download - this
* roughly happens when the current connectivity is 3G. See
* DictionaryProvider#getDictionaryWordListsForContentUri for details.
*/
// As opposed to many other methods, this method does not need the version of the word
// list because it may only install the latest version we know about for this specific
// word list ID / client ID combination.
public static void installIfNeverRequested(final Context context, final String clientId,
final String wordlistId) {
Log.i(TAG, "installIfNeverRequested() : ClientId = " + clientId
+ " : WordListId = " + wordlistId);
final String[] idArray = wordlistId.split(DictionaryProvider.ID_CATEGORY_SEPARATOR);
// If we have a new-format dictionary id (category:manual_id), then use the
// specified category. Otherwise, it is a main dictionary, so force the
// MAIN category upon it.
final String category = 2 == idArray.length ? idArray[0] : MAIN_DICTIONARY_CATEGORY;
if (!MAIN_DICTIONARY_CATEGORY.equals(category)) {
// Not a main dictionary. We only auto-install main dictionaries, so we can return now.
return;
}
if (CommonPreferences.getCommonPreferences(context).contains(wordlistId)) {
// If some kind of settings has been done in the past for this specific id, then
// this is not a candidate for auto-install. Because it already is either true,
// in which case it may be installed or downloading or whatever, and we don't
// need to care about it because it's already handled or being handled, or it's false
// in which case it means the user explicitely turned it off and don't want to have
// it installed. So we quit right away.
return;
}
final SQLiteDatabase db = MetadataDbHelper.getDb(context, clientId);
final ContentValues installCandidate =
MetadataDbHelper.getContentValuesOfLatestAvailableWordlistById(db, wordlistId);
if (MetadataDbHelper.STATUS_AVAILABLE
!= installCandidate.getAsInteger(MetadataDbHelper.STATUS_COLUMN)) {
// If it's not "AVAILABLE", we want to stop now. Because candidates for auto-install
// are lists that we know are available, but we also know have never been installed.
// It does obviously not concern already installed lists, or downloading lists,
// or those that have been disabled, flagged as deleting... So anything else than
// AVAILABLE means we don't auto-install.
return;
}
// We decided against prompting the user for a decision. This may be because we were
// explicitly asked not to, or because we are currently on wi-fi anyway, or because we
// already know the answer to the question. We'll enqueue a request ; StartDownloadAction
// knows to use the correct type of network according to the current settings.
// Also note that once it's auto-installed, a word list will be marked as INSTALLED. It will
// thus receive automatic updates if there are any, which is what we want. If the user does
// not want this word list, they will have to go to the settings and change them, which will
// change the shared preferences. So there is no way for a word list that has been
// auto-installed once to get auto-installed again, and that's what we want.
final ActionBatch actions = new ActionBatch();
WordListMetadata metadata = WordListMetadata.createFromContentValues(installCandidate);
actions.add(new ActionBatch.StartDownloadAction(clientId, metadata));
final String localeString = installCandidate.getAsString(MetadataDbHelper.LOCALE_COLUMN);
// We are in a content provider: we can't do any UI at all. We have to defer the displaying
// itself to the service. Also, we only display this when the user does not have a
// dictionary for this language already. During setup wizard, however, this UI is
// suppressed.
final boolean deviceProvisioned = Settings.Global.getInt(context.getContentResolver(),
Settings.Global.DEVICE_PROVISIONED, 0) != 0;
if (deviceProvisioned) {
final Intent intent = new Intent();
intent.setClass(context, DictionaryService.class);
intent.setAction(DictionaryService.SHOW_DOWNLOAD_TOAST_INTENT_ACTION);
intent.putExtra(DictionaryService.LOCALE_INTENT_ARGUMENT, localeString);
context.startService(intent);
} else {
Log.i(TAG, "installIfNeverRequested() : Don't show download toast");
}
Log.i(TAG, "installIfNeverRequested() : StartDownloadAction for " + metadata);
actions.execute(context, new LogProblemReporter(TAG));
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
if (!canHandleContentProviderApiCall()) return 0;
// Check for invalid id values if provided.
// If it represents a bookmark node then it's the root node and not mutable.
// Otherwise it represents a SQLite row id, so 0 is invalid.
long bookmarkId = INVALID_CONTENT_PROVIDER_ID;
try {
bookmarkId = ContentUris.parseId(uri);
if (bookmarkId == INVALID_CONTENT_PROVIDER_ID) return 0;
} catch (Exception e) {
}
int match = mUriMatcher.match(uri);
int result;
switch (match) {
case URI_MATCH_BOOKMARKS_ID:
String url = null;
if (values.containsKey(Browser.BookmarkColumns.URL)) {
url = values.getAsString(Browser.BookmarkColumns.URL);
}
String title = values.getAsString(Browser.BookmarkColumns.TITLE);
long parentId = INVALID_BOOKMARK_ID;
if (values.containsKey(BOOKMARK_PARENT_ID_PARAM)) {
parentId = values.getAsLong(BOOKMARK_PARENT_ID_PARAM);
}
result = nativeUpdateBookmark(mNativeChromeBrowserProvider, bookmarkId, url, title,
parentId);
updateLastModifiedBookmarkFolder(parentId);
break;
case URL_MATCH_API_BOOKMARK_ID:
result = updateBookmarkFromAPI(values, buildWhereClause(bookmarkId, selection),
selectionArgs);
break;
case URL_MATCH_API_BOOKMARK:
result = updateBookmarkFromAPI(values, selection, selectionArgs);
break;
case URL_MATCH_API_SEARCHES_ID:
result = updateSearchTermFromAPI(values, buildWhereClause(bookmarkId, selection),
selectionArgs);
break;
case URL_MATCH_API_SEARCHES:
result = updateSearchTermFromAPI(values, selection, selectionArgs);
break;
case URL_MATCH_API_HISTORY_CONTENT:
result = updateBookmarkFromAPI(values, buildHistoryWhereClause(selection),
selectionArgs);
break;
case URL_MATCH_API_HISTORY_CONTENT_ID:
result = updateBookmarkFromAPI(values,
buildHistoryWhereClause(bookmarkId, selection), selectionArgs);
break;
case URL_MATCH_API_BOOKMARK_CONTENT:
result = updateBookmarkFromAPI(values, buildBookmarkWhereClause(selection),
selectionArgs);
break;
case URL_MATCH_API_BOOKMARK_CONTENT_ID:
result = updateBookmarkFromAPI(values,
buildBookmarkWhereClause(bookmarkId, selection), selectionArgs);
break;
default:
throw new IllegalArgumentException(TAG + ": update - unknown URL " + uri);
}
if (result != 0) {
getContext().getContentResolver().notifyChange(uri, null);
}
return result;
}
/**
* Updates the repo metadata in the database. All data comes from the
* index file except {@link Repo#id}, which is generated by the database.
* That makes for an two cycle workflow, where first this must be called
* to fetch the {@code Repo.id} from the database, then it is called a
* second time to actually set the repo metadata.
*/
public static void update(Context context, Repo repo, ContentValues values) {
ContentResolver resolver = context.getContentResolver();
// Change the name to the new address. Next time we update the repo
// index file, it will populate the name field with the proper
// name, but the best we can do is guess right now.
if (values.containsKey(Cols.ADDRESS) &&
!values.containsKey(Cols.NAME)) {
String name = Repo.addressToName(values.getAsString(Cols.ADDRESS));
values.put(Cols.NAME, name);
}
/*
* If the repo is signed and has a public key, then guarantee that
* the fingerprint is also set. The stored fingerprint is checked
* when a repo URI is received by FDroid to prevent bad actors from
* overriding repo configs with other keys. So if the fingerprint is
* not stored yet, calculate it and store it. If the fingerprint is
* stored, then check it against the calculated fingerprint just to
* make sure it is correct. If the fingerprint is empty, then store
* the calculated one.
*/
if (values.containsKey(Cols.SIGNING_CERT)) {
String publicKey = values.getAsString(Cols.SIGNING_CERT);
String calcedFingerprint = Utils.calcFingerprint(publicKey);
if (values.containsKey(Cols.FINGERPRINT)) {
String fingerprint = values.getAsString(Cols.FINGERPRINT);
if (!TextUtils.isEmpty(publicKey)) {
if (TextUtils.isEmpty(fingerprint)) {
values.put(Cols.FINGERPRINT, calcedFingerprint);
} else if (!fingerprint.equals(calcedFingerprint)) {
// TODO the UI should represent this error!
Log.e(TAG, "The stored and calculated fingerprints do not match!");
Log.e(TAG, "Stored: " + fingerprint);
Log.e(TAG, "Calculated: " + calcedFingerprint);
}
}
} else if (!TextUtils.isEmpty(publicKey)) {
// no fingerprint in 'values', so put one there
values.put(Cols.FINGERPRINT, calcedFingerprint);
}
}
if (values.containsKey(Cols.IN_USE)) {
Integer inUse = values.getAsInteger(Cols.IN_USE);
if (inUse != null && inUse == 0) {
values.put(Cols.LAST_ETAG, (String) null);
}
}
final Uri uri = getContentUri(repo.getId());
final String[] args = {Long.toString(repo.getId())};
resolver.update(uri, values, Cols._ID + " = ?", args);
repo.setValues(values);
}