summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorVivek Sekhar <vsekhar@codeaurora.org>2015-07-17 14:14:38 -0700
committerjrizzoli <joey@cyanogenmoditalia.it>2015-08-28 13:15:46 +0200
commitb53a5957e0757a8ee36ed70b14071df65cfaea93 (patch)
tree07f2279e3c01b6705ea93f72b883552a46601459 /src
parent4b00031992eb1beea0c28cd78d497309640b3d80 (diff)
downloadandroid_packages_apps_Gello-b53a5957e0757a8ee36ed70b14071df65cfaea93.tar.gz
android_packages_apps_Gello-b53a5957e0757a8ee36ed70b14071df65cfaea93.tar.bz2
android_packages_apps_Gello-b53a5957e0757a8ee36ed70b14071df65cfaea93.zip
New version update notification
Notify user when a new version of browser is available internally. Change-Id: I29ae1443c473781c3227a574ee42eb5f7e1be36c
Diffstat (limited to 'src')
-rw-r--r--src/com/android/browser/BrowserSwitches.java7
-rw-r--r--src/com/android/browser/Controller.java6
-rw-r--r--src/com/android/browser/PreferenceKeys.java1
-rw-r--r--src/com/android/browser/UpdateNotificationService.java303
-rw-r--r--src/com/android/browser/preferences/AboutPreferencesFragment.java22
5 files changed, 333 insertions, 6 deletions
diff --git a/src/com/android/browser/BrowserSwitches.java b/src/com/android/browser/BrowserSwitches.java
index 77b6f052..137b2599 100644
--- a/src/com/android/browser/BrowserSwitches.java
+++ b/src/com/android/browser/BrowserSwitches.java
@@ -60,9 +60,12 @@ public class BrowserSwitches {
public static final String CMD_LINE_SWITCH_FEEDBACK = "mail-feedback-to";
- public static final String CMD_LINE_SWITCH_HELPURL = "help-url";
+ public static final String CMD_LINE_SWITCH_HELPURL = "help-url";
public static final String CMD_LINE_SWITCH_EULA_URL = "legal-eula-url";
public static final String CMD_LINE_SWITCH_PRIVACY_POLICY_URL = "legal-privacy-policy-url";
-}
+
+ public static final String AUTO_UPDATE_SERVER_CMD = "auto-update-server";
+
+} \ No newline at end of file
diff --git a/src/com/android/browser/Controller.java b/src/com/android/browser/Controller.java
index 67282742..dbbc164a 100644
--- a/src/com/android/browser/Controller.java
+++ b/src/com/android/browser/Controller.java
@@ -40,7 +40,6 @@ import android.content.res.TypedArray;
import android.database.ContentObserver;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteException;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Rect;
@@ -65,7 +64,6 @@ import android.provider.Settings;
import android.speech.RecognizerIntent;
import android.text.TextUtils;
import android.util.Log;
-import android.util.Patterns;
import android.view.ActionMode;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
@@ -104,8 +102,6 @@ import com.android.browser.mynavigation.AddMyNavigationPage;
import com.android.browser.mynavigation.MyNavigationUtil;
import com.android.browser.platformsupport.Browser;
import com.android.browser.platformsupport.BrowserContract;
-import com.android.browser.platformsupport.WebAddress;
-import com.android.browser.platformsupport.BrowserContract.Images;
import com.android.browser.preferences.AboutPreferencesFragment;
import com.android.browser.provider.BrowserProvider2.Thumbnails;
import com.android.browser.provider.SnapshotProvider.Snapshots;
@@ -787,6 +783,7 @@ public class Controller
Log.e(LOGTAG, "BrowserActivity is already resumed.");
return;
}
+ UpdateNotificationService.updateCheck(mActivity);
mSettings.setLastRunPaused(false);
mActivityPaused = false;
Tab current = mTabControl.getCurrentTab();
@@ -2404,6 +2401,7 @@ public class Controller
})
.show();
}
+
@Override
public void showPageInfo() {
mPageDialogsHandler.showPageInfo(mTabControl.getCurrentTab(), false, null);
diff --git a/src/com/android/browser/PreferenceKeys.java b/src/com/android/browser/PreferenceKeys.java
index d4280a66..0cc635ae 100644
--- a/src/com/android/browser/PreferenceKeys.java
+++ b/src/com/android/browser/PreferenceKeys.java
@@ -132,6 +132,7 @@ public interface PreferenceKeys {
static final String PREF_USER_AGENT = "user_agent";
static final String PREF_HELP = "help_about";
static final String PREF_FEEDBACK = "feedback";
+ static final String PREF_AUTO_UPDATE = "update_notification";
static final String PREF_EDGE_SWIPE = "edge_swiping_action";
static final String PREF_LEGAL = "legal";
diff --git a/src/com/android/browser/UpdateNotificationService.java b/src/com/android/browser/UpdateNotificationService.java
new file mode 100644
index 00000000..dc913158
--- /dev/null
+++ b/src/com/android/browser/UpdateNotificationService.java
@@ -0,0 +1,303 @@
+/*
+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.android.browser;
+
+import android.app.IntentService;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.TaskStackBuilder;
+import android.content.Intent;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.net.Uri;
+import android.support.v4.app.NotificationCompat;
+import android.util.Log;
+
+
+import org.codeaurora.swe.BrowserCommandLine;
+import org.codeaurora.swe.Engine;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.json.JSONTokener;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.net.URLConnection;
+
+public class UpdateNotificationService extends IntentService {
+ private static final String LOGTAG = "UpdateNotificationService";
+ private static final String ACTION_CHECK_UPDATES = BrowserConfig.AUTHORITY +
+ ".action.check.update";
+ public static final int DEFAULT_UPDATE_INTERVAL = 604800000; // one week
+ public static final String UPDATE_SERVICE_PREF = "browser_update_service";
+ public static final String UPDATE_JSON_VERSION_CODE = "versioncode";
+ public static final String UPDATE_JSON_VERSION_STRING = "versionstring";
+ public static final String UPDATE_JSON_MIN_INTERVAL = "interval";
+ public static final String UPDATE_INTERVAL = "update_interval";
+ public static final String UPDATE_VERSION_CODE = "version_code";
+ public static final String UPDATE_VERSION = "update_version";
+ public static final String UPDATE_URL = "update_url";
+ public static final String UPDATE_TIMESTAMP = "update_timestamp";
+ private static int NOTIFICATION_ID = 1000;
+ private static boolean sIntentServiceInitialized = false;
+ private static boolean sNotifyAlways = false;
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ initEngine(this);
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ if (sIntentServiceInitialized)
+ Engine.pauseTracing(this);
+ }
+
+ private static void initEngine(Context context) {
+ if (!EngineInitializer.isInitialized()) {
+ sIntentServiceInitialized = true;
+ EngineInitializer.initializeSync((Context) context);
+ }
+ }
+
+ public static void startActionUpdateNotificationService(Context context) {
+ Intent intent = new Intent(context, UpdateNotificationService.class);
+ intent.setAction(ACTION_CHECK_UPDATES);
+ context.startService(intent);
+ }
+
+ public static String getFlavor(Context ctx) {
+ String flavor = "";
+ try {
+ ApplicationInfo ai = ctx.getPackageManager().getApplicationInfo(
+ ctx.getPackageName(),PackageManager.GET_META_DATA);
+ String compiler = (String) ai.metaData.get("Compiler");
+ String arch = (String) ai.metaData.get("Architecture");
+ flavor = "url-" + compiler + "-" + arch;
+ } catch (Exception e) {
+ Log.e(LOGTAG, "getFlavor Exception : " + e.toString());
+ }
+ return flavor;
+ }
+
+ public static void updateCheck(Context context) {
+ initEngine(context.getApplicationContext());
+ if (!BrowserCommandLine.hasSwitch(BrowserSwitches.AUTO_UPDATE_SERVER_CMD)) {
+ if (Browser.LOGV_ENABLED)
+ Log.v(LOGTAG, "skip no command line: ");
+ return;
+ }
+ long interval = getInterval(context);
+ Long last_update_time = getLastUpdateTimestamp(context);
+ if ((last_update_time + interval) < System.currentTimeMillis()) {
+ if (Browser.LOGV_ENABLED)
+ Log.v(LOGTAG, "check for update now: ");
+ startActionUpdateNotificationService(context);
+ }
+ }
+
+ public static int getLatestVersionCode(Context ctx) {
+ SharedPreferences sharedPref = ctx.getSharedPreferences(
+ UPDATE_SERVICE_PREF, Context.MODE_PRIVATE);
+ return sharedPref.getInt(UPDATE_VERSION_CODE, 0);
+ }
+
+ public static String getLatestDownloadUrl(Context ctx) {
+ SharedPreferences sharedPref = ctx.getSharedPreferences(
+ UPDATE_SERVICE_PREF, Context.MODE_PRIVATE);
+ return sharedPref.getString(UPDATE_URL,"");
+ }
+
+ public static String getLatestVersion(Context ctx) {
+ SharedPreferences sharedPref = ctx.getSharedPreferences(
+ UPDATE_SERVICE_PREF, Context.MODE_PRIVATE);
+ return sharedPref.getString(UPDATE_VERSION, "");
+ }
+
+ private static long getLastUpdateTimestamp(Context ctx) {
+ SharedPreferences sharedPref = ctx.getSharedPreferences(
+ UPDATE_SERVICE_PREF, Context.MODE_PRIVATE);
+ return sharedPref.getLong(UPDATE_TIMESTAMP, 0);
+ }
+
+ private static int getInterval(Context ctx) {
+ SharedPreferences sharedPref = ctx.getSharedPreferences(
+ UPDATE_SERVICE_PREF, Context.MODE_PRIVATE);
+ return sharedPref.getInt(UPDATE_INTERVAL, DEFAULT_UPDATE_INTERVAL);
+ }
+
+ public UpdateNotificationService() {
+ super("UpdateNotificationService");
+ }
+
+ @Override
+ protected void onHandleIntent(Intent intent) {
+ if (intent != null) {
+ final String action = intent.getAction();
+ if (ACTION_CHECK_UPDATES.equals(action)) {
+ handleUpdateCheck();
+ }
+ }
+ }
+
+ private void updateTimeStamp() {
+ SharedPreferences sharedPref = getSharedPreferences(
+ UPDATE_SERVICE_PREF, Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = sharedPref.edit();
+ editor.putLong(UPDATE_TIMESTAMP, System.currentTimeMillis());
+ editor.commit();
+ }
+
+ private void persist(int versionCode, String url, String version, int interval) {
+ SharedPreferences sharedPref = getSharedPreferences(
+ UPDATE_SERVICE_PREF, Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = sharedPref.edit();
+ editor.putInt(UPDATE_VERSION_CODE, versionCode);
+ editor.putInt(UPDATE_INTERVAL, interval);
+ editor.putString(UPDATE_VERSION, version);
+ editor.putString(UPDATE_URL, url);
+ if (Browser.LOGV_ENABLED) {
+ Log.v(LOGTAG, "persist version code : " + versionCode);
+ Log.v(LOGTAG, "persist version : " + version);
+ Log.v(LOGTAG, "persist download url : " + url);
+ }
+ editor.commit();
+ }
+
+ private void handleUpdateCheck() {
+ String server_url = BrowserCommandLine.getSwitchValue(
+ BrowserSwitches.AUTO_UPDATE_SERVER_CMD) + "/" + getPackageName();
+ int interval = DEFAULT_UPDATE_INTERVAL;
+ InputStream stream = null;
+ if (server_url != null && !server_url.isEmpty()) {
+ try {
+ URLConnection connection = new URL(server_url).openConnection();
+ stream = connection.getInputStream();
+ String result = readContents(stream);
+ if (Browser.LOGV_ENABLED)
+ Log.v(LOGTAG, "handleUpdateCheck result : " + result);
+ JSONObject jsonResult = (JSONObject) new JSONTokener(result).nextValue();
+ int versionCode = Integer.parseInt((String) jsonResult.get(UPDATE_JSON_VERSION_CODE));
+ String url = (String) jsonResult.get(getFlavor(this));
+ String version = (String) jsonResult.get(UPDATE_JSON_VERSION_STRING);
+ if (jsonResult.has(UPDATE_JSON_MIN_INTERVAL))
+ interval = Integer.parseInt((String) jsonResult.get(UPDATE_JSON_MIN_INTERVAL));
+ if (getCurrentVersionCode(this) < versionCode &&
+ (sNotifyAlways || getLatestVersionCode(this) != versionCode)) {
+ persist(versionCode, url, version, interval);
+ // notify only once per version change
+ showNotification(this, url, version);
+ }
+ stream.close();
+ } catch (JSONException e) {
+ Log.e(LOGTAG, "handleUpdateCheck JSONException : " + e.toString());
+ } catch (IOException e) {
+ Log.e(LOGTAG, "handleUpdateCheck IOException : " + e.toString());
+ } finally {
+ // always update the timestamp
+ updateTimeStamp();
+ }
+ }
+ }
+
+ public static int getCurrentVersionCode(Context ctx) {
+ PackageInfo pInfo = null;
+ try {
+ pInfo = ctx.getPackageManager().getPackageInfo(ctx.getPackageName(), 0);
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.e(LOGTAG, "getCurrentVersionCode Exception : " + e.toString());
+ }
+ return pInfo.versionCode;
+ }
+
+ private static void showNotification(Context ctx, String url, String version) {
+ NotificationCompat.Builder builder =
+ new NotificationCompat.Builder(ctx)
+ .setSmallIcon(R.drawable.img_notify_update_white)
+ .setContentTitle(ctx.getString(R.string.update))
+ .setContentText(ctx.getString(R.string.update_msg) + version);
+ Intent resultIntent = new Intent(ctx, BrowserActivity.class);
+ resultIntent.setAction(Intent.ACTION_VIEW);
+ resultIntent.setData(Uri.parse(url));
+ TaskStackBuilder stackBuilder = TaskStackBuilder.create(ctx);
+ stackBuilder.addParentStack(BrowserActivity.class);
+ stackBuilder.addNextIntent(resultIntent);
+ PendingIntent resultPendingIntent =
+ stackBuilder.getPendingIntent(
+ 0,
+ PendingIntent.FLAG_UPDATE_CURRENT
+ );
+ builder.setContentIntent(resultPendingIntent);
+ NotificationManager mNotificationManager =
+ (NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);
+ Notification notification = builder.build();
+ notification.flags = Notification.DEFAULT_LIGHTS | Notification.FLAG_AUTO_CANCEL;
+ mNotificationManager.notify(NOTIFICATION_ID, notification);
+ }
+
+ private static void removeNotification(Context ctx) {
+ NotificationManager mNotificationManager =
+ (NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);
+ mNotificationManager.cancel(NOTIFICATION_ID);
+ }
+
+ private static String readContents(InputStream is) {
+ String line = null;
+ BufferedReader reader = new BufferedReader(new InputStreamReader(is));
+ StringBuilder sb = new StringBuilder();
+ try {
+ line = reader.readLine();
+ while (line != null) {
+ line = line.replaceFirst("channel = ","");
+ sb.append(line + "\n");
+ line = reader.readLine();
+ }
+ } catch (Exception e) {
+ Log.e(LOGTAG, "convertStreamToString Exception : " + e.toString());
+ } finally {
+ try {
+ is.close();
+ } catch (Exception e) {
+ Log.e(LOGTAG, "convertStreamToString Exception : " + e.toString());
+ }
+ }
+ return sb.toString();
+ }
+
+}
diff --git a/src/com/android/browser/preferences/AboutPreferencesFragment.java b/src/com/android/browser/preferences/AboutPreferencesFragment.java
index 2a0edac0..7d143205 100644
--- a/src/com/android/browser/preferences/AboutPreferencesFragment.java
+++ b/src/com/android/browser/preferences/AboutPreferencesFragment.java
@@ -38,12 +38,14 @@ import android.preference.Preference;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceFragment;
import android.preference.PreferenceScreen;
+import android.provider.Browser;
import com.android.browser.BrowserActivity;
import com.android.browser.BrowserPreferencesPage;
import com.android.browser.BrowserSwitches;
import com.android.browser.PreferenceKeys;
import com.android.browser.R;
+import com.android.browser.UpdateNotificationService;
import org.codeaurora.swe.BrowserCommandLine;
@@ -153,6 +155,18 @@ public class AboutPreferencesFragment extends PreferenceFragment
setOnClickListener(PreferenceKeys.PREF_FEEDBACK, !mFeedbackRecipient.isEmpty());
setOnClickListener(PreferenceKeys.PREF_LEGAL, true);
+ if (BrowserCommandLine.hasSwitch(BrowserSwitches.AUTO_UPDATE_SERVER_CMD)) {
+ setPreference(PreferenceKeys.PREF_AUTO_UPDATE,
+ UpdateNotificationService.getLatestVersion(getActivity()));
+ setOnClickListener(PreferenceKeys.PREF_AUTO_UPDATE,
+ UpdateNotificationService.getCurrentVersionCode(getActivity()) <
+ UpdateNotificationService.getLatestVersionCode(getActivity()));
+ } else {
+ Preference pref = findPreference(PreferenceKeys.PREF_AUTO_UPDATE);
+ if (mHeadPref != null)
+ mHeadPref.removePreference(pref);
+ }
+
}
@Override
@@ -200,6 +214,14 @@ public class AboutPreferencesFragment extends PreferenceFragment
intent.putExtra(Intent.EXTRA_TEXT, message);
startActivity(Intent.createChooser(intent, "Select email application"));
return true;
+ } else if (preference.getKey().equals(PreferenceKeys.PREF_AUTO_UPDATE)) {
+ Intent intent = new Intent(getActivity(), BrowserActivity.class);
+ intent.setAction(Intent.ACTION_VIEW);
+ intent.putExtra(Browser.EXTRA_APPLICATION_ID, getActivity().getPackageName());
+ intent.putExtra(Browser.EXTRA_CREATE_NEW_TAB, true);
+ intent.setData(Uri.parse(
+ UpdateNotificationService.getLatestDownloadUrl(getActivity())));
+ getActivity().startActivity(intent);
}
return false;
}