Bug 1286530 - Get rid of AvailableIn, CheckAnyPermissions and CheckAllPermissions draft
authorAlexandre Lissy <lissyx@lissyx.dyndns.org>
Thu, 21 Apr 2016 15:48:59 +0200
changeset 387082 d67386063883fc890c5f77c558089adbcf99b974
parent 386893 04821a70c739a00d12e12df651c0989441e22728
child 387083 827c2207f69c449f0b44ec5663a7e422f0d86e6c
push id22896
push userbmo:lissyx+mozillians@lissyx.dyndns.org
push dateWed, 13 Jul 2016 13:02:44 +0000
bugs1286530
milestone50.0a1
Bug 1286530 - Get rid of AvailableIn, CheckAnyPermissions and CheckAllPermissions MozReview-Commit-ID: 7gD1URPkuTb Conflicts: dom/bindings/BindingUtils.cpp dom/bindings/Codegen.py dom/bindings/parser/WebIDL.py
dom/base/Navigator.cpp
dom/bindings/BindingUtils.cpp
dom/bindings/BindingUtils.h
dom/bindings/Codegen.py
dom/bindings/Configuration.py
dom/bindings/DOMJSClass.h
dom/bindings/mozwebidlcodegen/__init__.py
dom/bindings/parser/WebIDL.py
dom/bindings/test/TestCodeGen.webidl
dom/bindings/test/TestJSImplGen.webidl
dom/workers/WorkerPrivate.cpp
dom/workers/WorkerPrivate.h
dom/workers/WorkerScope.cpp
dom/workers/Workers.h
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -113,18 +113,16 @@
 #include "WorkerPrivate.h"
 #include "WorkerRunnable.h"
 
 #if defined(XP_LINUX)
 #include "mozilla/Hal.h"
 #endif
 #include "mozilla/dom/ContentChild.h"
 
-#include "mozilla/dom/FeatureList.h"
-
 #ifdef MOZ_EME
 #include "mozilla/EMEUtils.h"
 #include "mozilla/DetailedPromise.h"
 #endif
 
 #ifdef MOZ_WIDGET_GONK
 #include <cutils/properties.h>
 #endif
@@ -1787,21 +1785,17 @@ Navigator::HasFeature(const nsAString& a
     }
 #endif
 
     if (featureName.EqualsLiteral("XMLHttpRequest.mozSystem")) {
       p->MaybeResolve(true);
       return p.forget();
     }
 
-    if (IsFeatureDetectible(featureName)) {
-      p->MaybeResolve(true);
-    } else {
-      p->MaybeResolve(JS::UndefinedHandleValue);
-    }
+    p->MaybeResolve(JS::UndefinedHandleValue);
     return p.forget();
   }
 
   // resolve with <undefined> because the feature name is not supported
   p->MaybeResolve(JS::UndefinedHandleValue);
 
   return p.forget();
 }
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -2497,42 +2497,16 @@ ConvertJSValueToByteString(JSContext* cx
     return false;
   }
 
   JS_EncodeStringToBuffer(cx, s, result.BeginWriting(), length);
 
   return true;
 }
 
-bool
-IsInPrivilegedApp(JSContext* aCx, JSObject* aObj)
-{
-  if (!NS_IsMainThread()) {
-    return GetWorkerPrivateFromContext(aCx)->IsInPrivilegedApp();
-  }
-
-  nsIPrincipal* principal = nsContentUtils::ObjectPrincipal(aObj);
-  uint16_t appStatus = principal->GetAppStatus();
-  return (appStatus == nsIPrincipal::APP_STATUS_CERTIFIED ||
-          appStatus == nsIPrincipal::APP_STATUS_PRIVILEGED) ||
-          Preferences::GetBool("dom.ignore_webidl_scope_checks", false);
-}
-
-bool
-IsInCertifiedApp(JSContext* aCx, JSObject* aObj)
-{
-  if (!NS_IsMainThread()) {
-    return GetWorkerPrivateFromContext(aCx)->IsInCertifiedApp();
-  }
-
-  nsIPrincipal* principal = nsContentUtils::ObjectPrincipal(aObj);
-  return principal->GetAppStatus() == nsIPrincipal::APP_STATUS_CERTIFIED ||
-         Preferences::GetBool("dom.ignore_webidl_scope_checks", false);
-}
-
 void
 FinalizeGlobal(JSFreeOp* aFreeOp, JSObject* aObj)
 {
   MOZ_ASSERT(js::GetObjectClass(aObj)->flags & JSCLASS_DOM_GLOBAL);
   mozilla::dom::DestroyProtoAndIfaceCache(aObj);
 }
 
 bool
@@ -2558,60 +2532,16 @@ EnumerateGlobal(JSContext* aCx, JS::Hand
   MOZ_ASSERT(JS_IsGlobalObject(aObj),
              "Should have a global here, since we plan to enumerate standard "
              "classes!");
 
   return JS_EnumerateStandardClasses(aCx, aObj);
 }
 
 bool
-CheckAnyPermissions(JSContext* aCx, JSObject* aObj, const char* const aPermissions[])
-{
-  JS::Rooted<JSObject*> rootedObj(aCx, aObj);
-  nsPIDOMWindowInner* window = xpc::WindowGlobalOrNull(rootedObj)->AsInner();
-  if (!window) {
-    return false;
-  }
-
-  nsCOMPtr<nsIPermissionManager> permMgr = services::GetPermissionManager();
-  NS_ENSURE_TRUE(permMgr, false);
-
-  do {
-    uint32_t permission = nsIPermissionManager::DENY_ACTION;
-    permMgr->TestPermissionFromWindow(window, *aPermissions, &permission);
-    if (permission == nsIPermissionManager::ALLOW_ACTION) {
-      return true;
-    }
-  } while (*(++aPermissions));
-  return false;
-}
-
-bool
-CheckAllPermissions(JSContext* aCx, JSObject* aObj, const char* const aPermissions[])
-{
-  JS::Rooted<JSObject*> rootedObj(aCx, aObj);
-  nsPIDOMWindowInner* window = xpc::WindowGlobalOrNull(rootedObj)->AsInner();
-  if (!window) {
-    return false;
-  }
-
-  nsCOMPtr<nsIPermissionManager> permMgr = services::GetPermissionManager();
-  NS_ENSURE_TRUE(permMgr, false);
-
-  do {
-    uint32_t permission = nsIPermissionManager::DENY_ACTION;
-    permMgr->TestPermissionFromWindow(window, *aPermissions, &permission);
-    if (permission != nsIPermissionManager::ALLOW_ACTION) {
-      return false;
-    }
-  } while (*(++aPermissions));
-  return true;
-}
-
-bool
 IsNonExposedGlobal(JSContext* aCx, JSObject* aGlobal,
                    uint32_t aNonExposedGlobals)
 {
   MOZ_ASSERT(aNonExposedGlobals, "Why did we get called?");
   MOZ_ASSERT((aNonExposedGlobals &
               ~(GlobalNames::Window |
                 GlobalNames::BackstagePass |
                 GlobalNames::DedicatedWorkerGlobalScope |
--- a/dom/bindings/BindingUtils.h
+++ b/dom/bindings/BindingUtils.h
@@ -2987,30 +2987,16 @@ class GetCCParticipant<T, true>
 public:
   static constexpr nsCycleCollectionParticipant*
   Get()
   {
     return nullptr;
   }
 };
 
-/*
- * Helper function for testing whether the given object comes from a
- * privileged app.
- */
-bool
-IsInPrivilegedApp(JSContext* aCx, JSObject* aObj);
-
-/*
- * Helper function for testing whether the given object comes from a
- * certified app.
- */
-bool
-IsInCertifiedApp(JSContext* aCx, JSObject* aObj);
-
 void
 FinalizeGlobal(JSFreeOp* aFop, JSObject* aObj);
 
 bool
 ResolveGlobal(JSContext* aCx, JS::Handle<JSObject*> aObj,
               JS::Handle<jsid> aId, bool* aResolvedp);
 
 bool
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -1864,97 +1864,63 @@ class CGClassHasInstanceHook(CGAbstractS
         hasInstanceCode += "return true;\n"
         return header + hasInstanceCode
 
 
 def isChromeOnly(m):
     return m.getExtendedAttribute("ChromeOnly")
 
 
-def getAvailableInTestFunc(obj):
-    availableIn = obj.getExtendedAttribute("AvailableIn")
-    if availableIn is None:
-        return None
-    assert isinstance(availableIn, list) and len(availableIn) == 1
-    if availableIn[0] == "PrivilegedApps":
-        return "IsInPrivilegedApp"
-    if availableIn[0] == "CertifiedApps":
-        return "IsInCertifiedApp"
-    raise TypeError("Unknown AvailableIn value '%s'" % availableIn[0])
-
-
 class MemberCondition:
     """
     An object representing the condition for a member to actually be
     exposed.  Any of the arguments can be None.  If not
     None, they should have the following types:
 
     pref: The name of the preference.
     func: The name of the function.
     secureContext: A bool indicating whether a secure context is required.
-    available: A string indicating where we should be available.
-    checkAnyPermissions: An integer index for the anypermissions_* to use.
-    checkAllPermissions: An integer index for the allpermissions_* to use.
     nonExposedGlobals: A set of names of globals.  Can be empty, in which case
                        it's treated the same way as None.
     """
-    def __init__(self, pref=None, func=None, secureContext=False, available=None,
-                 checkAnyPermissions=None, checkAllPermissions=None,
+    def __init__(self, pref=None, func=None, secureContext=False,
                  nonExposedGlobals=None):
         assert pref is None or isinstance(pref, str)
         assert func is None or isinstance(func, str)
         assert isinstance(secureContext, bool)
-        assert available is None or isinstance(available, str)
-        assert checkAnyPermissions is None or isinstance(checkAnyPermissions, int)
-        assert checkAllPermissions is None or isinstance(checkAllPermissions, int)
         assert nonExposedGlobals is None or isinstance(nonExposedGlobals, set)
         self.pref = pref
         self.secureContext = secureContext
 
         def toFuncPtr(val):
             if val is None:
                 return "nullptr"
             return "&" + val
         self.func = toFuncPtr(func)
-        self.available = toFuncPtr(available)
-        if checkAnyPermissions is None:
-            self.checkAnyPermissions = "nullptr"
-        else:
-            self.checkAnyPermissions = "anypermissions_%i" % checkAnyPermissions
-        if checkAllPermissions is None:
-            self.checkAllPermissions = "nullptr"
-        else:
-            self.checkAllPermissions = "allpermissions_%i" % checkAllPermissions
 
         if nonExposedGlobals:
             # Nonempty set
             self.nonExposedGlobals = " | ".join(
                 map(lambda g: "GlobalNames::%s" % g,
                     sorted(nonExposedGlobals)))
         else:
             self.nonExposedGlobals = "0"
 
     def __eq__(self, other):
         return (self.pref == other.pref and self.func == other.func and
                 self.secureContext == other.secureContext and
-                self.available == other.available and
-                self.checkAnyPermissions == other.checkAnyPermissions and
-                self.checkAllPermissions == other.checkAllPermissions and
                 self.nonExposedGlobals == other.nonExposedGlobals)
 
     def __ne__(self, other):
         return not self.__eq__(other)
 
     def hasDisablers(self):
         return (self.pref is not None or
                 self.secureContext or
                 self.func != "nullptr" or
-                self.available != "nullptr" or
-                self.checkAnyPermissions != "nullptr" or
-                self.checkAllPermissions != "nullptr" or
                 self.nonExposedGlobals != "0")
 
 
 class PropertyDefiner:
     """
     A common superclass for defining things on prototype objects.
 
     Subclasses should implement generateArray to generate the actual arrays of
@@ -2014,19 +1980,16 @@ class PropertyDefiner:
         nonExposureSet = interface.exposureSet - interfaceMember.exposureSet
 
         return MemberCondition(
             PropertyDefiner.getStringAttr(interfaceMember,
                                           "Pref"),
             PropertyDefiner.getStringAttr(interfaceMember,
                                           "Func"),
             interfaceMember.getExtendedAttribute("SecureContext") is not None,
-            getAvailableInTestFunc(interfaceMember),
-            descriptor.checkAnyPermissionsIndicesForMembers.get(interfaceMember.identifier.name),
-            descriptor.checkAllPermissionsIndicesForMembers.get(interfaceMember.identifier.name),
             nonExposureSet)
 
     def generatePrefableArray(self, array, name, specFormatter, specTerminator,
                               specType, getCondition, getDataTuple, doIdArrays):
         """
         This method generates our various arrays.
 
         array is an array of interface members as passed to generateArray
@@ -2060,17 +2023,17 @@ class PropertyDefiner:
 
         specs = []
         disablers = []
         prefableSpecs = []
 
         disablersTemplate = dedent(
             """
             static PrefableDisablers %s_disablers%d = {
-              true, %s, %s, %s, %s, %s, %s
+              true, %s, %s, %s
             };
             """)
         prefableWithDisablersTemplate = '  { &%s_disablers%d, &%s_specs[%d] }'
         prefableWithoutDisablersTemplate = '  { nullptr, &%s_specs[%d] }'
         prefCacheTemplate = '&%s[%d].disablers->enabled'
 
         def switchToCondition(props, condition):
             # Remember the info about where our pref-controlled
@@ -2082,20 +2045,17 @@ class PropertyDefiner:
             # Set up pointers to the new sets of specs inside prefableSpecs
             if condition.hasDisablers():
                 prefableSpecs.append(prefableWithDisablersTemplate %
                                      (name, len(specs), name, len(specs)))
                 disablers.append(disablersTemplate %
                                  (name, len(specs),
                                   toStringBool(condition.secureContext),
                                   condition.nonExposedGlobals,
-                                  condition.func,
-                                  condition.available,
-                                  condition.checkAnyPermissions,
-                                  condition.checkAllPermissions))
+                                  condition.func))
             else:
                 prefableSpecs.append(prefableWithoutDisablersTemplate %
                                      (name, len(specs)))
 
         switchToCondition(self, lastCondition)
 
         for member in array:
             curCondition = getCondition(member, self.descriptor)
@@ -3329,25 +3289,16 @@ class CGConstructorEnabled(CGAbstractMet
                 """, workerCondition=workerCondition.define())
             exposedInWorkerCheck = CGGeneric(exposedInWorkerCheck)
             if iface.isExposedOnMainThread():
                 exposedInWorkerCheck = CGIfWrapper(exposedInWorkerCheck,
                                                    "!NS_IsMainThread()")
             body.append(exposedInWorkerCheck)
 
         conditions = getConditionList(iface, "aCx", "aObj")
-        availableIn = getAvailableInTestFunc(iface)
-        if availableIn:
-            conditions.append(CGGeneric("%s(aCx, aObj)" % availableIn))
-        checkAnyPermissions = self.descriptor.checkAnyPermissionsIndex
-        if checkAnyPermissions is not None:
-            conditions.append(CGGeneric("CheckAnyPermissions(aCx, aObj, anypermissions_%i)" % checkAnyPermissions))
-        checkAllPermissions = self.descriptor.checkAllPermissionsIndex
-        if checkAllPermissions is not None:
-            conditions.append(CGGeneric("CheckAllPermissions(aCx, aObj, allpermissions_%i)" % checkAllPermissions))
 
         # We should really have some conditions
         assert len(body) or len(conditions)
 
         conditionsWrapper = ""
         if len(conditions):
             conditionsWrapper = CGWrapper(conditions,
                                           pre="return ",
@@ -12008,27 +11959,16 @@ class CGDescriptor(CGThing):
 
             # Always have a finalize hook, regardless of whether the class
             # wants a custom hook.
             cgThings.append(CGClassFinalizeHook(descriptor))
 
         if descriptor.concrete and descriptor.wrapperCache:
             cgThings.append(CGClassObjectMovedHook(descriptor))
 
-        for name in ["anypermissions", "allpermissions"]:
-            permissions = getattr(descriptor, name)
-            if len(permissions):
-                for (k, v) in sorted(permissions.items()):
-                    perms = CGList((CGGeneric('"%s",' % p) for p in k), joiner="\n")
-                    perms.append(CGGeneric("nullptr"))
-                    cgThings.append(CGWrapper(CGIndenter(perms),
-                                              pre="static const char* const %s_%i[] = {\n" % (name, v),
-                                              post="\n};\n",
-                                              defineOnly=True))
-
         # Generate the _ClearCachedFooValue methods before the property arrays that use them.
         if descriptor.interface.isJSImplemented():
             for m in clearableCachedAttrs(descriptor):
                 cgThings.append(CGJSImplClearCachedValueMethod(descriptor, m))
 
         properties = PropertyArrays(descriptor)
         cgThings.append(CGGeneric(define=str(properties)))
         cgThings.append(CGNativeProperties(descriptor, properties))
@@ -16404,50 +16344,16 @@ class GlobalGenRoots():
         curr = CGHeaders([], [], [], [], headers, [], 'UnionConversions', curr)
 
         # Add include guards.
         curr = CGIncludeGuard('UnionConversions', curr)
 
         # Done.
         return curr
 
-    @staticmethod
-    def FeatureList(config):
-        things = set()
-        for d in config.getDescriptors():
-            if not d.interface.isExternal() and d.featureDetectibleThings is not None:
-                things.update(d.featureDetectibleThings)
-        things = CGList((CGGeneric(declare='"%s",' % t) for t in sorted(things)), joiner="\n")
-        things.append(CGGeneric(declare="nullptr"))
-        things = CGWrapper(CGIndenter(things),
-                           pre="static const char* const FeatureList[] = {\n",
-                           post="\n};\n")
-
-        helper_pre = "bool IsFeatureDetectible(const nsAString& aFeature) {\n"
-        helper = CGWrapper(CGIndenter(things),
-                           pre=helper_pre,
-                           post=dedent("""
-              const char* const* feature = FeatureList;
-              while (*feature) {
-                if (aFeature.EqualsASCII(*feature)) {
-                  return true;
-                }
-                ++feature;
-              }
-
-              return false;
-            }
-        """))
-
-        curr = CGNamespace.build(['mozilla', 'dom'], helper)
-        curr = CGHeaders([], [], [], [], ["nsString.h"], [], 'FeatureList', curr)
-        curr = CGIncludeGuard('FeatureList', curr)
-
-        return curr
-
 
 # Code generator for simple events
 class CGEventGetter(CGNativeMember):
     def __init__(self, descriptor, attr):
         ea = descriptor.getExtendedAttributes(attr, getter=True)
         CGNativeMember.__init__(self, descriptor, attr,
                                 CGSpecializedGetter.makeNativeName(descriptor,
                                                                    attr),
--- a/dom/bindings/Configuration.py
+++ b/dom/bindings/Configuration.py
@@ -503,74 +503,21 @@ class Descriptor(DescriptorProvider):
                     # the value, and ConstructNavigatorObject needs a JSContext.
                     self.extendedAttributes['all'].setdefault(m.identifier.name, []).append('implicitJSContext')
 
         self._binaryNames = desc.get('binaryNames', {})
         self._binaryNames.setdefault('__legacycaller', 'LegacyCall')
         self._binaryNames.setdefault('__stringifier', 'Stringify')
 
         if not self.interface.isExternal():
-            self.anypermissions = dict()
-            self.allpermissions = dict()
-
-            # Adds a permission list to this descriptor and returns the index to use.
-            def addPermissions(ifaceOrMember, attribute):
-                if attribute == "CheckAllPermissions":
-                    permissions = self.allpermissions
-                else:
-                    permissions = self.anypermissions
-
-                checkPermissions = ifaceOrMember.getExtendedAttribute(attribute)
-                if checkPermissions is None:
-                    return None
-
-                # It's a list of whitespace-separated strings
-                assert(len(checkPermissions) is 1)
-                assert(checkPermissions[0] is not None)
-                checkPermissions = checkPermissions[0]
-                permissionsList = checkPermissions.split()
-                if len(permissionsList) == 0:
-                    raise TypeError("Need at least one permission name for %s" % attribute)
-
-                permissionsList = tuple(sorted(set(permissionsList)))
-                return permissions.setdefault(permissionsList, len(permissions))
-
-            self.checkAnyPermissionsIndex = addPermissions(self.interface, "CheckAnyPermissions")
-            self.checkAnyPermissionsIndicesForMembers = dict()
-            self.checkAllPermissionsIndex = addPermissions(self.interface, "CheckAllPermissions")
-            self.checkAllPermissionsIndicesForMembers = dict()
-            for m in self.interface.members:
-                permissionsIndex = addPermissions(m, "CheckAnyPermissions")
-                if permissionsIndex is not None:
-                    self.checkAnyPermissionsIndicesForMembers[m.identifier.name] = permissionsIndex
-                allpermissionsIndex = addPermissions(m, "CheckAllPermissions")
-                if allpermissionsIndex is not None:
-                    self.checkAllPermissionsIndicesForMembers[m.identifier.name] = allpermissionsIndex
-
             def isTestInterface(iface):
                 return (iface.identifier.name in ["TestInterface",
                                                   "TestJSImplInterface",
                                                   "TestRenamedInterface"])
 
-            self.featureDetectibleThings = set()
-            if not isTestInterface(self.interface):
-                if (self.interface.getExtendedAttribute("CheckAnyPermissions") or
-                    self.interface.getExtendedAttribute("CheckAllPermissions") or
-                    self.interface.getExtendedAttribute("AvailableIn") == "PrivilegedApps"):
-                    iface = self.interface.identifier.name
-                    self.featureDetectibleThings.add(iface)
-                    for m in self.interface.members:
-                        self.featureDetectibleThings.add("%s.%s" % (iface, m.identifier.name))
-
-                for m in self.interface.members:
-                    if (m.getExtendedAttribute("CheckAnyPermissions") or
-                        m.getExtendedAttribute("CheckAllPermissions") or
-                        m.getExtendedAttribute("AvailableIn") == "PrivilegedApps"):
-                        self.featureDetectibleThings.add("%s.%s" % (self.interface.identifier.name, m.identifier.name))
-
             for member in self.interface.members:
                 if not member.isAttr() and not member.isMethod():
                     continue
                 binaryName = member.getExtendedAttribute("BinaryName")
                 if binaryName:
                     assert isinstance(binaryName, list)
                     assert len(binaryName) == 1
                     self._binaryNames.setdefault(member.identifier.name,
--- a/dom/bindings/DOMJSClass.h
+++ b/dom/bindings/DOMJSClass.h
@@ -69,28 +69,16 @@ typedef bool
                        JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
                        JS::MutableHandle<JS::PropertyDescriptor> desc);
 
 typedef bool
 (* EnumerateOwnProperties)(JSContext* cx, JS::Handle<JSObject*> wrapper,
                            JS::Handle<JSObject*> obj,
                            JS::AutoIdVector& props);
 
-// Returns true if aObj's global has any of the permissions named in
-// aPermissions set to nsIPermissionManager::ALLOW_ACTION. aPermissions must be
-// null-terminated.
-bool
-CheckAnyPermissions(JSContext* aCx, JSObject* aObj, const char* const aPermissions[]);
-
-// Returns true if aObj's global has all of the permissions named in
-// aPermissions set to nsIPermissionManager::ALLOW_ACTION. aPermissions must be
-// null-terminated.
-bool
-CheckAllPermissions(JSContext* aCx, JSObject* aObj, const char* const aPermissions[]);
-
 // Returns true if the given global is of a type whose bit is set in
 // aNonExposedGlobals.
 bool
 IsNonExposedGlobal(JSContext* aCx, JSObject* aGlobal,
                    uint32_t aNonExposedGlobals);
 
 struct ConstantSpec
 {
@@ -133,55 +121,33 @@ struct PrefableDisablers {
     }
     if (secureContext && !IsSecureContextOrObjectIsFromSecureContext(cx, obj)) {
       return false;
     }
     if (enabledFunc &&
         !enabledFunc(cx, js::GetGlobalForObjectCrossCompartment(obj))) {
       return false;
     }
-    if (availableFunc &&
-        !availableFunc(cx, js::GetGlobalForObjectCrossCompartment(obj))) {
-      return false;
-    }
-    if (checkAnyPermissions &&
-        !CheckAnyPermissions(cx, js::GetGlobalForObjectCrossCompartment(obj),
-                             checkAnyPermissions)) {
-      return false;
-    }
-    if (checkAllPermissions &&
-        !CheckAllPermissions(cx, js::GetGlobalForObjectCrossCompartment(obj),
-                             checkAllPermissions)) {
-      return false;
-    }
     return true;
   }
 
   // A boolean indicating whether this set of specs is enabled. Not const
   // because it will change at runtime if the corresponding pref is changed.
   bool enabled;
 
   // A boolean indicating whether a Secure Context is required.
   const bool secureContext;
 
   // Bitmask of global names that we should not be exposed in.
   const uint16_t nonExposedGlobals;
 
   // A function pointer to a function that can say the property is disabled
   // even if "enabled" is set to true.  If the pointer is null the value of
-  // "enabled" is used as-is unless availableFunc overrides.
+  // "enabled" is used as-is.
   const PropertyEnabled enabledFunc;
-
-  // A function pointer to a function that can be used to disable a
-  // property even if "enabled" is true and enabledFunc allowed.  This
-  // is basically a hack to avoid having to codegen PropertyEnabled
-  // implementations in case when we need to do two separate checks.
-  const PropertyEnabled availableFunc;
-  const char* const* const checkAnyPermissions;
-  const char* const* const checkAllPermissions;
 };
 
 template<typename T>
 struct Prefable {
   inline bool isEnabled(JSContext* cx, JS::Handle<JSObject*> obj) const {
     if (MOZ_LIKELY(!disablers)) {
       return true;
     }
--- a/dom/bindings/mozwebidlcodegen/__init__.py
+++ b/dom/bindings/mozwebidlcodegen/__init__.py
@@ -122,17 +122,16 @@ class WebIDLCodegenManager(LoggingMixin)
     """Manages all code generation around WebIDL.
 
     To facilitate testing, this object is meant to be generic and reusable.
     Paths, etc should be parameters and not hardcoded.
     """
 
     # Global parser derived declaration files.
     GLOBAL_DECLARE_FILES = {
-        'FeatureList.h',
         'GeneratedAtomList.h',
         'GeneratedEventList.h',
         'PrototypeList.h',
         'RegisterBindings.h',
         'RegisterWorkerBindings.h',
         'RegisterWorkerDebuggerBindings.h',
         'ResolveSystemBinding.h',
         'UnionConversions.h',
--- a/dom/bindings/parser/WebIDL.py
+++ b/dom/bindings/parser/WebIDL.py
@@ -1256,20 +1256,17 @@ class IDLInterfaceOrNamespace(IDLObjectW
                     if self.isOnGlobalProtoChain():
                         raise WebIDLError("[Alias] must not be used on a "
                                           "[Global] interface operation",
                                           [member.location])
                     if (member.getExtendedAttribute("Exposed") or
                         member.getExtendedAttribute("ChromeOnly") or
                         member.getExtendedAttribute("Pref") or
                         member.getExtendedAttribute("Func") or
-                        member.getExtendedAttribute("SecureContext") or
-                        member.getExtendedAttribute("AvailableIn") or
-                        member.getExtendedAttribute("CheckAnyPermissions") or
-                        member.getExtendedAttribute("CheckAllPermissions")):
+                        member.getExtendedAttribute("SecureContext")):
                         raise WebIDLError("[Alias] must not be used on a "
                                           "conditionally exposed operation",
                                           [member.location])
                     if member.isStatic():
                         raise WebIDLError("[Alias] must not be used on a "
                                           "static operation",
                                           [member.location])
                     if member.isIdentifierLess():
@@ -1291,24 +1288,16 @@ class IDLInterfaceOrNamespace(IDLObjectW
                                               [member.location, m.location])
 
         if (self.getExtendedAttribute("Pref") and
             self._exposureGlobalNames != set([self.parentScope.primaryGlobalName])):
             raise WebIDLError("[Pref] used on an interface that is not %s-only" %
                               self.parentScope.primaryGlobalName,
                               [self.location])
 
-        for attribute in ["CheckAnyPermissions", "CheckAllPermissions"]:
-            if (self.getExtendedAttribute(attribute) and
-                self._exposureGlobalNames != set([self.parentScope.primaryGlobalName])):
-                raise WebIDLError("[%s] used on an interface that is "
-                                  "not %s-only" %
-                                  (attribute, self.parentScope.primaryGlobalName),
-                                  [self.location])
-
         # Conditional exposure makes no sense for interfaces with no
         # interface object, unless they're navigator properties.
         if (self.isExposedConditionally() and
             not self.hasInterfaceObject() and
             not self.isNavigatorProperty()):
             raise WebIDLError("Interface with no interface object is "
                               "exposed conditionally",
                               [self.location])
@@ -1715,20 +1704,17 @@ class IDLInterface(IDLInterfaceOrNamespa
                                       [attr.location])
             elif identifier == "Exposed":
                 convertExposedAttrToGlobalNameSet(attr,
                                                   self._exposureGlobalNames)
             elif (identifier == "Pref" or
                   identifier == "JSImplementation" or
                   identifier == "HeaderFile" or
                   identifier == "NavigatorProperty" or
-                  identifier == "AvailableIn" or
                   identifier == "Func" or
-                  identifier == "CheckAnyPermissions" or
-                  identifier == "CheckAllPermissions" or
                   identifier == "Deprecated"):
                 # Known extended attributes that take a string value
                 if not attr.hasValue():
                     raise WebIDLError("[%s] must have a value" % identifier,
                                       [attr.location])
             else:
                 raise WebIDLError("Unknown extended attribute %s on interface" % identifier,
                                   [attr.location])
@@ -3545,24 +3531,16 @@ class IDLInterfaceMember(IDLObjectWithId
 
     def validate(self):
         if (self.getExtendedAttribute("Pref") and
             self.exposureSet != set([self._globalScope.primaryGlobalName])):
             raise WebIDLError("[Pref] used on an interface member that is not "
                               "%s-only" % self._globalScope.primaryGlobalName,
                               [self.location])
 
-        for attribute in ["CheckAnyPermissions", "CheckAllPermissions"]:
-            if (self.getExtendedAttribute(attribute) and
-                self.exposureSet != set([self._globalScope.primaryGlobalName])):
-                raise WebIDLError("[%s] used on an interface member that is "
-                                  "not %s-only" %
-                                  (attribute, self.parentScope.primaryGlobalName),
-                                  [self.location])
-
         if self.isAttr() or self.isMethod():
             if self.affects == "Everything" and self.dependsOn != "Everything":
                 raise WebIDLError("Interface member is flagged as affecting "
                                   "everything but not depending on everything. "
                                   "That seems rather unlikely.",
                                   [self.location])
 
         if self.getExtendedAttribute("NewObject"):
@@ -3969,20 +3947,17 @@ class IDLConst(IDLInterfaceMember):
 
     def handleExtendedAttribute(self, attr):
         identifier = attr.identifier()
         if identifier == "Exposed":
             convertExposedAttrToGlobalNameSet(attr, self._exposureGlobalNames)
         elif (identifier == "Pref" or
               identifier == "ChromeOnly" or
               identifier == "Func" or
-              identifier == "SecureContext" or
-              identifier == "AvailableIn" or
-              identifier == "CheckAnyPermissions" or
-              identifier == "CheckAllPermissions"):
+              identifier == "SecureContext"):
             # Known attributes that we don't need to do anything with here
             pass
         else:
             raise WebIDLError("Unknown extended attribute %s on constant" % identifier,
                               [attr.location])
         IDLInterfaceMember.handleExtendedAttribute(self, attr)
 
     def _getDependentObjects(self):
@@ -4312,21 +4287,18 @@ class IDLAttribute(IDLInterfaceMember):
               identifier == "Deprecated" or
               identifier == "SetterThrows" or
               identifier == "Throws" or
               identifier == "GetterThrows" or
               identifier == "ChromeOnly" or
               identifier == "Func" or
               identifier == "SecureContext" or
               identifier == "Frozen" or
-              identifier == "AvailableIn" or
               identifier == "NewObject" or
               identifier == "UnsafeInPrerendering" or
-              identifier == "CheckAnyPermissions" or
-              identifier == "CheckAllPermissions" or
               identifier == "BinaryName"):
             # Known attributes that we don't need to do anything with here
             pass
         else:
             raise WebIDLError("Unknown extended attribute %s on attribute" % identifier,
                               [attr.location])
         IDLInterfaceMember.handleExtendedAttribute(self, attr)
 
@@ -5038,19 +5010,16 @@ class IDLMethod(IDLInterfaceMember, IDLS
         elif (identifier == "Throws" or
               identifier == "NewObject" or
               identifier == "ChromeOnly" or
               identifier == "UnsafeInPrerendering" or
               identifier == "Pref" or
               identifier == "Deprecated" or
               identifier == "Func" or
               identifier == "SecureContext" or
-              identifier == "AvailableIn" or
-              identifier == "CheckAnyPermissions" or
-              identifier == "CheckAllPermissions" or
               identifier == "BinaryName" or
               identifier == "StaticClassOverride"):
             # Known attributes that we don't need to do anything with here
             pass
         else:
             raise WebIDLError("Unknown extended attribute %s on method" % identifier,
                               [attr.location])
         IDLInterfaceMember.handleExtendedAttribute(self, attr)
--- a/dom/bindings/test/TestCodeGen.webidl
+++ b/dom/bindings/test/TestCodeGen.webidl
@@ -6,17 +6,17 @@
 
 typedef long myLong;
 typedef TestInterface AnotherNameForTestInterface;
 typedef TestInterface? NullableTestInterface;
 typedef CustomEventInit TestDictionaryTypedef;
 
 interface TestExternalInterface;
 
-[AvailableIn=PrivilegedApps, Pref="xyz"]
+[Pref="xyz"]
 interface TestRenamedInterface {
 };
 
 callback interface TestCallbackInterface {
   readonly attribute long foo;
   attribute DOMString bar;
   void doSomething();
   long doSomethingElse(DOMString arg, TestInterface otherArg);
@@ -130,17 +130,16 @@ interface OnlyForUseInConstructor {
  Constructor(DOMString str),
  Constructor(unsigned long num, boolean? boolArg),
  Constructor(TestInterface? iface),
  Constructor(long arg1, IndirectlyImplementedInterface iface),
  Constructor(Date arg1),
  Constructor(ArrayBuffer arrayBuf),
  Constructor(Uint8Array typedArr),
  // Constructor(long arg1, long arg2, (TestInterface or OnlyForUseInConstructor) arg3),
- AvailableIn=CertifiedApps,
  NamedConstructor=Test,
  NamedConstructor=Test(DOMString str),
  NamedConstructor=Test2(DictForConstructor dict, any any1, object obj1,
                         object? obj2, sequence<Dict> seq, optional any any2,
                         optional object obj3, optional object? obj4),
  NamedConstructor=Test3((long or MozMap<any>) arg1)
  ]
 interface TestInterface {
@@ -882,24 +881,16 @@ interface TestInterface {
   [Pref="abc.def", Func="TestFuncControlledMember"]
   void prefable17();
   [Func="TestFuncControlledMember"]
   void prefable18();
   [Func="TestFuncControlledMember"]
   void prefable19();
   [Pref="abc.def", Func="TestFuncControlledMember", ChromeOnly]
   void prefable20();
-  [Func="TestFuncControlledMember", AvailableIn=CertifiedApps]
-  void prefable21();
-  [Func="TestFuncControlledMember", AvailableIn=CertifiedApps]
-  void prefable22();
-  [Pref="abc.def", Func="TestFuncControlledMember", AvailableIn=CertifiedApps]
-  void prefable23();
-  [Pref="abc.def", Func="TestFuncControlledMember", AvailableIn=PrivilegedApps]
-  void prefable24();
 
   // Conditionally exposed methods/attributes involving [SecureContext]
   [SecureContext]
   readonly attribute boolean conditionalOnSecureContext1;
   [SecureContext, Pref="abc.def"]
   readonly attribute boolean conditionalOnSecureContext2;
   [SecureContext, Pref="abc.def", Func="nsGenericHTMLElement::TouchEventsEnabled"]
   readonly attribute boolean conditionalOnSecureContext3;
--- a/dom/bindings/test/TestJSImplGen.webidl
+++ b/dom/bindings/test/TestJSImplGen.webidl
@@ -728,24 +728,16 @@ interface TestJSImplInterface {
   [Pref="abc.def", Func="TestFuncControlledMember"]
   void prefable17();
   [Func="TestFuncControlledMember"]
   void prefable18();
   [Func="TestFuncControlledMember"]
   void prefable19();
   [Pref="abc.def", Func="TestFuncControlledMember", ChromeOnly]
   void prefable20();
-  [Func="TestFuncControlledMember", AvailableIn=CertifiedApps]
-  void prefable21();
-  [Func="TestFuncControlledMember", AvailableIn=CertifiedApps]
-  void prefable22();
-  [Pref="abc.def", Func="TestFuncControlledMember", AvailableIn=CertifiedApps]
-  void prefable23();
-  [Pref="abc.def", Func="TestFuncControlledMember", AvailableIn=PrivilegedApps]
-  void prefable24();
 
   // Conditionally exposed methods/attributes involving [SecureContext]
   [SecureContext]
   readonly attribute boolean conditionalOnSecureContext1;
   [SecureContext, Pref="abc.def"]
   readonly attribute boolean conditionalOnSecureContext2;
   [SecureContext, Pref="abc.def", Func="nsGenericHTMLElement::TouchEventsEnabled"]
   readonly attribute boolean conditionalOnSecureContext3;
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -1872,18 +1872,16 @@ WorkerLoadInfo::WorkerLoadInfo()
   : mWindowID(UINT64_MAX)
   , mServiceWorkerID(0)
   , mReferrerPolicy(net::RP_Default)
   , mFromWindow(false)
   , mEvalAllowed(false)
   , mReportCSPViolations(false)
   , mXHRParamsAllowed(false)
   , mPrincipalIsSystem(false)
-  , mIsInPrivilegedApp(false)
-  , mIsInCertifiedApp(false)
   , mStorageAllowed(false)
   , mPrivateBrowsing(true)
   , mServiceWorkersTestingInWindow(false)
 {
   MOZ_COUNT_CTOR(WorkerLoadInfo);
 }
 
 WorkerLoadInfo::~WorkerLoadInfo()
@@ -1932,18 +1930,16 @@ WorkerLoadInfo::StealFrom(WorkerLoadInfo
   mWindowID = aOther.mWindowID;
   mServiceWorkerID = aOther.mServiceWorkerID;
   mReferrerPolicy = aOther.mReferrerPolicy;
   mFromWindow = aOther.mFromWindow;
   mEvalAllowed = aOther.mEvalAllowed;
   mReportCSPViolations = aOther.mReportCSPViolations;
   mXHRParamsAllowed = aOther.mXHRParamsAllowed;
   mPrincipalIsSystem = aOther.mPrincipalIsSystem;
-  mIsInPrivilegedApp = aOther.mIsInPrivilegedApp;
-  mIsInCertifiedApp = aOther.mIsInCertifiedApp;
   mStorageAllowed = aOther.mStorageAllowed;
   mPrivateBrowsing = aOther.mPrivateBrowsing;
   mServiceWorkersTestingInWindow = aOther.mServiceWorkersTestingInWindow;
 }
 
 template <class Derived>
 class WorkerPrivateParent<Derived>::EventTarget final
   : public nsIEventTarget
@@ -3551,21 +3547,16 @@ WorkerPrivateParent<Derived>::SetPrincip
                                            nsILoadGroup* aLoadGroup)
 {
   AssertIsOnMainThread();
   MOZ_ASSERT(NS_LoadGroupMatchesPrincipal(aLoadGroup, aPrincipal));
   MOZ_ASSERT(!mLoadInfo.mPrincipalInfo);
 
   mLoadInfo.mPrincipal = aPrincipal;
   mLoadInfo.mPrincipalIsSystem = nsContentUtils::IsSystemPrincipal(aPrincipal);
-  uint16_t appStatus = aPrincipal->GetAppStatus();
-  mLoadInfo.mIsInPrivilegedApp =
-    (appStatus == nsIPrincipal::APP_STATUS_CERTIFIED ||
-     appStatus == nsIPrincipal::APP_STATUS_PRIVILEGED);
-  mLoadInfo.mIsInCertifiedApp = (appStatus == nsIPrincipal::APP_STATUS_CERTIFIED);
 
   aPrincipal->GetCsp(getter_AddRefs(mLoadInfo.mCSP));
 
   if (mLoadInfo.mCSP) {
     mLoadInfo.mCSP->GetAllowsEval(&mLoadInfo.mReportCSPViolations,
                                   &mLoadInfo.mEvalAllowed);
     // Set ReferrerPolicy
     bool hasReferrerPolicy = false;
@@ -4388,21 +4379,16 @@ WorkerPrivate::GetLoadInfo(JSContext* aC
 
       uint32_t perm;
       rv = permMgr->TestPermissionFromPrincipal(loadInfo.mPrincipal, "systemXHR",
                                                 &perm);
       NS_ENSURE_SUCCESS(rv, rv);
 
       loadInfo.mXHRParamsAllowed = perm == nsIPermissionManager::ALLOW_ACTION;
 
-      uint16_t appStatus = loadInfo.mPrincipal->GetAppStatus();
-      loadInfo.mIsInPrivilegedApp =
-        (appStatus == nsIPrincipal::APP_STATUS_CERTIFIED ||
-         appStatus == nsIPrincipal::APP_STATUS_PRIVILEGED);
-      loadInfo.mIsInCertifiedApp = (appStatus == nsIPrincipal::APP_STATUS_CERTIFIED);
       loadInfo.mFromWindow = true;
       loadInfo.mWindowID = globalWindow->WindowID();
       nsContentUtils::StorageAccess access =
         nsContentUtils::StorageAllowedForWindow(globalWindow);
       loadInfo.mStorageAllowed = access > nsContentUtils::StorageAccess::eDeny;
       loadInfo.mPrivateBrowsing = nsContentUtils::IsInPrivateBrowsing(document);
     } else {
       // Not a window
--- a/dom/workers/WorkerPrivate.h
+++ b/dom/workers/WorkerPrivate.h
@@ -598,28 +598,16 @@ public:
   SetPrincipal(nsIPrincipal* aPrincipal, nsILoadGroup* aLoadGroup);
 
   bool
   UsesSystemPrincipal() const
   {
     return mLoadInfo.mPrincipalIsSystem;
   }
 
-  bool
-  IsInPrivilegedApp() const
-  {
-    return mLoadInfo.mIsInPrivilegedApp;
-  }
-
-  bool
-  IsInCertifiedApp() const
-  {
-    return mLoadInfo.mIsInCertifiedApp;
-  }
-
   const PrincipalInfo&
   GetPrincipalInfo() const
   {
     return *mLoadInfo.mPrincipalInfo;
   }
 
   already_AddRefed<nsIChannel>
   ForgetWorkerChannel()
--- a/dom/workers/WorkerScope.cpp
+++ b/dom/workers/WorkerScope.cpp
@@ -465,32 +465,29 @@ DedicatedWorkerGlobalScope::WrapGlobalOb
   JS::CompartmentOptions options;
   mWorkerPrivate->CopyJSCompartmentOptions(options);
 
   const bool usesSystemPrincipal = mWorkerPrivate->UsesSystemPrincipal();
 
   // Note that xpc::ShouldDiscardSystemSource() and
   // xpc::ExtraWarningsForSystemJS() read prefs that are cached on the main
   // thread. This is benignly racey.
-  const bool discardSource = (usesSystemPrincipal ||
-                              mWorkerPrivate->IsInPrivilegedApp()) &&
+  const bool discardSource = usesSystemPrincipal &&
                              xpc::ShouldDiscardSystemSource();
   const bool extraWarnings = usesSystemPrincipal &&
                              xpc::ExtraWarningsForSystemJS();
 
   JS::CompartmentBehaviors& behaviors = options.behaviors();
   behaviors.setDiscardSource(discardSource)
            .extraWarningsOverride().set(extraWarnings);
 
-  const bool inCertifiedApp = mWorkerPrivate->IsInCertifiedApp();
   const bool sharedMemoryEnabled = xpc::SharedMemoryEnabled();
 
   JS::CompartmentCreationOptions& creationOptions = options.creationOptions();
-  creationOptions.setSharedMemoryAndAtomicsEnabled(sharedMemoryEnabled)
-                 .setExperimentalDateTimeFormatFormatToPartsEnabled(inCertifiedApp);
+  creationOptions.setSharedMemoryAndAtomicsEnabled(sharedMemoryEnabled);
 
   return DedicatedWorkerGlobalScopeBinding::Wrap(aCx, this, this,
                                                  options,
                                                  GetWorkerPrincipal(),
                                                  true, aReflector);
 }
 
 void
--- a/dom/workers/Workers.h
+++ b/dom/workers/Workers.h
@@ -263,18 +263,16 @@ struct WorkerLoadInfo
   uint64_t mServiceWorkerID;
 
   net::ReferrerPolicy mReferrerPolicy;
   bool mFromWindow;
   bool mEvalAllowed;
   bool mReportCSPViolations;
   bool mXHRParamsAllowed;
   bool mPrincipalIsSystem;
-  bool mIsInPrivilegedApp;
-  bool mIsInCertifiedApp;
   bool mStorageAllowed;
   bool mPrivateBrowsing;
   bool mServiceWorkersTestingInWindow;
 
   WorkerLoadInfo();
   ~WorkerLoadInfo();
 
   void StealFrom(WorkerLoadInfo& aOther);