1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "ios/chrome/browser/ui/webui/chrome_web_ui_ios_controller_factory.h"
6
7#import <Foundation/Foundation.h>
8
9#include "base/bind.h"
10#include "base/location.h"
11#include "ios/chrome/browser/chrome_url_constants.h"
12#include "ios/chrome/browser/policy/policy_features.h"
13#include "ios/chrome/browser/system_flags.h"
14#include "ios/chrome/browser/ui/webui/about_ui.h"
15#include "ios/chrome/browser/ui/webui/autofill_and_password_manager_internals/autofill_internals_ui_ios.h"
16#include "ios/chrome/browser/ui/webui/autofill_and_password_manager_internals/password_manager_internals_ui_ios.h"
17#include "ios/chrome/browser/ui/webui/crashes_ui.h"
18#include "ios/chrome/browser/ui/webui/flags_ui.h"
19#include "ios/chrome/browser/ui/webui/gcm/gcm_internals_ui.h"
20#include "ios/chrome/browser/ui/webui/inspect/inspect_ui.h"
21#include "ios/chrome/browser/ui/webui/interstitials/interstitial_ui.h"
22#include "ios/chrome/browser/ui/webui/management/management_ui.h"
23#include "ios/chrome/browser/ui/webui/net_export/net_export_ui.h"
24#include "ios/chrome/browser/ui/webui/ntp_tiles_internals_ui.h"
25#include "ios/chrome/browser/ui/webui/omaha_ui.h"
26#include "ios/chrome/browser/ui/webui/policy/policy_ui.h"
27#include "ios/chrome/browser/ui/webui/prefs_internals_ui.h"
28#include "ios/chrome/browser/ui/webui/signin_internals_ui_ios.h"
29#include "ios/chrome/browser/ui/webui/suggestions_ui.h"
30#include "ios/chrome/browser/ui/webui/terms_ui.h"
31#include "ios/chrome/browser/ui/webui/translate_internals/translate_internals_ui.h"
32#include "ios/chrome/browser/ui/webui/ukm_internals_ui.h"
33#include "ios/chrome/browser/ui/webui/user_actions_ui.h"
34#include "ios/chrome/browser/ui/webui/version_ui.h"
35#include "ios/components/webui/sync_internals/sync_internals_ui.h"
36#include "ios/components/webui/web_ui_url_constants.h"
37#include "url/gurl.h"
38
39#if !defined(__has_feature) || !__has_feature(objc_arc)
40#error "This file requires ARC support."
41#endif
42
43using web::WebUIIOS;
44using web::WebUIIOSController;
45
46namespace {
47
48// A function for creating a new WebUIIOS.
49using WebUIIOSFactoryFunction =
50    std::unique_ptr<WebUIIOSController> (*)(WebUIIOS* web_ui, const GURL& url);
51
52// Template for defining WebUIIOSFactoryFunction.
53template <class T>
54std::unique_ptr<WebUIIOSController> NewWebUIIOS(WebUIIOS* web_ui,
55                                                const GURL& url) {
56  return std::make_unique<T>(web_ui, url.host());
57}
58
59// Returns a function that can be used to create the right type of WebUIIOS for
60// a tab, based on its URL. Returns NULL if the URL doesn't have WebUIIOS
61// associated with it.
62WebUIIOSFactoryFunction GetWebUIIOSFactoryFunction(const GURL& url) {
63  // This will get called a lot to check all URLs, so do a quick check of other
64  // schemes to filter out most URLs.
65  if (!url.SchemeIs(kChromeUIScheme))
66    return nullptr;
67
68  // Please keep this in alphabetical order. If #ifs or special logic is
69  // required, add it below in the appropriate section.
70  const std::string url_host = url.host();
71  if (url_host == kChromeUIAutofillInternalsHost)
72    return &NewWebUIIOS<AutofillInternalsUIIOS>;
73  if (url_host == kChromeUIChromeURLsHost ||
74      url_host == kChromeUIHistogramHost || url_host == kChromeUICreditsHost)
75    return &NewWebUIIOS<AboutUI>;
76  if (url_host == kChromeUICrashesHost)
77    return &NewWebUIIOS<CrashesUI>;
78  if (url_host == kChromeUIFlagsHost)
79    return &NewWebUIIOS<FlagsUI>;
80  if (url_host == kChromeUIGCMInternalsHost)
81    return &NewWebUIIOS<GCMInternalsUI>;
82  if (url_host == kChromeUIInspectHost)
83    return &NewWebUIIOS<InspectUI>;
84  if (url_host == kChromeUIIntersitialsHost)
85    return &NewWebUIIOS<InterstitialUI>;
86  if (url_host == kChromeUIManagementHost)
87    return &NewWebUIIOS<ManagementUI>;
88  if (url_host == kChromeUINetExportHost)
89    return &NewWebUIIOS<NetExportUI>;
90  if (url_host == kChromeUINTPTilesInternalsHost)
91    return &NewWebUIIOS<NTPTilesInternalsUI>;
92  if (url_host == kChromeUIOmahaHost)
93    return &NewWebUIIOS<OmahaUI>;
94  if (url_host == kChromeUIPasswordManagerInternalsHost)
95    return &NewWebUIIOS<PasswordManagerInternalsUIIOS>;
96  if (url_host == kChromeUIPrefsInternalsHost)
97    return &NewWebUIIOS<PrefsInternalsUI>;
98  if (url_host == kChromeUISignInInternalsHost)
99    return &NewWebUIIOS<SignInInternalsUIIOS>;
100  if (url.host_piece() == kChromeUISuggestionsHost)
101    return &NewWebUIIOS<suggestions::SuggestionsUI>;
102  if (url.host_piece() == kChromeUITranslateInternalsHost)
103    return &NewWebUIIOS<TranslateInternalsUI>;
104  if (url_host == kChromeUIURLKeyedMetricsHost)
105    return &NewWebUIIOS<UkmInternalsUI>;
106  if (url_host == kChromeUIUserActionsHost)
107    return &NewWebUIIOS<UserActionsUI>;
108  if (url_host == kChromeUISyncInternalsHost)
109    return &NewWebUIIOS<SyncInternalsUI>;
110  if (url_host == kChromeUITermsHost)
111    return &NewWebUIIOS<TermsUI>;
112  if (url_host == kChromeUIVersionHost)
113    return &NewWebUIIOS<VersionUI>;
114
115  if (IsEnterprisePolicyEnabled() && url_host == kChromeUIPolicyHost) {
116    return &NewWebUIIOS<PolicyUI>;
117  }
118
119  return nullptr;
120}
121
122}  // namespace
123
124NSInteger ChromeWebUIIOSControllerFactory::GetErrorCodeForWebUIURL(
125    const GURL& url) const {
126  if (url.host() == kChromeUIDinoHost) {
127    return NSURLErrorNotConnectedToInternet;
128  }
129  if (GetWebUIIOSFactoryFunction(url))
130    return 0;
131  return NSURLErrorUnsupportedURL;
132}
133
134std::unique_ptr<WebUIIOSController>
135ChromeWebUIIOSControllerFactory::CreateWebUIIOSControllerForURL(
136    WebUIIOS* web_ui,
137    const GURL& url) const {
138  WebUIIOSFactoryFunction function = GetWebUIIOSFactoryFunction(url);
139  if (!function)
140    return nullptr;
141
142  return (*function)(web_ui, url);
143}
144
145// static
146ChromeWebUIIOSControllerFactory*
147ChromeWebUIIOSControllerFactory::GetInstance() {
148  static base::NoDestructor<ChromeWebUIIOSControllerFactory> instance;
149  return instance.get();
150}
151
152ChromeWebUIIOSControllerFactory::ChromeWebUIIOSControllerFactory() {}
153
154ChromeWebUIIOSControllerFactory::~ChromeWebUIIOSControllerFactory() {}
155