소스 검색

Userscripts: fix some minor issues (#1957)

uazo 3 년 전
부모
커밋
2de7773a24

+ 3 - 88
build/patches/Add-bookmark-import-export-actions.patch

@@ -5,10 +5,9 @@ Subject: Add bookmark import/export actions
 Add bookmark import/export actions in bookmarks activity and page
 Add bookmark import/export actions in bookmarks activity and page
 Reduce permissions needed for bookmarks import/export
 Reduce permissions needed for bookmarks import/export
 Completely remove contacts picker permission from the file dialog
 Completely remove contacts picker permission from the file dialog
+
+Need: Adds-support-for-writing-URIs.patch
 ---
 ---
- base/android/content_uri_utils.cc             |  10 +
- base/android/content_uri_utils.h              |   4 +
- .../org/chromium/base/ContentUriUtils.java    |  33 ++
  chrome/android/java/AndroidManifest.xml       |   1 -
  chrome/android/java/AndroidManifest.xml       |   1 -
  .../res/menu/bookmark_action_bar_menu.xml     |  14 +
  .../res/menu/bookmark_action_bar_menu.xml     |  14 +
  .../browser/TabbedModeTabDelegateFactory.java |   5 +-
  .../browser/TabbedModeTabDelegateFactory.java |   5 +-
@@ -44,92 +43,8 @@ Completely remove contacts picker permission from the file dialog
  ui/shell_dialogs/select_file_dialog.h         |   2 +
  ui/shell_dialogs/select_file_dialog.h         |   2 +
  .../select_file_dialog_android.cc             |   6 +
  .../select_file_dialog_android.cc             |   6 +
  ui/shell_dialogs/select_file_dialog_android.h |   2 +
  ui/shell_dialogs/select_file_dialog_android.h |   2 +
- 38 files changed, 893 insertions(+), 29 deletions(-)
+ 35 files changed, 846 insertions(+), 29 deletions(-)
 
 
-diff --git a/base/android/content_uri_utils.cc b/base/android/content_uri_utils.cc
---- a/base/android/content_uri_utils.cc
-+++ b/base/android/content_uri_utils.cc
-@@ -30,6 +30,16 @@ File OpenContentUriForRead(const FilePath& content_uri) {
-   return File(fd);
- }
- 
-+File OpenContentUriForWrite(const FilePath& content_uri) {
-+  JNIEnv* env = base::android::AttachCurrentThread();
-+  ScopedJavaLocalRef<jstring> j_uri =
-+      ConvertUTF8ToJavaString(env, content_uri.value());
-+  jint fd = Java_ContentUriUtils_openContentUriForWrite(env, j_uri);
-+  if (fd < 0)
-+    return File();
-+  return File(fd);
-+}
-+
- std::string GetContentUriMimeType(const FilePath& content_uri) {
-   JNIEnv* env = base::android::AttachCurrentThread();
-   ScopedJavaLocalRef<jstring> j_uri =
-diff --git a/base/android/content_uri_utils.h b/base/android/content_uri_utils.h
---- a/base/android/content_uri_utils.h
-+++ b/base/android/content_uri_utils.h
-@@ -18,6 +18,10 @@ namespace base {
- // Returns -1 if the URI is invalid.
- BASE_EXPORT File OpenContentUriForRead(const FilePath& content_uri);
- 
-+// Opens a content URI for write and returns the file descriptor to the caller.
-+// Returns -1 if the URI is invalid.
-+BASE_EXPORT File OpenContentUriForWrite(const FilePath& content_uri);
-+
- // Check whether a content URI exists.
- BASE_EXPORT bool ContentUriExists(const FilePath& content_uri);
- 
-diff --git a/base/android/java/src/org/chromium/base/ContentUriUtils.java b/base/android/java/src/org/chromium/base/ContentUriUtils.java
---- a/base/android/java/src/org/chromium/base/ContentUriUtils.java
-+++ b/base/android/java/src/org/chromium/base/ContentUriUtils.java
-@@ -23,6 +23,9 @@ import org.chromium.base.annotations.CalledByNative;
- import java.io.File;
- import java.io.IOException;
- 
-+import android.system.Os;
-+import android.content.ContentProviderClient;
-+
- /**
-  * This class provides methods to access content URI schemes.
-  */
-@@ -89,6 +92,36 @@ public abstract class ContentUriUtils {
-         return -1;
-     }
- 
-+    @CalledByNative
-+    public static int openContentUriForWrite(String uriString) {
-+        try {
-+            Uri uri = Uri.parse(uriString);
-+            ContentResolver resolver = ContextUtils.getApplicationContext().getContentResolver();
-+            ContentProviderClient client = resolver.acquireContentProviderClient(
-+                                            uri.getAuthority());
-+            ParcelFileDescriptor pfd = client.openFile(uri, "rw");
-+            int fd = pfd.detachFd();
-+            client.close();
-+            return fd;
-+        } catch (Exception e) {
-+            Log.e(TAG, "Cannot open intermediate URI", e);
-+        }
-+        return -1;
-+    }
-+
-+    public static String getFilePathFromContentUri(Uri uri) {
-+        String path = null;
-+        try {
-+            ContentResolver resolver = ContextUtils.getApplicationContext().getContentResolver();
-+            ParcelFileDescriptor pfd = resolver.openFileDescriptor(uri, "r");
-+            path = Os.readlink("/proc/self/fd/" + pfd.getFd());
-+            pfd.close();
-+        } catch (Exception e) {
-+            Log.w(TAG, "Cannot get file path from content URI", e);
-+        }
-+        return path;
-+    }
-+
-     /**
-      * Check whether a content URI exists.
-      *
 diff --git a/chrome/android/java/AndroidManifest.xml b/chrome/android/java/AndroidManifest.xml
 diff --git a/chrome/android/java/AndroidManifest.xml b/chrome/android/java/AndroidManifest.xml
 --- a/chrome/android/java/AndroidManifest.xml
 --- a/chrome/android/java/AndroidManifest.xml
 +++ b/chrome/android/java/AndroidManifest.xml
 +++ b/chrome/android/java/AndroidManifest.xml

+ 97 - 0
build/patches/Adds-support-for-writing-URIs.patch

@@ -0,0 +1,97 @@
+From: uazo <uazo@users.noreply.github.com>
+Date: Tue, 12 Apr 2022 15:58:01 +0000
+Subject: Adds support for writing URIs
+
+Allows native side URI file writing
+---
+ base/android/content_uri_utils.cc             | 10 ++++++
+ base/android/content_uri_utils.h              |  4 +++
+ .../org/chromium/base/ContentUriUtils.java    | 33 +++++++++++++++++++
+ 3 files changed, 47 insertions(+)
+
+diff --git a/base/android/content_uri_utils.cc b/base/android/content_uri_utils.cc
+--- a/base/android/content_uri_utils.cc
++++ b/base/android/content_uri_utils.cc
+@@ -30,6 +30,16 @@ File OpenContentUriForRead(const FilePath& content_uri) {
+   return File(fd);
+ }
+ 
++File OpenContentUriForWrite(const FilePath& content_uri) {
++  JNIEnv* env = base::android::AttachCurrentThread();
++  ScopedJavaLocalRef<jstring> j_uri =
++      ConvertUTF8ToJavaString(env, content_uri.value());
++  jint fd = Java_ContentUriUtils_openContentUriForWrite(env, j_uri);
++  if (fd < 0)
++    return File();
++  return File(fd);
++}
++
+ std::string GetContentUriMimeType(const FilePath& content_uri) {
+   JNIEnv* env = base::android::AttachCurrentThread();
+   ScopedJavaLocalRef<jstring> j_uri =
+diff --git a/base/android/content_uri_utils.h b/base/android/content_uri_utils.h
+--- a/base/android/content_uri_utils.h
++++ b/base/android/content_uri_utils.h
+@@ -18,6 +18,10 @@ namespace base {
+ // Returns -1 if the URI is invalid.
+ BASE_EXPORT File OpenContentUriForRead(const FilePath& content_uri);
+ 
++// Opens a content URI for write and returns the file descriptor to the caller.
++// Returns -1 if the URI is invalid.
++BASE_EXPORT File OpenContentUriForWrite(const FilePath& content_uri);
++
+ // Check whether a content URI exists.
+ BASE_EXPORT bool ContentUriExists(const FilePath& content_uri);
+ 
+diff --git a/base/android/java/src/org/chromium/base/ContentUriUtils.java b/base/android/java/src/org/chromium/base/ContentUriUtils.java
+--- a/base/android/java/src/org/chromium/base/ContentUriUtils.java
++++ b/base/android/java/src/org/chromium/base/ContentUriUtils.java
+@@ -23,6 +23,9 @@ import org.chromium.base.annotations.CalledByNative;
+ import java.io.File;
+ import java.io.IOException;
+ 
++import android.system.Os;
++import android.content.ContentProviderClient;
++
+ /**
+  * This class provides methods to access content URI schemes.
+  */
+@@ -89,6 +92,36 @@ public abstract class ContentUriUtils {
+         return -1;
+     }
+ 
++    @CalledByNative
++    public static int openContentUriForWrite(String uriString) {
++        try {
++            Uri uri = Uri.parse(uriString);
++            ContentResolver resolver = ContextUtils.getApplicationContext().getContentResolver();
++            ContentProviderClient client = resolver.acquireContentProviderClient(
++                                            uri.getAuthority());
++            ParcelFileDescriptor pfd = client.openFile(uri, "rw");
++            int fd = pfd.detachFd();
++            client.close();
++            return fd;
++        } catch (Exception e) {
++            Log.e(TAG, "Cannot open intermediate URI", e);
++        }
++        return -1;
++    }
++
++    public static String getFilePathFromContentUri(Uri uri) {
++        String path = null;
++        try {
++            ContentResolver resolver = ContextUtils.getApplicationContext().getContentResolver();
++            ParcelFileDescriptor pfd = resolver.openFileDescriptor(uri, "r");
++            path = Os.readlink("/proc/self/fd/" + pfd.getFd());
++            pfd.close();
++        } catch (Exception e) {
++            Log.w(TAG, "Cannot get file path from content URI", e);
++        }
++        return path;
++    }
++
+     /**
+      * Check whether a content URI exists.
+      *
+--
+2.25.1

+ 40 - 21
build/patches/Experimental-user-scripts-support.patch

@@ -21,6 +21,8 @@ document-idle), homepage, url_source
 The UI also allows you to see the source of the script.
 The UI also allows you to see the source of the script.
 
 
 See also: components/user_scripts/README.md
 See also: components/user_scripts/README.md
+
+Need: Adds-support-for-writing-URIs.patch
 ---
 ---
  chrome/android/BUILD.gn                       |   5 +
  chrome/android/BUILD.gn                       |   5 +
  .../android/java/res/xml/main_preferences.xml |   5 +
  .../android/java/res/xml/main_preferences.xml |   5 +
@@ -52,13 +54,13 @@ See also: components/user_scripts/README.md
  .../java/res/layout/scripts_preference.xml    |  40 +
  .../java/res/layout/scripts_preference.xml    |  40 +
  .../android/java/res/values/dimens.xml        |  11 +
  .../android/java/res/values/dimens.xml        |  11 +
  .../java/res/xml/userscripts_preferences.xml  |  34 +
  .../java/res/xml/userscripts_preferences.xml  |  34 +
- .../user_scripts/UserScriptsUtils.java        |  84 ++
+ .../user_scripts/UserScriptsUtils.java        |  87 ++
  .../user_scripts/FragmentWindowAndroid.java   |  90 ++
  .../user_scripts/FragmentWindowAndroid.java   |  90 ++
  .../user_scripts/IUserScriptsUtils.java       |  22 +
  .../user_scripts/IUserScriptsUtils.java       |  22 +
  .../components/user_scripts/ScriptInfo.java   |  37 +
  .../components/user_scripts/ScriptInfo.java   |  37 +
  .../user_scripts/ScriptListBaseAdapter.java   | 163 ++++
  .../user_scripts/ScriptListBaseAdapter.java   | 163 ++++
  .../user_scripts/ScriptListPreference.java    | 171 ++++
  .../user_scripts/ScriptListPreference.java    | 171 ++++
- .../user_scripts/UserScriptsBridge.java       | 200 +++++
+ .../user_scripts/UserScriptsBridge.java       | 212 +++++
  .../user_scripts/UserScriptsPreferences.java  | 116 +++
  .../user_scripts/UserScriptsPreferences.java  | 116 +++
  .../user_scripts/android/java_sources.gni     |  18 +
  .../user_scripts/android/java_sources.gni     |  18 +
  .../android/user_scripts_bridge.cc            | 173 ++++
  .../android/user_scripts_bridge.cc            | 173 ++++
@@ -72,7 +74,7 @@ See also: components/user_scripts/README.md
  .../user-script-ui/user-scripts-ui.js         |   9 +
  .../user-script-ui/user-scripts-ui.js         |   9 +
  .../browser/ui/user_scripts_ui.cc             | 147 ++++
  .../browser/ui/user_scripts_ui.cc             | 147 ++++
  .../user_scripts/browser/ui/user_scripts_ui.h |  37 +
  .../user_scripts/browser/ui/user_scripts_ui.h |  37 +
- .../browser/user_script_loader.cc             | 714 ++++++++++++++++
+ .../browser/user_script_loader.cc             | 716 ++++++++++++++++
  .../user_scripts/browser/user_script_loader.h | 169 ++++
  .../user_scripts/browser/user_script_loader.h | 169 ++++
  .../browser/user_script_pref_info.cc          |  34 +
  .../browser/user_script_pref_info.cc          |  34 +
  .../browser/user_script_pref_info.h           |  72 ++
  .../browser/user_script_pref_info.h           |  72 ++
@@ -131,9 +133,9 @@ See also: components/user_scripts/README.md
  .../renderer/user_scripts_renderer_client.h   |  37 +
  .../renderer/user_scripts_renderer_client.h   |  37 +
  .../renderer/web_ui_injection_host.cc         |  40 +
  .../renderer/web_ui_injection_host.cc         |  40 +
  .../renderer/web_ui_injection_host.h          |  27 +
  .../renderer/web_ui_injection_host.h          |  27 +
- .../strings/userscripts_strings.grdp          |  55 ++
+ .../strings/userscripts_strings.grdp          |  57 ++
  tools/gritsettings/resource_ids.spec          |   6 +
  tools/gritsettings/resource_ids.spec          |   6 +
- 111 files changed, 9576 insertions(+), 2 deletions(-)
+ 111 files changed, 9595 insertions(+), 2 deletions(-)
  create mode 100644 components/user_scripts/README.md
  create mode 100644 components/user_scripts/README.md
  create mode 100755 components/user_scripts/android/BUILD.gn
  create mode 100755 components/user_scripts/android/BUILD.gn
  create mode 100644 components/user_scripts/android/java/res/layout/accept_script_item.xml
  create mode 100644 components/user_scripts/android/java/res/layout/accept_script_item.xml
@@ -1227,7 +1229,7 @@ diff --git a/components/user_scripts/android/java/src/org/chromium/chrome/browse
 new file mode 100755
 new file mode 100755
 --- /dev/null
 --- /dev/null
 +++ b/components/user_scripts/android/java/src/org/chromium/chrome/browser/user_scripts/UserScriptsUtils.java
 +++ b/components/user_scripts/android/java/src/org/chromium/chrome/browser/user_scripts/UserScriptsUtils.java
-@@ -0,0 +1,84 @@
+@@ -0,0 +1,87 @@
 +/*
 +/*
 +    This file is part of Bromite.
 +    This file is part of Bromite.
 +
 +
@@ -1277,6 +1279,7 @@ new file mode 100755
 +    }
 +    }
 +
 +
 +    public static UserScriptsUtils getInstance() {
 +    public static UserScriptsUtils getInstance() {
++        if (instance == null) Initialize();
 +        return instance;
 +        return instance;
 +    }
 +    }
 +
 +
@@ -1286,11 +1289,13 @@ new file mode 100755
 +
 +
 +        Context context = ContextUtils.getApplicationContext();
 +        Context context = ContextUtils.getApplicationContext();
 +
 +
-+        if (ContentUriUtils.isContentUri(filePath))
-+            filePath = ContentUriUtils.getDisplayName(contentUri, context,
++        String visibleName = filePath;
++        if (ContentUriUtils.isContentUri(visibleName)) {
++            visibleName = ContentUriUtils.getDisplayName(contentUri, context,
 +                MediaStore.MediaColumns.DISPLAY_NAME);
 +                MediaStore.MediaColumns.DISPLAY_NAME);
++        }
 +
 +
-+        if (filePath.toUpperCase().endsWith(".USER.JS") == false) return false;
++        if (visibleName.toUpperCase().endsWith(".USER.JS") == false) return false;
 +
 +
 +        SettingsLauncher settingsLauncher = new SettingsLauncherImpl();
 +        SettingsLauncher settingsLauncher = new SettingsLauncherImpl();
 +        Intent intent = settingsLauncher.createSettingsActivityIntent(
 +        Intent intent = settingsLauncher.createSettingsActivityIntent(
@@ -1312,7 +1317,6 @@ new file mode 100755
 +        IntentHandler.startChromeLauncherActivityForTrustedIntent(intent);
 +        IntentHandler.startChromeLauncherActivityForTrustedIntent(intent);
 +    }
 +    }
 +}
 +}
-\ No newline at end of file
 diff --git a/components/user_scripts/android/java/src/org/chromium/components/user_scripts/FragmentWindowAndroid.java b/components/user_scripts/android/java/src/org/chromium/components/user_scripts/FragmentWindowAndroid.java
 diff --git a/components/user_scripts/android/java/src/org/chromium/components/user_scripts/FragmentWindowAndroid.java b/components/user_scripts/android/java/src/org/chromium/components/user_scripts/FragmentWindowAndroid.java
 new file mode 100644
 new file mode 100644
 --- /dev/null
 --- /dev/null
@@ -1826,7 +1830,7 @@ diff --git a/components/user_scripts/android/java/src/org/chromium/components/us
 new file mode 100644
 new file mode 100644
 --- /dev/null
 --- /dev/null
 +++ b/components/user_scripts/android/java/src/org/chromium/components/user_scripts/UserScriptsBridge.java
 +++ b/components/user_scripts/android/java/src/org/chromium/components/user_scripts/UserScriptsBridge.java
-@@ -0,0 +1,200 @@
+@@ -0,0 +1,212 @@
 +/*
 +/*
 +    This file is part of Bromite.
 +    This file is part of Bromite.
 +
 +
@@ -1857,6 +1861,7 @@ new file mode 100644
 +import android.content.Context;
 +import android.content.Context;
 +import android.content.Intent;
 +import android.content.Intent;
 +import android.net.Uri;
 +import android.net.Uri;
++import android.provider.MediaStore;
 +import androidx.annotation.Nullable;
 +import androidx.annotation.Nullable;
 +import android.app.AlertDialog;
 +import android.app.AlertDialog;
 +import android.content.DialogInterface;
 +import android.content.DialogInterface;
@@ -1864,6 +1869,7 @@ new file mode 100644
 +import org.chromium.base.annotations.CalledByNative;
 +import org.chromium.base.annotations.CalledByNative;
 +import org.chromium.base.annotations.JNINamespace;
 +import org.chromium.base.annotations.JNINamespace;
 +import org.chromium.base.annotations.NativeMethods;
 +import org.chromium.base.annotations.NativeMethods;
++import org.chromium.base.ContentUriUtils;
 +import org.chromium.base.Log;
 +import org.chromium.base.Log;
 +import org.chromium.ui.base.WindowAndroid;
 +import org.chromium.ui.base.WindowAndroid;
 +
 +
@@ -1942,7 +1948,17 @@ new file mode 100644
 +            }
 +            }
 +        };
 +        };
 +
 +
-+        String message = context.getString(R.string.ask_to_install, ScriptFullPath);
++        String scriptName = ScriptFullPath;
++        if (ContentUriUtils.isContentUri(scriptName)) {
++            scriptName = ContentUriUtils.getFilePathFromContentUri(Uri.parse(scriptName));
++            if (scriptName == null) {
++                // fallback to content uri name if fail
++                scriptName = ContentUriUtils.getDisplayName(Uri.parse(ScriptFullPath), context,
++                    MediaStore.MediaColumns.DISPLAY_NAME);
++            }
++        }
++
++        String message = context.getString(R.string.ask_to_install, scriptName);
 +
 +
 +        AlertDialog.Builder builder = new AlertDialog.Builder(context);
 +        AlertDialog.Builder builder = new AlertDialog.Builder(context);
 +        builder.setMessage(message)
 +        builder.setMessage(message)
@@ -2828,7 +2844,7 @@ diff --git a/components/user_scripts/browser/user_script_loader.cc b/components/
 new file mode 100755
 new file mode 100755
 --- /dev/null
 --- /dev/null
 +++ b/components/user_scripts/browser/user_script_loader.cc
 +++ b/components/user_scripts/browser/user_script_loader.cc
-@@ -0,0 +1,714 @@
+@@ -0,0 +1,716 @@
 +/*
 +/*
 +    This file is part of Bromite.
 +    This file is part of Bromite.
 +
 +
@@ -3054,7 +3070,9 @@ new file mode 100755
 +    }
 +    }
 +
 +
 +    if (!infile.IsValid()) {
 +    if (!infile.IsValid()) {
-+      *error = u"Cannot open script source.";
++      base::File::Error out_error = infile.error_details();
++      *error = u"Cannot open script source. Error: " +
++                base::ASCIIToUTF16(base::File::ErrorToString(out_error));
 +      return false;
 +      return false;
 +    }
 +    }
 +
 +
@@ -3087,12 +3105,10 @@ new file mode 100755
 +      return false;
 +      return false;
 +    }
 +    }
 +
 +
-+    script->set_name(user_script_path.BaseName().value());
 +    script->set_match_origin_as_fallback(MatchOriginAsFallbackBehavior::kNever);
 +    script->set_match_origin_as_fallback(MatchOriginAsFallbackBehavior::kNever);
 +
 +
 +    std::unique_ptr<UserScript::File> file(new UserScript::File());
 +    std::unique_ptr<UserScript::File> file(new UserScript::File());
 +    file->set_content(content);
 +    file->set_content(content);
-+    file->set_url(GURL(base::StrCat({"https://userscripts/file/", script->name(), ".js"})));
 +
 +
 +    // create SHA256 of file
 +    // create SHA256 of file
 +    char raw[crypto::kSHA256Length] = {0};
 +    char raw[crypto::kSHA256Length] = {0};
@@ -3101,6 +3117,8 @@ new file mode 100755
 +    base::Base64Encode(base::StringPiece(raw, crypto::kSHA256Length), &key);
 +    base::Base64Encode(base::StringPiece(raw, crypto::kSHA256Length), &key);
 +    file->set_key(key);
 +    file->set_key(key);
 +
 +
++    file->set_url(GURL(base::StrCat({"https://userscripts/file/", key, ".js"})));
++
 +    script->js_scripts().push_back(std::move(file));
 +    script->js_scripts().push_back(std::move(file));
 +
 +
 +    // add into key the filename
 +    // add into key the filename
@@ -9884,7 +9902,7 @@ new file mode 100755
 +  bool is_subframe = web_frame->Parent();
 +  bool is_subframe = web_frame->Parent();
 +  if (!script->MatchesDocument(effective_document_url, is_subframe)) {
 +  if (!script->MatchesDocument(effective_document_url, is_subframe)) {
 +    if (base::FeatureList::IsEnabled(features::kEnableLoggingUserScripts))
 +    if (base::FeatureList::IsEnabled(features::kEnableLoggingUserScripts))
-+      LOG(INFO) << "UserScripts: Match name=" << script->name() <<
++      LOG(INFO) << "UserScripts: No Match name=" << script->name() <<
 +                                      " id=" << script->host_id().id() <<
 +                                      " id=" << script->host_id().id() <<
 +                                      " url=" << effective_document_url.spec();
 +                                      " url=" << effective_document_url.spec();
 +    return injection;
 +    return injection;
@@ -10549,7 +10567,7 @@ diff --git a/components/user_scripts/strings/userscripts_strings.grdp b/componen
 new file mode 100755
 new file mode 100755
 --- /dev/null
 --- /dev/null
 +++ b/components/user_scripts/strings/userscripts_strings.grdp
 +++ b/components/user_scripts/strings/userscripts_strings.grdp
-@@ -0,0 +1,55 @@
+@@ -0,0 +1,57 @@
 +<?xml version="1.0" encoding="utf-8"?>
 +<?xml version="1.0" encoding="utf-8"?>
 +<grit-part>
 +<grit-part>
 +
 +
@@ -10593,9 +10611,11 @@ new file mode 100755
 +  </message>
 +  </message>
 +
 +
 +  <message name="IDS_ASK_TO_INSTALL" desc=". [CHAR-LIMIT=32]" formatter_data="android_java">
 +  <message name="IDS_ASK_TO_INSTALL" desc=". [CHAR-LIMIT=32]" formatter_data="android_java">
-+    Only install user scripts that you have verified are secure, user scripts can steal your credentials and data.
++    Do you want to install this user script from following location?
 +
 +
-+Do you want to install <ph name="FILE">%s</ph>?
++<ph name="FILE">%s</ph>
++
++NOTE: only install user scripts that you have verified are secure, user scripts can steal your credentials and data.
 +  </message>
 +  </message>
 +  <message name="IDS_YES" desc=". [CHAR-LIMIT=32]" formatter_data="android_java">
 +  <message name="IDS_YES" desc=". [CHAR-LIMIT=32]" formatter_data="android_java">
 +    Yes
 +    Yes
@@ -10605,7 +10625,6 @@ new file mode 100755
 +  </message>
 +  </message>
 +
 +
 +</grit-part>
 +</grit-part>
-\ No newline at end of file
 diff --git a/tools/gritsettings/resource_ids.spec b/tools/gritsettings/resource_ids.spec
 diff --git a/tools/gritsettings/resource_ids.spec b/tools/gritsettings/resource_ids.spec
 --- a/tools/gritsettings/resource_ids.spec
 --- a/tools/gritsettings/resource_ids.spec
 +++ b/tools/gritsettings/resource_ids.spec
 +++ b/tools/gritsettings/resource_ids.spec