use of android.content.OperationApplicationException in project orgzly-android by orgzly.
the class Shelf method syncCreatedAtTimeWithProperty.
/**
* Syncs created-at time and property, using lower value if both exist.
*/
public void syncCreatedAtTimeWithProperty() throws IOException {
boolean useCreatedAtProperty = AppPreferences.createdAt(mContext);
String createdAtPropName = AppPreferences.createdAtProperty(mContext);
if (!useCreatedAtProperty) {
return;
}
ArrayList<ContentProviderOperation> ops = new ArrayList<>();
// If new property is added to the note below, book has to be marked as modified.
Set<Long> bookIds = new HashSet<>();
/*
* Get all notes.
* This is slow and only notes that have either created-at time or created-at property
* are actually needed. But since this syncing (triggered on preference change) is done
* so rarely, we don't bother.
*/
try (Cursor cursor = mContext.getContentResolver().query(ProviderContract.Notes.ContentUri.notes(), null, null, null, null)) {
if (cursor != null) {
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
/* Get current heading string. */
Note note = NotesClient.fromCursor(cursor);
/* Skip root node. */
if (note.getPosition().getLevel() == 0) {
continue;
}
long dbCreatedAt = note.getCreatedAt();
OrgProperties properties = NotesClient.getNoteProperties(mContext, NotesClient.idFromCursor(cursor));
String dbPropValue = properties.get(createdAtPropName);
OrgDateTime dbPropertyValue = OrgDateTime.doParse(dbPropValue);
// Compare dbCreatedAt and dbPropertyValue
if (dbCreatedAt > 0 && dbPropertyValue == null) {
addOpUpdateProperty(ops, note, createdAtPropName, dbCreatedAt, dbPropValue, bookIds);
} else if (dbCreatedAt > 0 && dbPropertyValue != null) {
// Use older created-at
if (dbPropertyValue.getCalendar().getTimeInMillis() < dbCreatedAt) {
addOpUpdateCreatedAt(ops, note, dbPropertyValue, note.getCreatedAt());
} else {
addOpUpdateProperty(ops, note, createdAtPropName, dbCreatedAt, dbPropValue, bookIds);
}
// Or prefer property and set created-at time?
// addOpUpdateCreatedAt(ops, note.getId(), dbPropertyValue, note.getCreatedAt());
} else if (dbCreatedAt == 0 && dbPropertyValue != null) {
addOpUpdateCreatedAt(ops, note, dbPropertyValue, note.getCreatedAt());
}
// else: Neither created-at time nor property are set
}
}
}
long time = System.currentTimeMillis();
for (long bookId : bookIds) {
BooksClient.setModifiedTime(mContext, bookId, time);
}
/*
* Apply batch.
*/
try {
mContext.getContentResolver().applyBatch(ProviderContract.AUTHORITY, ops);
} catch (RemoteException | OperationApplicationException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
notifyDataChanged(mContext);
syncOnNoteUpdate();
}
use of android.content.OperationApplicationException in project android_frameworks_base by crdroidandroid.
the class TvInputManagerService method registerBroadcastReceivers.
private void registerBroadcastReceivers() {
PackageMonitor monitor = new PackageMonitor() {
private void buildTvInputList(String[] packages) {
synchronized (mLock) {
if (mCurrentUserId == getChangingUserId()) {
buildTvInputListLocked(mCurrentUserId, packages);
buildTvContentRatingSystemListLocked(mCurrentUserId);
}
}
}
@Override
public void onPackageUpdateFinished(String packageName, int uid) {
if (DEBUG)
Slog.d(TAG, "onPackageUpdateFinished(packageName=" + packageName + ")");
// This callback is invoked when the TV input is reinstalled.
// In this case, isReplacing() always returns true.
buildTvInputList(new String[] { packageName });
}
@Override
public void onPackagesAvailable(String[] packages) {
if (DEBUG) {
Slog.d(TAG, "onPackagesAvailable(packages=" + Arrays.toString(packages) + ")");
}
// available.
if (isReplacing()) {
buildTvInputList(packages);
}
}
@Override
public void onPackagesUnavailable(String[] packages) {
// unavailable.
if (DEBUG) {
Slog.d(TAG, "onPackagesUnavailable(packages=" + Arrays.toString(packages) + ")");
}
if (isReplacing()) {
buildTvInputList(packages);
}
}
@Override
public void onSomePackagesChanged() {
// the TV inputs.
if (DEBUG)
Slog.d(TAG, "onSomePackagesChanged()");
if (isReplacing()) {
if (DEBUG)
Slog.d(TAG, "Skipped building TV input list due to replacing");
// methods instead.
return;
}
buildTvInputList(null);
}
@Override
public boolean onPackageChanged(String packageName, int uid, String[] components) {
// the update can be handled in {@link #onSomePackagesChanged}.
return true;
}
@Override
public void onPackageRemoved(String packageName, int uid) {
synchronized (mLock) {
UserState userState = getOrCreateUserStateLocked(getChangingUserId());
if (!userState.packageSet.contains(packageName)) {
// Not a TV input package.
return;
}
}
ArrayList<ContentProviderOperation> operations = new ArrayList<>();
String selection = TvContract.BaseTvColumns.COLUMN_PACKAGE_NAME + "=?";
String[] selectionArgs = { packageName };
operations.add(ContentProviderOperation.newDelete(TvContract.Channels.CONTENT_URI).withSelection(selection, selectionArgs).build());
operations.add(ContentProviderOperation.newDelete(TvContract.Programs.CONTENT_URI).withSelection(selection, selectionArgs).build());
operations.add(ContentProviderOperation.newDelete(TvContract.WatchedPrograms.CONTENT_URI).withSelection(selection, selectionArgs).build());
ContentProviderResult[] results = null;
try {
ContentResolver cr = getContentResolverForUser(getChangingUserId());
results = cr.applyBatch(TvContract.AUTHORITY, operations);
} catch (RemoteException | OperationApplicationException e) {
Slog.e(TAG, "error in applyBatch", e);
}
if (DEBUG) {
Slog.d(TAG, "onPackageRemoved(packageName=" + packageName + ", uid=" + uid + ")");
Slog.d(TAG, "results=" + results);
}
}
};
monitor.register(mContext, null, UserHandle.ALL, true);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_USER_SWITCHED);
intentFilter.addAction(Intent.ACTION_USER_REMOVED);
mContext.registerReceiverAsUser(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (Intent.ACTION_USER_SWITCHED.equals(action)) {
switchUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0));
} else if (Intent.ACTION_USER_REMOVED.equals(action)) {
removeUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0));
}
}
}, UserHandle.ALL, intentFilter, null, null);
}
use of android.content.OperationApplicationException in project android_frameworks_base by DirtyUnicorns.
the class TvInputManagerService method registerBroadcastReceivers.
private void registerBroadcastReceivers() {
PackageMonitor monitor = new PackageMonitor() {
private void buildTvInputList(String[] packages) {
synchronized (mLock) {
if (mCurrentUserId == getChangingUserId()) {
buildTvInputListLocked(mCurrentUserId, packages);
buildTvContentRatingSystemListLocked(mCurrentUserId);
}
}
}
@Override
public void onPackageUpdateFinished(String packageName, int uid) {
if (DEBUG)
Slog.d(TAG, "onPackageUpdateFinished(packageName=" + packageName + ")");
// This callback is invoked when the TV input is reinstalled.
// In this case, isReplacing() always returns true.
buildTvInputList(new String[] { packageName });
}
@Override
public void onPackagesAvailable(String[] packages) {
if (DEBUG) {
Slog.d(TAG, "onPackagesAvailable(packages=" + Arrays.toString(packages) + ")");
}
// available.
if (isReplacing()) {
buildTvInputList(packages);
}
}
@Override
public void onPackagesUnavailable(String[] packages) {
// unavailable.
if (DEBUG) {
Slog.d(TAG, "onPackagesUnavailable(packages=" + Arrays.toString(packages) + ")");
}
if (isReplacing()) {
buildTvInputList(packages);
}
}
@Override
public void onSomePackagesChanged() {
// the TV inputs.
if (DEBUG)
Slog.d(TAG, "onSomePackagesChanged()");
if (isReplacing()) {
if (DEBUG)
Slog.d(TAG, "Skipped building TV input list due to replacing");
// methods instead.
return;
}
buildTvInputList(null);
}
@Override
public boolean onPackageChanged(String packageName, int uid, String[] components) {
// the update can be handled in {@link #onSomePackagesChanged}.
return true;
}
@Override
public void onPackageRemoved(String packageName, int uid) {
synchronized (mLock) {
UserState userState = getOrCreateUserStateLocked(getChangingUserId());
if (!userState.packageSet.contains(packageName)) {
// Not a TV input package.
return;
}
}
ArrayList<ContentProviderOperation> operations = new ArrayList<>();
String selection = TvContract.BaseTvColumns.COLUMN_PACKAGE_NAME + "=?";
String[] selectionArgs = { packageName };
operations.add(ContentProviderOperation.newDelete(TvContract.Channels.CONTENT_URI).withSelection(selection, selectionArgs).build());
operations.add(ContentProviderOperation.newDelete(TvContract.Programs.CONTENT_URI).withSelection(selection, selectionArgs).build());
operations.add(ContentProviderOperation.newDelete(TvContract.WatchedPrograms.CONTENT_URI).withSelection(selection, selectionArgs).build());
ContentProviderResult[] results = null;
try {
ContentResolver cr = getContentResolverForUser(getChangingUserId());
results = cr.applyBatch(TvContract.AUTHORITY, operations);
} catch (RemoteException | OperationApplicationException e) {
Slog.e(TAG, "error in applyBatch", e);
}
if (DEBUG) {
Slog.d(TAG, "onPackageRemoved(packageName=" + packageName + ", uid=" + uid + ")");
Slog.d(TAG, "results=" + results);
}
}
};
monitor.register(mContext, null, UserHandle.ALL, true);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_USER_SWITCHED);
intentFilter.addAction(Intent.ACTION_USER_REMOVED);
mContext.registerReceiverAsUser(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (Intent.ACTION_USER_SWITCHED.equals(action)) {
switchUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0));
} else if (Intent.ACTION_USER_REMOVED.equals(action)) {
removeUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0));
}
}
}, UserHandle.ALL, intentFilter, null, null);
}
use of android.content.OperationApplicationException in project android_packages_apps_Dialer by LineageOS.
the class AnnotatedCallLogContentProvider method applyBatch.
/**
* {@inheritDoc}
*
* <p>Note: When applyBatch is used with the AnnotatedCallLog, only a single notification for the
* content URI is generated, not individual notifications for each affected URI.
*/
@NonNull
@Override
public ContentProviderResult[] applyBatch(@NonNull ArrayList<ContentProviderOperation> operations) throws OperationApplicationException {
ContentProviderResult[] results = new ContentProviderResult[operations.size()];
if (operations.isEmpty()) {
return results;
}
SQLiteDatabase database = databaseHelper.getWritableDatabase();
try {
applyingBatch.set(true);
database.beginTransaction();
for (int i = 0; i < operations.size(); i++) {
ContentProviderOperation operation = operations.get(i);
int match = uriMatcher.match(operation.getUri());
switch(match) {
case ANNOTATED_CALL_LOG_TABLE_CODE:
case ANNOTATED_CALL_LOG_TABLE_ID_CODE:
// These are allowed values, continue.
break;
case COALESCED_ANNOTATED_CALL_LOG_TABLE_CODE:
throw new UnsupportedOperationException("coalesced call log does not support applyBatch");
default:
throw new IllegalArgumentException("Unknown uri: " + operation.getUri());
}
ContentProviderResult result = operation.apply(this, results, i);
if (operations.get(i).isInsert()) {
if (result.uri == null) {
throw new OperationApplicationException("error inserting row");
}
} else if (result.count == 0) {
/*
* The batches built by MutationApplier happen to contain operations in order of:
*
* 1. Inserts
* 2. Updates
* 3. Deletes
*
* Let's say the last row in the table is row Z, and MutationApplier wishes to update it,
* as well as insert row A. When row A gets inserted, row Z will be deleted via the
* trigger if the table is full. Then later, when we try to process the update for row Z,
* it won't exist.
*/
LogUtil.w("AnnotatedCallLogContentProvider.applyBatch", "update or delete failed, possibly because row got cleaned up");
}
results[i] = result;
}
database.setTransactionSuccessful();
} finally {
applyingBatch.set(false);
database.endTransaction();
}
notifyChange(AnnotatedCallLog.CONTENT_URI);
return results;
}
use of android.content.OperationApplicationException in project Signal-Android by signalapp.
the class DirectoryHelper method updateContactsDatabase.
private static void updateContactsDatabase(@NonNull Context context, @NonNull List<Address> activeAddresses, boolean removeMissing) {
Optional<AccountHolder> account = getOrCreateAccount(context);
if (account.isPresent()) {
try {
DatabaseFactory.getContactsDatabase(context).setRegisteredUsers(account.get().getAccount(), activeAddresses, removeMissing);
Cursor cursor = ContactAccessor.getInstance().getAllSystemContacts(context);
RecipientDatabase.BulkOperationsHandle handle = DatabaseFactory.getRecipientDatabase(context).resetAllSystemContactInfo();
try {
while (cursor != null && cursor.moveToNext()) {
String number = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER));
if (!TextUtils.isEmpty(number)) {
Address address = Address.fromExternal(context, number);
String displayName = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String contactPhotoUri = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.PHOTO_URI));
String contactLabel = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.LABEL));
Uri contactUri = ContactsContract.Contacts.getLookupUri(cursor.getLong(cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone._ID)), cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.LOOKUP_KEY)));
handle.setSystemContactInfo(address, displayName, contactPhotoUri, contactLabel, contactUri.toString());
}
}
} finally {
handle.finish();
}
} catch (RemoteException | OperationApplicationException e) {
Log.w(TAG, e);
}
}
}
Aggregations