use of com.android.calendar.CloudNotificationBackplane in project Etar-Calendar by Etar-Group.
the class GlobalDismissManager method dismissGlobally.
/**
* Globally dismiss notifications that are backed by the same events.
*
* @param context application context
* @param alarmIds Unique identifiers for events that have been dismissed by the user.
* @return true if notification_sender_id is available
*/
public static void dismissGlobally(final Context context, final List<AlarmId> alarmIds) {
final String senderId = context.getResources().getString(R.string.notification_sender_id);
if ("".equals(senderId)) {
Log.i(TAG, "no sender configured");
return;
}
Set<Long> eventIds = new HashSet<Long>(alarmIds.size());
for (AlarmId alarmId : alarmIds) {
eventIds.add(alarmId.mEventId);
}
// find the mapping between calendars and events
Map<Long, Long> eventsToCalendars = lookupEventToCalendarMap(context, eventIds);
if (eventsToCalendars.isEmpty()) {
Log.d(TAG, "found no calendars for events");
return;
}
Set<Long> calendars = new LinkedHashSet<Long>();
calendars.addAll(eventsToCalendars.values());
// find the accounts associated with those calendars
Map<Long, Pair<String, String>> calendarsToAccounts = lookupCalendarToAccountMap(context, calendars);
if (calendarsToAccounts.isEmpty()) {
Log.d(TAG, "found no accounts for calendars");
return;
}
// TODO group by account to reduce queries
Map<String, String> syncIdToAccount = new HashMap<String, String>();
Map<Long, String> eventIdToSyncId = new HashMap<Long, String>();
ContentResolver resolver = context.getContentResolver();
for (Long eventId : eventsToCalendars.keySet()) {
Long calendar = eventsToCalendars.get(eventId);
Pair<String, String> account = calendarsToAccounts.get(calendar);
if (GOOGLE_ACCOUNT_TYPE.equals(account.first)) {
Uri uri = asSync(Events.CONTENT_URI, account.first, account.second);
Cursor cursor = resolver.query(uri, EVENT_SYNC_PROJECTION, Events._ID + " = " + eventId, null, null);
try {
cursor.moveToPosition(-1);
int sync_id_idx = cursor.getColumnIndex(Events._SYNC_ID);
if (sync_id_idx != -1) {
while (cursor.moveToNext()) {
String syncId = cursor.getString(sync_id_idx);
syncIdToAccount.put(syncId, account.second);
eventIdToSyncId.put(eventId, syncId);
}
}
} finally {
cursor.close();
}
}
}
if (syncIdToAccount.isEmpty()) {
Log.d(TAG, "found no syncIds for events");
return;
}
// TODO group by account to reduce packets
CloudNotificationBackplane cnb = ExtensionsFactory.getCloudNotificationBackplane();
if (cnb.open(context)) {
for (AlarmId alarmId : alarmIds) {
String syncId = eventIdToSyncId.get(alarmId.mEventId);
String account = syncIdToAccount.get(syncId);
Bundle data = new Bundle();
data.putString(SYNC_ID, syncId);
data.putString(START_TIME, Long.toString(alarmId.mStart));
data.putString(ACCOUNT_NAME, account);
try {
cnb.send(account, syncId + ":" + alarmId.mStart, data);
} catch (IOException e) {
// TODO save a note to try again later
}
}
cnb.close();
}
}
use of com.android.calendar.CloudNotificationBackplane in project Etar-Calendar by Etar-Group.
the class GlobalDismissManager method processEventIds.
/**
* Look for unknown accounts in a set of events and associate with them.
* Returns immediately, processing happens in the background.
*
* @param context application context
* @param eventIds IDs for events that have posted notifications that may be
* dismissed.
*/
public static void processEventIds(Context context, Set<Long> eventIds) {
final String senderId = context.getResources().getString(R.string.notification_sender_id);
if (senderId == null || senderId.isEmpty()) {
Log.i(TAG, "no sender configured");
return;
}
Map<Long, Long> eventsToCalendars = lookupEventToCalendarMap(context, eventIds);
Set<Long> calendars = new LinkedHashSet<Long>();
calendars.addAll(eventsToCalendars.values());
if (calendars.isEmpty()) {
Log.d(TAG, "found no calendars for events");
return;
}
Map<Long, Pair<String, String>> calendarsToAccounts = lookupCalendarToAccountMap(context, calendars);
if (calendarsToAccounts.isEmpty()) {
Log.d(TAG, "found no accounts for calendars");
return;
}
// filter out non-google accounts (necessary?)
Set<String> accounts = new LinkedHashSet<String>();
for (Pair<String, String> accountPair : calendarsToAccounts.values()) {
if (GOOGLE_ACCOUNT_TYPE.equals(accountPair.first)) {
accounts.add(accountPair.second);
}
}
// filter out accounts we already know about
SharedPreferences prefs = context.getSharedPreferences(GLOBAL_DISMISS_MANAGER_PREFS, Context.MODE_PRIVATE);
Set<String> existingAccounts = prefs.getStringSet(ACCOUNT_KEY, new HashSet<String>());
accounts.removeAll(existingAccounts);
if (accounts.isEmpty()) {
// nothing to do, we've already registered all the accounts.
return;
}
// subscribe to remaining accounts
CloudNotificationBackplane cnb = ExtensionsFactory.getCloudNotificationBackplane();
if (cnb.open(context)) {
for (String account : accounts) {
try {
if (cnb.subscribeToGroup(senderId, account, account)) {
existingAccounts.add(account);
}
} catch (IOException e) {
// Try again, next time the account triggers and alert.
}
}
cnb.close();
prefs.edit().putStringSet(ACCOUNT_KEY, existingAccounts).commit();
}
}
use of com.android.calendar.CloudNotificationBackplane in project Etar-Calendar by Etar-Group.
the class GlobalDismissManager method syncSenderDismissCache.
/**
* Some events don't have a global sync_id when they are dismissed. We need to wait
* until the data provider is updated before we can send the global dismiss message.
*/
public static void syncSenderDismissCache(Context context) {
final String senderId = context.getResources().getString(R.string.notification_sender_id);
if ("".equals(senderId)) {
Log.i(TAG, "no sender configured");
return;
}
CloudNotificationBackplane cnb = ExtensionsFactory.getCloudNotificationBackplane();
if (!cnb.open(context)) {
Log.i(TAG, "Unable to open cloud notification backplane");
}
long currentTime = System.currentTimeMillis();
ContentResolver resolver = context.getContentResolver();
synchronized (sSenderDismissCache) {
Iterator<Map.Entry<LocalDismissId, Long>> it = sSenderDismissCache.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<LocalDismissId, Long> entry = it.next();
LocalDismissId dismissId = entry.getKey();
Uri uri = asSync(Events.CONTENT_URI, dismissId.mAccountType, dismissId.mAccountName);
Cursor cursor = resolver.query(uri, EVENT_SYNC_PROJECTION, Events._ID + " = " + dismissId.mEventId, null, null);
try {
cursor.moveToPosition(-1);
int sync_id_idx = cursor.getColumnIndex(Events._SYNC_ID);
if (sync_id_idx != -1) {
while (cursor.moveToNext()) {
String syncId = cursor.getString(sync_id_idx);
if (syncId != null) {
Bundle data = new Bundle();
long startTime = dismissId.mStartTime;
String accountName = dismissId.mAccountName;
data.putString(SYNC_ID, syncId);
data.putString(START_TIME, Long.toString(startTime));
data.putString(ACCOUNT_NAME, accountName);
try {
cnb.send(accountName, syncId + ":" + startTime, data);
it.remove();
} catch (IOException e) {
// If we couldn't send, then leave dismissal in cache
}
}
}
}
} finally {
cursor.close();
}
// Remove old dismissals from cache after a certain time period
if (currentTime - entry.getValue() > TIME_TO_LIVE) {
it.remove();
}
}
}
cnb.close();
}
Aggregations