diff options
Diffstat (limited to 'core/java')
8 files changed, 151 insertions, 468 deletions
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index bba6caf..76a6a8e 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -659,8 +659,8 @@ public class Notification implements Parcelable /** * @hide - * Extra added by NotificationManagerService to indicate whether a NotificationScorer - * modified the Notifications's score. + * Extra added by NotificationManagerService to indicate whether + * the Notifications's score has been modified. */ public static final String EXTRA_SCORE_MODIFIED = "android.scoreModified"; diff --git a/core/java/android/service/notification/INotificationListener.aidl b/core/java/android/service/notification/INotificationListener.aidl index d4b29d8..d4919eb 100644 --- a/core/java/android/service/notification/INotificationListener.aidl +++ b/core/java/android/service/notification/INotificationListener.aidl @@ -17,11 +17,15 @@ package android.service.notification; import android.service.notification.StatusBarNotification; +import android.service.notification.NotificationOrderUpdate; /** @hide */ oneway interface INotificationListener { - void onListenerConnected(in String[] notificationKeys); - void onNotificationPosted(in StatusBarNotification notification); - void onNotificationRemoved(in StatusBarNotification notification); + void onListenerConnected(in NotificationOrderUpdate update); + void onNotificationPosted(in StatusBarNotification notification, + in NotificationOrderUpdate update); + void onNotificationRemoved(in StatusBarNotification notification, + in NotificationOrderUpdate update); + void onNotificationOrderUpdate(in NotificationOrderUpdate update); }
\ No newline at end of file diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java index 3673f03..a94f45a 100644 --- a/core/java/android/service/notification/NotificationListenerService.java +++ b/core/java/android/service/notification/NotificationListenerService.java @@ -22,10 +22,13 @@ import android.app.Service; import android.content.Context; import android.content.Intent; import android.os.IBinder; +import android.os.RemoteException; import android.os.ServiceManager; -import android.os.UserHandle; import android.util.Log; +import java.util.Comparator; +import java.util.HashMap; + /** * A service that receives calls from the system when new notifications are posted or removed. * <p>To extend this class, you must declare the service in your manifest file with @@ -46,6 +49,7 @@ public abstract class NotificationListenerService extends Service { + "[" + getClass().getSimpleName() + "]"; private INotificationListenerWrapper mWrapper = null; + private String[] mNotificationKeys; private INotificationManager mNoMan; @@ -95,6 +99,15 @@ public abstract class NotificationListenerService extends Service { // optional } + /** + * Implement this method to be notified when the notification order cahnges. + * + * Call {@link #getOrderedNotificationKeys()} to retrieve the new order. + */ + public void onNotificationOrderUpdate() { + // optional + } + private final INotificationManager getNotificationInterface() { if (mNoMan == null) { mNoMan = INotificationManager.Stub.asInterface( @@ -202,7 +215,7 @@ public abstract class NotificationListenerService extends Service { * Request the list of outstanding notifications (that is, those that are visible to the * current user). Useful when you don't know what's already been posted. * - * @return An array of active notifications. + * @return An array of active notifications, sorted in natural order. */ public StatusBarNotification[] getActiveNotifications() { return getActiveNotifications(null /*all*/); @@ -213,7 +226,8 @@ public abstract class NotificationListenerService extends Service { * current user). Useful when you don't know what's already been posted. * * @param keys A specific list of notification keys, or {@code null} for all. - * @return An array of active notifications. + * @return An array of active notifications, sorted in natural order + * if {@code keys} is {@code null}. */ public StatusBarNotification[] getActiveNotifications(String[] keys) { if (!isBound()) return null; @@ -226,21 +240,15 @@ public abstract class NotificationListenerService extends Service { } /** - * Request the list of outstanding notification keys(that is, those that are visible to the - * current user). You can use the notification keys for subsequent retrieval via + * Request the list of notification keys in their current natural order. + * You can use the notification keys for subsequent retrieval via * {@link #getActiveNotifications(String[]) or dismissal via * {@link #cancelNotifications(String[]). * - * @return An array of active notification keys. + * @return An array of active notification keys, in their natural order. */ - public String[] getActiveNotificationKeys() { - if (!isBound()) return null; - try { - return getNotificationInterface().getActiveNotificationKeysFromListener(mWrapper); - } catch (android.os.RemoteException ex) { - Log.v(TAG, "Unable to contact notification manager", ex); - } - return null; + public String[] getOrderedNotificationKeys() { + return mNotificationKeys; } @Override @@ -261,28 +269,60 @@ public abstract class NotificationListenerService extends Service { private class INotificationListenerWrapper extends INotificationListener.Stub { @Override - public void onNotificationPosted(StatusBarNotification sbn) { + public void onNotificationPosted(StatusBarNotification sbn, + NotificationOrderUpdate update) { try { - NotificationListenerService.this.onNotificationPosted(sbn); + // protect subclass from concurrent modifications of (@link mNotificationKeys}. + synchronized (mWrapper) { + updateNotificationKeys(update); + NotificationListenerService.this.onNotificationPosted(sbn); + } } catch (Throwable t) { - Log.w(TAG, "Error running onNotificationPosted", t); + Log.w(TAG, "Error running onOrderedNotificationPosted", t); } } @Override - public void onNotificationRemoved(StatusBarNotification sbn) { + public void onNotificationRemoved(StatusBarNotification sbn, + NotificationOrderUpdate update) { try { - NotificationListenerService.this.onNotificationRemoved(sbn); + // protect subclass from concurrent modifications of (@link mNotificationKeys}. + synchronized (mWrapper) { + updateNotificationKeys(update); + NotificationListenerService.this.onNotificationRemoved(sbn); + } } catch (Throwable t) { Log.w(TAG, "Error running onNotificationRemoved", t); } } @Override - public void onListenerConnected(String[] notificationKeys) { + public void onListenerConnected(NotificationOrderUpdate update) { try { - NotificationListenerService.this.onListenerConnected(notificationKeys); + // protect subclass from concurrent modifications of (@link mNotificationKeys}. + synchronized (mWrapper) { + updateNotificationKeys(update); + NotificationListenerService.this.onListenerConnected(mNotificationKeys); + } } catch (Throwable t) { Log.w(TAG, "Error running onListenerConnected", t); } } + @Override + public void onNotificationOrderUpdate(NotificationOrderUpdate update) + throws RemoteException { + try { + // protect subclass from concurrent modifications of (@link mNotificationKeys}. + synchronized (mWrapper) { + updateNotificationKeys(update); + NotificationListenerService.this.onNotificationOrderUpdate(); + } + } catch (Throwable t) { + Log.w(TAG, "Error running onNotificationOrderUpdate", t); + } + } + } + + private void updateNotificationKeys(NotificationOrderUpdate update) { + // TODO: avoid garbage by comparing the lists + mNotificationKeys = update.getOrderedKeys(); } } diff --git a/core/java/android/service/notification/NotificationOrderUpdate.aidl b/core/java/android/service/notification/NotificationOrderUpdate.aidl new file mode 100644 index 0000000..5d50641 --- /dev/null +++ b/core/java/android/service/notification/NotificationOrderUpdate.aidl @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2014, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.service.notification; + +parcelable NotificationOrderUpdate; diff --git a/core/java/android/service/notification/NotificationOrderUpdate.java b/core/java/android/service/notification/NotificationOrderUpdate.java new file mode 100644 index 0000000..20e19a3 --- /dev/null +++ b/core/java/android/service/notification/NotificationOrderUpdate.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.service.notification; + +import android.os.Parcel; +import android.os.Parcelable; + +public class NotificationOrderUpdate implements Parcelable { + // TODO replace this with an update instead of the whole array + private final String[] mKeys; + + /** @hide */ + public NotificationOrderUpdate(String[] keys) { + this.mKeys = keys; + } + + public NotificationOrderUpdate(Parcel in) { + this.mKeys = in.readStringArray(); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeStringArray(this.mKeys); + } + + public static final Parcelable.Creator<NotificationOrderUpdate> CREATOR + = new Parcelable.Creator<NotificationOrderUpdate>() { + public NotificationOrderUpdate createFromParcel(Parcel parcel) { + return new NotificationOrderUpdate(parcel); + } + + public NotificationOrderUpdate[] newArray(int size) { + return new NotificationOrderUpdate[size]; + } + }; + + /** + * @hide + * @return ordered list of keys + */ + String[] getOrderedKeys() { + return mKeys; + } +} diff --git a/core/java/com/android/internal/notification/DemoContactNotificationScorer.java b/core/java/com/android/internal/notification/DemoContactNotificationScorer.java deleted file mode 100644 index f484724..0000000 --- a/core/java/com/android/internal/notification/DemoContactNotificationScorer.java +++ /dev/null @@ -1,188 +0,0 @@ -/* -* Copyright (C) 2013 The Android Open Source Project -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package com.android.internal.notification; - -import android.app.Notification; -import android.content.Context; -import android.database.Cursor; -import android.net.Uri; -import android.os.Bundle; -import android.provider.ContactsContract; -import android.provider.Settings; -import android.text.SpannableString; -import android.util.Slog; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -/** - * This NotificationScorer bumps up the priority of notifications that contain references to the - * display names of starred contacts. The references it picks up are spannable strings which, in - * their entirety, match the display name of some starred contact. The magnitude of the bump ranges - * from 0 to 15 (assuming NOTIFICATION_PRIORITY_MULTIPLIER = 10) depending on the initial score, and - * the mapping is defined by priorityBumpMap. In a production version of this scorer, a notification - * extra will be used to specify contact identifiers. - */ - -public class DemoContactNotificationScorer implements NotificationScorer { - private static final String TAG = "DemoContactNotificationScorer"; - private static final boolean DBG = false; - - protected static final boolean ENABLE_CONTACT_SCORER = true; - private static final String SETTING_ENABLE_SCORER = "contact_scorer_enabled"; - protected boolean mEnabled; - - // see NotificationManagerService - private static final int NOTIFICATION_PRIORITY_MULTIPLIER = 10; - - private Context mContext; - - private static final List<String> RELEVANT_KEYS_LIST = Arrays.asList( - Notification.EXTRA_INFO_TEXT, Notification.EXTRA_TEXT, Notification.EXTRA_TEXT_LINES, - Notification.EXTRA_SUB_TEXT, Notification.EXTRA_TITLE - ); - - private static final String[] PROJECTION = new String[] { - ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME - }; - - private static final Uri CONTACTS_URI = ContactsContract.Contacts.CONTENT_URI; - - private static List<String> extractSpannedStrings(CharSequence charSequence) { - if (charSequence == null) return Collections.emptyList(); - if (!(charSequence instanceof SpannableString)) { - return Arrays.asList(charSequence.toString()); - } - SpannableString spannableString = (SpannableString)charSequence; - // get all spans - Object[] ssArr = spannableString.getSpans(0, spannableString.length(), Object.class); - // spanned string sequences - ArrayList<String> sss = new ArrayList<String>(); - for (Object spanObj : ssArr) { - try { - sss.add(spannableString.subSequence(spannableString.getSpanStart(spanObj), - spannableString.getSpanEnd(spanObj)).toString()); - } catch(StringIndexOutOfBoundsException e) { - Slog.e(TAG, "Bad indices when extracting spanned subsequence", e); - } - } - return sss; - }; - - private static String getQuestionMarksInParens(int n) { - StringBuilder sb = new StringBuilder("("); - for (int i = 0; i < n; i++) { - if (sb.length() > 1) sb.append(','); - sb.append('?'); - } - sb.append(")"); - return sb.toString(); - } - - private boolean hasStarredContact(Bundle extras) { - if (extras == null) return false; - ArrayList<String> qStrings = new ArrayList<String>(); - // build list to query against the database for display names. - for (String rk: RELEVANT_KEYS_LIST) { - if (extras.get(rk) == null) { - continue; - } else if (extras.get(rk) instanceof CharSequence) { - qStrings.addAll(extractSpannedStrings((CharSequence) extras.get(rk))); - } else if (extras.get(rk) instanceof CharSequence[]) { - // this is intended for Notification.EXTRA_TEXT_LINES - for (CharSequence line: (CharSequence[]) extras.get(rk)){ - qStrings.addAll(extractSpannedStrings(line)); - } - } else { - Slog.w(TAG, "Strange, the extra " + rk + " is of unexpected type."); - } - } - if (qStrings.isEmpty()) return false; - String[] qStringsArr = qStrings.toArray(new String[qStrings.size()]); - - String selection = ContactsContract.Contacts.DISPLAY_NAME + " IN " - + getQuestionMarksInParens(qStringsArr.length) + " AND " - + ContactsContract.Contacts.STARRED+" ='1'"; - - Cursor c = null; - try { - c = mContext.getContentResolver().query( - CONTACTS_URI, PROJECTION, selection, qStringsArr, null); - if (c != null) return c.getCount() > 0; - } catch(Throwable t) { - Slog.w(TAG, "Problem getting content resolver or performing contacts query.", t); - } finally { - if (c != null) { - c.close(); - } - } - return false; - } - - private final static int clamp(int x, int low, int high) { - return (x < low) ? low : ((x > high) ? high : x); - } - - private static int priorityBumpMap(int incomingScore) { - //assumption is that scale runs from [-2*pm, 2*pm] - int pm = NOTIFICATION_PRIORITY_MULTIPLIER; - int theScore = incomingScore; - // enforce input in range - theScore = clamp(theScore, -2 * pm, 2 * pm); - if (theScore != incomingScore) return incomingScore; - // map -20 -> -20 and -10 -> 5 (when pm = 10) - if (theScore <= -pm) { - theScore += 1.5 * (theScore + 2 * pm); - } else { - // map 0 -> 10, 10 -> 15, 20 -> 20; - theScore += 0.5 * (2 * pm - theScore); - } - if (DBG) Slog.v(TAG, "priorityBumpMap: score before: " + incomingScore - + ", score after " + theScore + "."); - return theScore; - } - - @Override - public void initialize(Context context) { - if (DBG) Slog.v(TAG, "Initializing " + getClass().getSimpleName() + "."); - mContext = context; - mEnabled = ENABLE_CONTACT_SCORER && 1 == Settings.Global.getInt( - mContext.getContentResolver(), SETTING_ENABLE_SCORER, 0); - } - - @Override - public int getScore(Notification notification, int score) { - if (notification == null || !mEnabled) { - if (DBG) Slog.w(TAG, "empty notification? scorer disabled?"); - return score; - } - boolean hasStarredPriority = hasStarredContact(notification.extras); - - if (DBG) { - if (hasStarredPriority) { - Slog.v(TAG, "Notification references starred contact. Promoted!"); - } else { - Slog.v(TAG, "Notification lacks any starred contact reference. Not promoted!"); - } - } - if (hasStarredPriority) score = priorityBumpMap(score); - return score; - } -} - diff --git a/core/java/com/android/internal/notification/NotificationScorer.java b/core/java/com/android/internal/notification/NotificationScorer.java deleted file mode 100644 index 863c08c..0000000 --- a/core/java/com/android/internal/notification/NotificationScorer.java +++ /dev/null @@ -1,27 +0,0 @@ -/* -* Copyright (C) 2013 The Android Open Source Project -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package com.android.internal.notification; - -import android.app.Notification; -import android.content.Context; - -public interface NotificationScorer { - - public void initialize(Context context); - public int getScore(Notification notification, int score); - -} diff --git a/core/java/com/android/internal/notification/PeopleNotificationScorer.java b/core/java/com/android/internal/notification/PeopleNotificationScorer.java deleted file mode 100644 index efb5f63..0000000 --- a/core/java/com/android/internal/notification/PeopleNotificationScorer.java +++ /dev/null @@ -1,227 +0,0 @@ -/* -* Copyright (C) 2014 The Android Open Source Project -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package com.android.internal.notification; - -import android.app.Notification; -import android.content.Context; -import android.database.Cursor; -import android.net.Uri; -import android.os.Bundle; -import android.provider.ContactsContract; -import android.provider.ContactsContract.Contacts; -import android.provider.Settings; -import android.text.TextUtils; -import android.util.LruCache; -import android.util.Slog; - -/** - * This {@link NotificationScorer} attempts to validate people references. - * Also elevates the priority of real people. - */ -public class PeopleNotificationScorer implements NotificationScorer { - private static final String TAG = "PeopleNotificationScorer"; - private static final boolean DBG = false; - - private static final boolean ENABLE_PEOPLE_SCORER = true; - private static final String SETTING_ENABLE_PEOPLE_SCORER = "people_scorer_enabled"; - private static final String[] LOOKUP_PROJECTION = { Contacts._ID }; - private static final int MAX_PEOPLE = 10; - private static final int PEOPLE_CACHE_SIZE = 200; - // see NotificationManagerService - private static final int NOTIFICATION_PRIORITY_MULTIPLIER = 10; - - protected boolean mEnabled; - private Context mContext; - - // maps raw person handle to resolved person object - private LruCache<String, LookupResult> mPeopleCache; - - private float findMaxContactScore(Bundle extras) { - if (extras == null) { - return 0f; - } - - final String[] people = extras.getStringArray(Notification.EXTRA_PEOPLE); - if (people == null || people.length == 0) { - return 0f; - } - - float rank = 0f; - for (int personIdx = 0; personIdx < people.length && personIdx < MAX_PEOPLE; personIdx++) { - final String handle = people[personIdx]; - if (TextUtils.isEmpty(handle)) continue; - - LookupResult lookupResult = mPeopleCache.get(handle); - if (lookupResult == null || lookupResult.isExpired()) { - final Uri uri = Uri.parse(handle); - if ("tel".equals(uri.getScheme())) { - if (DBG) Slog.w(TAG, "checking telephone URI: " + handle); - lookupResult = lookupPhoneContact(handle, uri.getSchemeSpecificPart()); - } else if (handle.startsWith(Contacts.CONTENT_LOOKUP_URI.toString())) { - if (DBG) Slog.w(TAG, "checking lookup URI: " + handle); - lookupResult = resolveContactsUri(handle, uri); - } else { - if (DBG) Slog.w(TAG, "unsupported URI " + handle); - } - } else { - if (DBG) Slog.w(TAG, "using cached lookupResult: " + lookupResult.mId); - } - if (lookupResult != null) { - rank = Math.max(rank, lookupResult.getRank()); - } - } - return rank; - } - - private LookupResult lookupPhoneContact(final String handle, final String number) { - LookupResult lookupResult = null; - Cursor c = null; - try { - Uri numberUri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, - Uri.encode(number)); - c = mContext.getContentResolver().query(numberUri, LOOKUP_PROJECTION, null, null, null); - if (c != null && c.getCount() > 0) { - c.moveToFirst(); - final int idIdx = c.getColumnIndex(Contacts._ID); - final int id = c.getInt(idIdx); - if (DBG) Slog.w(TAG, "is valid: " + id); - lookupResult = new LookupResult(id); - } - } catch(Throwable t) { - Slog.w(TAG, "Problem getting content resolver or performing contacts query.", t); - } finally { - if (c != null) { - c.close(); - } - } - if (lookupResult == null) { - lookupResult = new LookupResult(LookupResult.INVALID_ID); - } - mPeopleCache.put(handle, lookupResult); - return lookupResult; - } - - private LookupResult resolveContactsUri(String handle, final Uri personUri) { - LookupResult lookupResult = null; - Cursor c = null; - try { - c = mContext.getContentResolver().query(personUri, LOOKUP_PROJECTION, null, null, null); - if (c != null && c.getCount() > 0) { - c.moveToFirst(); - final int idIdx = c.getColumnIndex(Contacts._ID); - final int id = c.getInt(idIdx); - if (DBG) Slog.w(TAG, "is valid: " + id); - lookupResult = new LookupResult(id); - } - } catch(Throwable t) { - Slog.w(TAG, "Problem getting content resolver or performing contacts query.", t); - } finally { - if (c != null) { - c.close(); - } - } - if (lookupResult == null) { - lookupResult = new LookupResult(LookupResult.INVALID_ID); - } - mPeopleCache.put(handle, lookupResult); - return lookupResult; - } - - private final static int clamp(int x, int low, int high) { - return (x < low) ? low : ((x > high) ? high : x); - } - - // TODO: rework this function before shipping - private static int priorityBumpMap(int incomingScore) { - //assumption is that scale runs from [-2*pm, 2*pm] - int pm = NOTIFICATION_PRIORITY_MULTIPLIER; - int theScore = incomingScore; - // enforce input in range - theScore = clamp(theScore, -2 * pm, 2 * pm); - if (theScore != incomingScore) return incomingScore; - // map -20 -> -20 and -10 -> 5 (when pm = 10) - if (theScore <= -pm) { - theScore += 1.5 * (theScore + 2 * pm); - } else { - // map 0 -> 10, 10 -> 15, 20 -> 20; - theScore += 0.5 * (2 * pm - theScore); - } - if (DBG) Slog.v(TAG, "priorityBumpMap: score before: " + incomingScore - + ", score after " + theScore + "."); - return theScore; - } - - @Override - public void initialize(Context context) { - if (DBG) Slog.v(TAG, "Initializing " + getClass().getSimpleName() + "."); - mContext = context; - mPeopleCache = new LruCache<String, LookupResult>(PEOPLE_CACHE_SIZE); - mEnabled = ENABLE_PEOPLE_SCORER && 1 == Settings.Global.getInt( - mContext.getContentResolver(), SETTING_ENABLE_PEOPLE_SCORER, 0); - } - - @Override - public int getScore(Notification notification, int score) { - if (notification == null || !mEnabled) { - if (DBG) Slog.w(TAG, "empty notification? scorer disabled?"); - return score; - } - float contactScore = findMaxContactScore(notification.extras); - if (contactScore > 0f) { - if (DBG) Slog.v(TAG, "Notification references a real contact. Promoted!"); - score = priorityBumpMap(score); - } else { - if (DBG) Slog.v(TAG, "Notification lacks any valid contact reference. Not promoted!"); - } - return score; - } - - private static class LookupResult { - private static final long CONTACT_REFRESH_MILLIS = 60 * 60 * 1000; // 1hr - public static final int INVALID_ID = -1; - - private final long mExpireMillis; - private int mId; - - public LookupResult(int id) { - mId = id; - mExpireMillis = System.currentTimeMillis() + CONTACT_REFRESH_MILLIS; - } - - public boolean isExpired() { - return mExpireMillis < System.currentTimeMillis(); - } - - public boolean isInvalid() { - return mId == INVALID_ID || isExpired(); - } - - public float getRank() { - if (isInvalid()) { - return 0f; - } else { - return 1f; // TODO: finer grained score - } - } - - public LookupResult setId(int id) { - mId = id; - return this; - } - } -} - |
