PWAs should not show up when searching for the main app (#4221)

* Search shows up steam games

* Formatting

* Filtering only those steam shortcuts which run an application

* Using equals instead of ==

* PWAs should not show up when searching for the main app

* Modified the subtitle to say progressive web application

* renamed to web application

* To search for web applications for all chromium based browsers

* Renamed it to WebApplication

* Added unit tests and refactored code

* made string global const

* Added localization tags

* Added a separate function for localization as the IPublic API was not available to all

* Removed unnecessary references and variables

* Update src/modules/launcher/Plugins/Microsoft.Plugin.Program/Languages/de.xaml

Co-authored-by: htcfreek <61519853+htcfreek@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: htcfreek <61519853+htcfreek@users.noreply.github.com>

* Added enum for application types

Co-authored-by: htcfreek <61519853+htcfreek@users.noreply.github.com>
This commit is contained in:
Alekhya 2020-06-12 13:11:24 -07:00 committed by GitHub
parent 4c70e75bfc
commit 236c1208e6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 245 additions and 10 deletions

View File

@ -34,4 +34,9 @@
<system:String x:Key="wox_plugin_program_plugin_name">Programm</system:String>
<system:String x:Key="wox_plugin_program_plugin_description">Suche Programme mit Wox</system:String>
<!--Application subtitle-->
<system:String x:Key="powertoys_run_plugin_program_win32_application">Win32-Anwendung</system:String>
<system:String x:Key="powertoys_run_plugin_program_internet_shortcut_application">Weblink-Anwendung</system:String>
<system:String x:Key="powertoys_run_plugin_program_web_application">Web-Anwendung</system:String>
</ResourceDictionary>

View File

@ -45,4 +45,8 @@
<system:String x:Key="wox_plugin_program_disable_dlgtitle_success">Success</system:String>
<system:String x:Key="wox_plugin_program_disable_dlgtitle_success_message">Successfully disabled this program from displaying in your query</system:String>
<!--Application subtitle-->
<system:String x:Key="powertoys_run_plugin_program_win32_application">Win32 application</system:String>
<system:String x:Key="powertoys_run_plugin_program_internet_shortcut_application">Internet shortcut application</system:String>
<system:String x:Key="powertoys_run_plugin_program_web_application">Web application</system:String>
</ResourceDictionary>

View File

@ -35,4 +35,9 @@
<system:String x:Key="wox_plugin_program_plugin_name">Program</system:String>
<system:String x:Key="wox_plugin_program_plugin_description">Search programs in Wox</system:String>
<!--Application subtitle-->
<system:String x:Key="powertoys_run_plugin_program_win32_application">Win32 application</system:String>
<system:String x:Key="powertoys_run_plugin_program_internet_shortcut_application">Internet shortcut application</system:String>
<system:String x:Key="powertoys_run_plugin_program_web_application">Web application</system:String>
</ResourceDictionary>

View File

@ -34,4 +34,9 @@
<system:String x:Key="wox_plugin_program_plugin_name">Programy</system:String>
<system:String x:Key="wox_plugin_program_plugin_description">Szukaj i uruchamiaj programy z poziomu Woxa</system:String>
<!--Application subtitle-->
<system:String x:Key="powertoys_run_plugin_program_win32_application">Win32 application</system:String>
<system:String x:Key="powertoys_run_plugin_program_internet_shortcut_application">Internet shortcut application</system:String>
<system:String x:Key="powertoys_run_plugin_program_web_application">Web application</system:String>
</ResourceDictionary>

View File

@ -36,4 +36,9 @@
<system:String x:Key="wox_plugin_program_invalid_path">Geçersiz Konum</system:String>
<!--Application subtitle-->
<system:String x:Key="powertoys_run_plugin_program_win32_application">Win32 application</system:String>
<system:String x:Key="powertoys_run_plugin_program_internet_shortcut_application">Internet shortcut application</system:String>
<system:String x:Key="powertoys_run_plugin_program_web_application">Web application</system:String>
</ResourceDictionary>

View File

@ -36,4 +36,9 @@
<system:String x:Key="wox_plugin_program_invalid_path">无效路径</system:String>
<!--Application subtitle-->
<system:String x:Key="powertoys_run_plugin_program_win32_application">Win32 application</system:String>
<system:String x:Key="powertoys_run_plugin_program_internet_shortcut_application">Internet shortcut application</system:String>
<system:String x:Key="powertoys_run_plugin_program_web_application">Web application</system:String>
</ResourceDictionary>

View File

@ -33,4 +33,9 @@
<system:String x:Key="wox_plugin_program_plugin_name">程式</system:String>
<system:String x:Key="wox_plugin_program_plugin_description">在 Wox 中搜尋程式</system:String>
<!--Application subtitle-->
<system:String x:Key="powertoys_run_plugin_program_win32_application">Win32 application</system:String>
<system:String x:Key="powertoys_run_plugin_program_internet_shortcut_application">Internet shortcut application</system:String>
<system:String x:Key="powertoys_run_plugin_program_web_application">Web application</system:String>
</ResourceDictionary>

View File

@ -103,6 +103,7 @@ namespace Microsoft.Plugin.Program.Programs
public String description = String.Empty;
// Sets to true if the program takes in arguments
public String Arguments = String.Empty;
public bool hasArguments = false;
// Retrieve the target path using Shell Link
@ -130,6 +131,7 @@ namespace Microsoft.Plugin.Program.Programs
StringBuilder argumentBuffer = new StringBuilder(MAX_PATH);
((IShellLinkW)link).GetArguments(argumentBuffer, argumentBuffer.Capacity);
Arguments = argumentBuffer.ToString();
// Set variable to true if the program takes in any arguments
if (argumentBuffer.Length != 0)

View File

@ -31,16 +31,24 @@ namespace Microsoft.Plugin.Program.Programs
public bool Valid { get; set; }
public bool Enabled { get; set; }
public bool hasArguments { get; set; } = false;
public string Arguments { get; set; } = String.Empty;
public string Location => ParentDirectory;
public string AppType { get; set; }
public uint AppType { get; set; }
private const string ShortcutExtension = "lnk";
private const string ApplicationReferenceExtension = "appref-ms";
private const string ExeExtension = "exe";
private const string InternetShortcutExtension = "url";
private const string InternetShortcutApplication = "Internet shortcut application";
private const string Win32Application = "Win32 application";
private const string proxyWebApp = "_proxy.exe";
private const string appIdArgument = "--app-id";
private enum ApplicationTypes
{
WEB_APPLICATION = 0,
INTERNET_SHORTCUT_APPLICATION = 1,
WIN32_APPLICATION = 2
}
private int Score(string query)
{
@ -51,6 +59,68 @@ namespace Microsoft.Plugin.Program.Programs
return score;
}
public bool IsWebApplication()
{
// To Filter PWAs when the user searches for the main application
// All Chromium based applications contain the --app-id argument
// Reference : https://codereview.chromium.org/399045/show
bool isWebApplication = FullPath.Contains(proxyWebApp) && Arguments.Contains(appIdArgument);
return isWebApplication;
}
// Condition to Filter pinned Web Applications or PWAs when searching for the main application
public bool FilterWebApplication(string query)
{
// If the app is not a web application, then do not filter it
if(!IsWebApplication())
{
return false;
}
// Set the subtitle to 'Web Application'
AppType = (uint)ApplicationTypes.WEB_APPLICATION;
string[] subqueries = query.Split();
bool nameContainsQuery = false;
bool pathContainsQuery = false;
// check if any space separated query is a part of the app name or path name
foreach (var subquery in subqueries)
{
if (FullPath.Contains(subquery, StringComparison.OrdinalIgnoreCase))
{
pathContainsQuery = true;
}
if(Name.Contains(subquery, StringComparison.OrdinalIgnoreCase))
{
nameContainsQuery = true;
}
}
return pathContainsQuery && !nameContainsQuery;
}
// Function to set the subtitle based on the Type of application
public string SetSubtitle(uint AppType, IPublicAPI api)
{
if(AppType == (uint)ApplicationTypes.WIN32_APPLICATION)
{
return api.GetTranslation("powertoys_run_plugin_program_win32_application");
}
else if(AppType == (uint)ApplicationTypes.INTERNET_SHORTCUT_APPLICATION)
{
return api.GetTranslation("powertoys_run_plugin_program_internet_shortcut_application");
}
else if(AppType == (uint)ApplicationTypes.WEB_APPLICATION)
{
return api.GetTranslation("powertoys_run_plugin_program_web_application");
}
else
{
return String.Empty;
}
}
public Result Result(string query, IPublicAPI api)
{
var score = Score(query);
@ -64,10 +134,18 @@ namespace Microsoft.Plugin.Program.Programs
var noArgumentScoreModifier = 5;
score += noArgumentScoreModifier;
}
else
{
// Filter Web Applications when searching for the main application
if (FilterWebApplication(query))
{
return null;
}
}
var result = new Result
{
SubTitle = AppType,
SubTitle = SetSubtitle(AppType, api),
IcoPath = IcoPath,
Score = score,
ContextData = this,
@ -105,7 +183,7 @@ namespace Microsoft.Plugin.Program.Programs
public List<ContextMenuResult> ContextMenus(IPublicAPI api)
{
// To add a context menu only to open file location as Internet shortcut applications do not have the functionality to run as admin
if(AppType.Equals(InternetShortcutApplication))
if(AppType == (uint)ApplicationTypes.INTERNET_SHORTCUT_APPLICATION)
{
var contextMenuItems = new List<ContextMenuResult>
{
@ -195,7 +273,7 @@ namespace Microsoft.Plugin.Program.Programs
Description = string.Empty,
Valid = true,
Enabled = true,
AppType = Win32Application
AppType = (uint)ApplicationTypes.WIN32_APPLICATION
};
return p;
}
@ -260,10 +338,9 @@ namespace Microsoft.Plugin.Program.Programs
FullPath = path.ToLower(),
UniqueIdentifier = path,
ParentDirectory = Directory.GetParent(path).FullName,
Description = InternetShortcutApplication,
Valid = true,
Enabled = true,
AppType = InternetShortcutApplication
AppType = (uint)ApplicationTypes.INTERNET_SHORTCUT_APPLICATION
};
return p;
}
@ -295,6 +372,7 @@ namespace Microsoft.Plugin.Program.Programs
program.FullPath = Path.GetFullPath(target).ToLower();
program.ExecutableName = Path.GetFileName(target);
program.hasArguments = _helper.hasArguments;
program.Arguments = _helper.Arguments;
var description = _helper.description;
if (!string.IsNullOrEmpty(description))

View File

@ -78,6 +78,53 @@ namespace Wox.Test.Plugins
LnkResolvedPath = null
};
Win32 twitter_pwa = new Win32
{
Name = "Twitter",
FullPath = "c:\\program files (x86)\\google\\chrome\\application\\chrome_proxy.exe",
LnkResolvedPath = "c:\\users\\powertoys\\appdata\\roaming\\microsoft\\windows\\start menu\\programs\\chrome apps\\twitter.lnk",
Arguments = " --profile-directory=Default --app-id=jgeosdfsdsgmkedfgdfgdfgbkmhcgcflmi"
};
Win32 pinned_webpage = new Win32
{
Name = "Web page",
FullPath = "c:\\program files (x86)\\microsoft\\edge\\application\\msedge_proxy.exe",
LnkResolvedPath = "c:\\users\\powertoys\\appdata\\roaming\\microsoft\\windows\\start menu\\programs\\web page.lnk",
Arguments = "--profile-directory=Default --app-id=homljgmgpmcbpjbnjpfijnhipfkiclkd"
};
Win32 edge_named_pinned_webpage = new Win32
{
Name = "edge - Bing",
FullPath = "c:\\program files (x86)\\microsoft\\edge\\application\\msedge_proxy.exe",
LnkResolvedPath = "c:\\users\\powertoys\\appdata\\roaming\\microsoft\\windows\\start menu\\programs\\edge - bing.lnk",
Arguments = " --profile-directory=Default --app-id=aocfnapldcnfbofgmbbllojgocaelgdd"
};
Win32 msedge = new Win32
{
Name = "Microsoft Edge",
ExecutableName = "msedge.exe",
FullPath = "c:\\program files (x86)\\microsoft\\edge\\application\\msedge.exe",
LnkResolvedPath = "c:\\programdata\\microsoft\\windows\\start menu\\programs\\microsoft edge.lnk"
};
Win32 chrome = new Win32
{
Name = "Google Chrome",
ExecutableName = "chrome.exe",
FullPath = "c:\\program files (x86)\\google\\chrome\\application\\chrome.exe",
LnkResolvedPath = "c:\\programdata\\microsoft\\windows\\start menu\\programs\\google chrome.lnk"
};
Win32 dummy_proxy_app = new Win32
{
Name = "Proxy App",
ExecutableName = "test_proxy.exe",
FullPath = "c:\\program files (x86)\\microsoft\\edge\\application\\test_proxy.exe",
LnkResolvedPath = "c:\\programdata\\microsoft\\windows\\start menu\\programs\\test proxy.lnk"
};
[Test]
public void DedupFunction_whenCalled_mustRemoveDuplicateNotepads()
@ -139,5 +186,79 @@ namespace Wox.Test.Plugins
// Assert
Assert.AreEqual(apps.Length, 3);
}
[Test]
public void FunctionIsWebApplication_ShouldReturnTrue_ForWebApplications()
{
// The IsWebApplication(() function must return true for all PWAs and pinned web pages
Assert.IsTrue(twitter_pwa.IsWebApplication());
Assert.IsTrue(pinned_webpage.IsWebApplication());
Assert.IsTrue(edge_named_pinned_webpage.IsWebApplication());
// Should not filter apps whose executable name ends with proxy.exe
Assert.IsFalse(dummy_proxy_app.IsWebApplication());
}
[TestCase("ignore")]
public void FunctionFilterWebApplication_ShouldReturnFalse_WhenSearchingForTheMainApp(string query)
{
// Irrespective of the query, the FilterWebApplication() Function must not filter main apps such as edge and chrome
Assert.IsFalse(msedge.FilterWebApplication(query));
Assert.IsFalse(chrome.FilterWebApplication(query));
}
[TestCase("edge", ExpectedResult = true)]
[TestCase("EDGE", ExpectedResult = true)]
[TestCase("msedge", ExpectedResult = true)]
[TestCase("Microsoft", ExpectedResult = true)]
[TestCase("edg", ExpectedResult = true)]
[TestCase("Edge page", ExpectedResult = false)]
[TestCase("Edge Web page", ExpectedResult = false)]
public bool EdgeWebSites_ShouldBeFiltered_WhenSearchingForEdge(string query)
{
return pinned_webpage.FilterWebApplication(query);
}
[TestCase("chrome", ExpectedResult = true)]
[TestCase("CHROME", ExpectedResult = true)]
[TestCase("Google", ExpectedResult = true)]
[TestCase("Google Chrome", ExpectedResult = true)]
[TestCase("Google Chrome twitter", ExpectedResult = false)]
public bool ChromeWebSites_ShouldBeFiltered_WhenSearchingForChrome(string query)
{
return twitter_pwa.FilterWebApplication(query);
}
[TestCase("twitter", 0, ExpectedResult = false)]
[TestCase("Twit", 0, ExpectedResult = false)]
[TestCase("TWITTER", 0, ExpectedResult = false)]
[TestCase("web", 1, ExpectedResult = false)]
[TestCase("Page", 1, ExpectedResult = false)]
[TestCase("WEB PAGE", 1, ExpectedResult = false)]
[TestCase("edge", 2, ExpectedResult = false)]
[TestCase("EDGE", 2, ExpectedResult = false)]
public bool PinnedWebPages_ShouldNotBeFiltered_WhenSearchingForThem(string query, int Case)
{
const uint CASE_TWITTER = 0;
const uint CASE_WEB_PAGE = 1;
const uint CASE_EDGE_NAMED_WEBPAGE = 2;
// If the query is a part of the name of the web application, it should not be filtered,
// even if the name is the same as that of the main application, eg: case 2 - edge
if (Case == CASE_TWITTER)
{
return twitter_pwa.FilterWebApplication(query);
}
else if(Case == CASE_WEB_PAGE)
{
return pinned_webpage.FilterWebApplication(query);
}
else if(Case == CASE_EDGE_NAMED_WEBPAGE)
{
return edge_named_pinned_webpage.FilterWebApplication(query);
}
// unreachable code
return true;
}
}
}