| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.chrome.browser.physicalweb; | 5 package org.chromium.chrome.browser.physicalweb; |
| 6 | 6 |
| 7 import android.app.AlarmManager; | 7 import android.app.AlarmManager; |
| 8 import android.app.Notification; | 8 import android.app.Notification; |
| 9 import android.app.NotificationManager; | 9 import android.app.NotificationManager; |
| 10 import android.app.PendingIntent; | 10 import android.app.PendingIntent; |
| 11 import android.content.Context; | 11 import android.content.Context; |
| 12 import android.content.Intent; | 12 import android.content.Intent; |
| 13 import android.content.SharedPreferences; | 13 import android.content.SharedPreferences; |
| 14 import android.content.res.Resources; | 14 import android.content.res.Resources; |
| 15 import android.graphics.Bitmap; | 15 import android.graphics.Bitmap; |
| 16 import android.graphics.BitmapFactory; | 16 import android.graphics.BitmapFactory; |
| 17 import android.os.AsyncTask; | 17 import android.os.AsyncTask; |
| 18 import android.os.Handler; | 18 import android.os.Handler; |
| 19 import android.os.Looper; | 19 import android.os.Looper; |
| 20 import android.os.SystemClock; | 20 import android.os.SystemClock; |
| 21 import android.support.v4.app.NotificationCompat; | 21 import android.support.v4.app.NotificationCompat; |
| 22 | 22 |
| 23 import org.json.JSONException; |
| 24 import org.json.JSONObject; |
| 25 |
| 23 import org.chromium.base.ContextUtils; | 26 import org.chromium.base.ContextUtils; |
| 24 import org.chromium.base.Log; | 27 import org.chromium.base.Log; |
| 25 import org.chromium.base.ObserverList; | 28 import org.chromium.base.ObserverList; |
| 29 import org.chromium.base.ThreadUtils; |
| 26 import org.chromium.base.VisibleForTesting; | 30 import org.chromium.base.VisibleForTesting; |
| 31 import org.chromium.base.annotations.CalledByNative; |
| 32 import org.chromium.base.library_loader.LibraryProcessType; |
| 27 import org.chromium.chrome.R; | 33 import org.chromium.chrome.R; |
| 28 import org.chromium.chrome.browser.ChromeApplication; | 34 import org.chromium.chrome.browser.ChromeApplication; |
| 29 import org.chromium.chrome.browser.notifications.NotificationConstants; | 35 import org.chromium.chrome.browser.notifications.NotificationConstants; |
| 30 import org.chromium.chrome.browser.notifications.NotificationManagerProxy; | 36 import org.chromium.chrome.browser.notifications.NotificationManagerProxy; |
| 31 import org.chromium.chrome.browser.notifications.NotificationManagerProxyImpl; | 37 import org.chromium.chrome.browser.notifications.NotificationManagerProxyImpl; |
| 32 import org.json.JSONException; | 38 import org.chromium.content.browser.BrowserStartupController; |
| 33 import org.json.JSONObject; | 39 import org.chromium.content.browser.BrowserStartupController.StartupCallback; |
| 34 | 40 |
| 35 import java.util.ArrayList; | 41 import java.util.ArrayList; |
| 36 import java.util.Arrays; | 42 import java.util.Arrays; |
| 37 import java.util.Collection; | 43 import java.util.Collection; |
| 38 import java.util.Collections; | 44 import java.util.Collections; |
| 39 import java.util.Comparator; | 45 import java.util.Comparator; |
| 40 import java.util.HashMap; | 46 import java.util.HashMap; |
| 41 import java.util.HashSet; | 47 import java.util.HashSet; |
| 42 import java.util.List; | 48 import java.util.List; |
| 43 import java.util.Map; | 49 import java.util.Map; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 70 private static final int MAX_CACHE_SIZE = 100; | 76 private static final int MAX_CACHE_SIZE = 100; |
| 71 private static UrlManager sInstance = null; | 77 private static UrlManager sInstance = null; |
| 72 private final Context mContext; | 78 private final Context mContext; |
| 73 private final ObserverList<Listener> mObservers; | 79 private final ObserverList<Listener> mObservers; |
| 74 private final Set<String> mNearbyUrls; | 80 private final Set<String> mNearbyUrls; |
| 75 private final Map<String, UrlInfo> mUrlInfoMap; | 81 private final Map<String, UrlInfo> mUrlInfoMap; |
| 76 private final Map<String, PwsResult> mPwsResultMap; | 82 private final Map<String, PwsResult> mPwsResultMap; |
| 77 private final PriorityQueue<String> mUrlsSortedByTimestamp; | 83 private final PriorityQueue<String> mUrlsSortedByTimestamp; |
| 78 private NotificationManagerProxy mNotificationManager; | 84 private NotificationManagerProxy mNotificationManager; |
| 79 private PwsClient mPwsClient; | 85 private PwsClient mPwsClient; |
| 86 private long mNativePhysicalWebDataSourceAndroid; |
| 80 | 87 |
| 81 /** | 88 /** |
| 82 * Interface for observers that should be notified when the nearby URL list
changes. | 89 * Interface for observers that should be notified when the nearby URL list
changes. |
| 83 */ | 90 */ |
| 84 public interface Listener { | 91 public interface Listener { |
| 85 /** | 92 /** |
| 86 * Callback called when one or more URLs are added to the URL list. | 93 * Callback called when one or more URLs are added to the URL list. |
| 87 * @param urls A set of UrlInfos containing nearby URLs resolvable with
our resolution | 94 * @param urls A set of UrlInfos containing nearby URLs resolvable with
our resolution |
| 88 * service. | 95 * service. |
| 89 */ | 96 */ |
| (...skipping 16 matching lines...) Expand all Loading... |
| 106 mPwsResultMap = new HashMap<>(); | 113 mPwsResultMap = new HashMap<>(); |
| 107 mUrlsSortedByTimestamp = new PriorityQueue<String>(1, new Comparator<Str
ing>() { | 114 mUrlsSortedByTimestamp = new PriorityQueue<String>(1, new Comparator<Str
ing>() { |
| 108 @Override | 115 @Override |
| 109 public int compare(String url1, String url2) { | 116 public int compare(String url1, String url2) { |
| 110 Long scanTimestamp1 = Long.valueOf(mUrlInfoMap.get(url1).getScan
Timestamp()); | 117 Long scanTimestamp1 = Long.valueOf(mUrlInfoMap.get(url1).getScan
Timestamp()); |
| 111 Long scanTimestamp2 = Long.valueOf(mUrlInfoMap.get(url2).getScan
Timestamp()); | 118 Long scanTimestamp2 = Long.valueOf(mUrlInfoMap.get(url2).getScan
Timestamp()); |
| 112 return scanTimestamp1.compareTo(scanTimestamp2); | 119 return scanTimestamp1.compareTo(scanTimestamp2); |
| 113 } | 120 } |
| 114 }); | 121 }); |
| 115 initSharedPreferences(); | 122 initSharedPreferences(); |
| 123 registerNativeInitStartupCallback(); |
| 116 } | 124 } |
| 117 | 125 |
| 118 /** | 126 /** |
| 119 * Get a singleton instance of this class. | 127 * Get a singleton instance of this class. |
| 120 * @return A singleton instance of this class. | 128 * @return A singleton instance of this class. |
| 121 */ | 129 */ |
| 130 @CalledByNative |
| 122 public static UrlManager getInstance() { | 131 public static UrlManager getInstance() { |
| 123 if (sInstance == null) { | 132 if (sInstance == null) { |
| 124 sInstance = new UrlManager(ContextUtils.getApplicationContext()); | 133 sInstance = new UrlManager(ContextUtils.getApplicationContext()); |
| 125 } | 134 } |
| 126 return sInstance; | 135 return sInstance; |
| 127 } | 136 } |
| 128 | 137 |
| 129 /** | 138 /** |
| 130 * Get a singleton instance of this class. | 139 * Get a singleton instance of this class. |
| 131 * @param context unused | 140 * @param context unused |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 179 return; | 188 return; |
| 180 } | 189 } |
| 181 registerNewDisplayableUrl(urlInfo); | 190 registerNewDisplayableUrl(urlInfo); |
| 182 } | 191 } |
| 183 | 192 |
| 184 /** | 193 /** |
| 185 * Remove a URL to the store of URLs. | 194 * Remove a URL to the store of URLs. |
| 186 * This method additionally updates the Physical Web notification. | 195 * This method additionally updates the Physical Web notification. |
| 187 * @param urlInfo The URL to remove. | 196 * @param urlInfo The URL to remove. |
| 188 */ | 197 */ |
| 189 @VisibleForTesting | |
| 190 public void removeUrl(UrlInfo urlInfo) { | 198 public void removeUrl(UrlInfo urlInfo) { |
| 191 Log.d(TAG, "URL lost: %s", urlInfo); | 199 Log.d(TAG, "URL lost: %s", urlInfo); |
| 192 recordUpdate(); | 200 recordUpdate(); |
| 193 mNearbyUrls.remove(urlInfo.getUrl()); | 201 mNearbyUrls.remove(urlInfo.getUrl()); |
| 194 putCachedNearbyUrls(); | 202 putCachedNearbyUrls(); |
| 195 | 203 |
| 196 // If there are no URLs nearby to display, clear the notification. | 204 // If there are no URLs nearby to display, clear the notification. |
| 197 if (getUrls(PhysicalWeb.isOnboarding()).isEmpty()) { | 205 if (getUrls(PhysicalWeb.isOnboarding()).isEmpty()) { |
| 198 clearNotification(); | 206 clearNotification(); |
| 199 } | 207 } |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 245 | 253 |
| 246 public Set<String> getNearbyUrls() { | 254 public Set<String> getNearbyUrls() { |
| 247 return mNearbyUrls; | 255 return mNearbyUrls; |
| 248 } | 256 } |
| 249 | 257 |
| 250 public Set<String> getResolvedUrls() { | 258 public Set<String> getResolvedUrls() { |
| 251 return mPwsResultMap.keySet(); | 259 return mPwsResultMap.keySet(); |
| 252 } | 260 } |
| 253 | 261 |
| 254 /** | 262 /** |
| 255 * Gets all UrlInfos and PwsResults for resolved URLs. | 263 * Gets all UrlInfos and PwsResults for nearby URLs. |
| 264 * The UrlInfos and PwsResults are returned as parallel arrays. Unresolved U
RLs in the UrlInfo |
| 265 * array will have a null element in the corresponding entry of the PwsResul
t array. |
| 266 * @return A PwCollection object containg parallel arrays of UrlInfos and Pw
sResults. |
| 256 */ | 267 */ |
| 257 public PwCollection getPwCollection() { | 268 public PwCollection getPwCollection() { |
| 258 List<PwsResult> nearbyPwsResults = new ArrayList<>(); | 269 List<PwsResult> nearbyPwsResults = new ArrayList<>(); |
| 259 for (String url : mNearbyUrls) { | 270 for (String url : mNearbyUrls) { |
| 260 nearbyPwsResults.add(mPwsResultMap.get(url)); | 271 nearbyPwsResults.add(mPwsResultMap.get(url)); |
| 261 } | 272 } |
| 262 return new PwCollection(getUrlInfoList(mNearbyUrls), nearbyPwsResults); | 273 return new PwCollection(getUrlInfoList(mNearbyUrls), nearbyPwsResults); |
| 263 } | 274 } |
| 264 | 275 |
| 265 /** | 276 /** |
| (...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 620 } | 631 } |
| 621 Log.d(TAG, "Garbage collecting: ", urlInfo); | 632 Log.d(TAG, "Garbage collecting: ", urlInfo); |
| 622 // The min value cannot have changed at this point, so it's OK to ju
st remove via | 633 // The min value cannot have changed at this point, so it's OK to ju
st remove via |
| 623 // poll(). | 634 // poll(). |
| 624 mUrlsSortedByTimestamp.poll(); | 635 mUrlsSortedByTimestamp.poll(); |
| 625 mUrlInfoMap.remove(url); | 636 mUrlInfoMap.remove(url); |
| 626 mPwsResultMap.remove(url); | 637 mPwsResultMap.remove(url); |
| 627 } | 638 } |
| 628 } | 639 } |
| 629 | 640 |
| 641 /** |
| 642 * Register a StartupCallback to initialize the native portion of the JNI br
idge. |
| 643 */ |
| 644 private void registerNativeInitStartupCallback() { |
| 645 ThreadUtils.postOnUiThread(new Runnable() { |
| 646 @Override |
| 647 public void run() { |
| 648 BrowserStartupController.get(mContext, LibraryProcessType.PROCES
S_BROWSER) |
| 649 .addStartupCompletedObserver(new StartupCallback() { |
| 650 @Override |
| 651 public void onSuccess(boolean alreadyStarted) { |
| 652 mNativePhysicalWebDataSourceAndroid = nativeInit
(); |
| 653 } |
| 654 |
| 655 @Override |
| 656 public void onFailure() { |
| 657 // Startup failed. |
| 658 } |
| 659 }); |
| 660 } |
| 661 }); |
| 662 } |
| 663 |
| 664 /** |
| 665 * Checks if we have initialized the native library and received a handle to
the data source. |
| 666 * @return true if the data source handle is non-null. |
| 667 */ |
| 668 private boolean isNativeInitialized() { |
| 669 return mNativePhysicalWebDataSourceAndroid != 0; |
| 670 } |
| 671 |
| 630 @VisibleForTesting | 672 @VisibleForTesting |
| 631 void overridePwsClientForTesting(PwsClient pwsClient) { | 673 void overridePwsClientForTesting(PwsClient pwsClient) { |
| 632 mPwsClient = pwsClient; | 674 mPwsClient = pwsClient; |
| 633 } | 675 } |
| 634 | 676 |
| 635 @VisibleForTesting | 677 @VisibleForTesting |
| 636 void overrideNotificationManagerForTesting( | 678 void overrideNotificationManagerForTesting( |
| 637 NotificationManagerProxy notificationManager) { | 679 NotificationManagerProxy notificationManager) { |
| 638 mNotificationManager = notificationManager; | 680 mNotificationManager = notificationManager; |
| 639 } | 681 } |
| (...skipping 23 matching lines...) Expand all Loading... |
| 663 return mNearbyUrls.contains(url) | 705 return mNearbyUrls.contains(url) |
| 664 || mPwsResultMap.containsKey(url) | 706 || mPwsResultMap.containsKey(url) |
| 665 || mUrlInfoMap.containsKey(url) | 707 || mUrlInfoMap.containsKey(url) |
| 666 || mUrlsSortedByTimestamp.contains(url); | 708 || mUrlsSortedByTimestamp.contains(url); |
| 667 } | 709 } |
| 668 | 710 |
| 669 @VisibleForTesting | 711 @VisibleForTesting |
| 670 int getMaxCacheSize() { | 712 int getMaxCacheSize() { |
| 671 return MAX_CACHE_SIZE; | 713 return MAX_CACHE_SIZE; |
| 672 } | 714 } |
| 715 |
| 716 private native long nativeInit(); |
| 673 } | 717 } |
| OLD | NEW |