def layer_changed(self, layer):
        """Handler for when the QGIS active layer is changed.

        If the active layer is changed and it has keywords and a report,
        show the report.

        :param layer: QgsMapLayer instance that is now active.
        :type layer: QgsMapLayer, QgsRasterLayer, QgsVectorLayer
        """
        # Don't handle this event if we are already handling another layer
        # addition or removal event.
        if self.get_layers_lock or layer is None:
            return

        # Do nothing if there is no active layer - see #1861
        if not self._has_active_layer():
            if self.conflicting_plugin_detected:
                send_static_message(self, conflicting_plugin_message())
            else:
                send_static_message(self, getting_started_message())

        # Now try to read the keywords and show them in the dock
        try:
            keywords = self.keyword_io.read_keywords(layer)

            # list of layer purpose to show impact report
            impacted_layer = [
                layer_purpose_exposure_summary['key'],
                layer_purpose_aggregate_hazard_impacted['key'],
                layer_purpose_aggregation_summary['key'],
                layer_purpose_analysis_impacted['key'],
                layer_purpose_exposure_summary_table['key'],
                layer_purpose_profiling['key'],
                # Legacy from InaSAFE < 4.2. We still want to open old
                # analysis made with 4.0 an 4.1.
                # We should remove them later.
                'exposure_summary',
                'aggregate_hazard_impacted',
                'aggregation_summary',
                'analysis_impacted'
            ]

            provenances = keywords.get('provenance_data', {})
            extra_keywords = keywords.get('extra_keywords', {})
            is_multi_exposure = (
                extra_keywords.get(extra_keyword_analysis_type['key']) == (
                    MULTI_EXPOSURE_ANALYSIS_FLAG))

            if provenances:
                set_provenance_to_project_variables(provenances)
            try:
                if is_multi_exposure:
                    self.impact_function = (
                        MultiExposureImpactFunction.load_from_output_metadata(
                            keywords))
                elif provenances:
                    self.impact_function = (
                        ImpactFunction.load_from_output_metadata(
                            keywords))
            except InvalidLayerError as e:
                display_critical_message_bar(
                    tr("Invalid Layer"), str(e), iface_object=self.iface)
                self.impact_function = None

            show_keywords = True
            if keywords.get('layer_purpose') in impacted_layer:
                analysis_dir = os.path.dirname(layer.source())
                output_dir_path = os.path.join(analysis_dir, 'output')

                html_report_products = [
                    'impact-report-output.html',
                    'multi-exposure-impact-report-output.html']

                for html_report_product in html_report_products:
                    table_report_path = os.path.join(
                        output_dir_path, html_report_product)
                    if os.path.exists(table_report_path):
                        show_keywords = False
                        self.show_impact(table_report_path)
                        break

            if show_keywords:
                if inasafe_keyword_version_key not in list(keywords.keys()):
                    show_keyword_version_message(
                        self, tr('No Version'), self.inasafe_version)
                    self.print_button.setEnabled(False)
                else:
                    keyword_version = str(keywords.get(
                        inasafe_keyword_version_key))
                    supported = is_keyword_version_supported(
                        keyword_version)
                    if supported:
                        self.show_generic_keywords(layer)
                    else:
                        # Layer version is not supported
                        show_keyword_version_message(
                            self, keyword_version, self.inasafe_version)
                    self.print_button.setEnabled(False)

        # TODO: maybe we need to split these apart more to give mode
        # TODO: granular error messages TS
        except (KeywordNotFoundError,
                HashNotFoundError,
                InvalidParameterError,
                NoKeywordsFoundError,
                MetadataReadError,
                AttributeError) as e:
            # Added this check in 3.2 for #1861

            active_layer = self.iface.activeLayer()
            if active_layer is None:
                if self.conflicting_plugin_detected:
                    send_static_message(self, conflicting_plugin_message())
                else:
                    send_static_message(self, getting_started_message())
            else:
                LOGGER.debug(e)
                show_no_keywords_message(self)
                self.print_button.setEnabled(False)
        except Exception as e:  # pylint: disable=broad-except
            error_message = get_error_message(e)
            send_error_message(self, error_message)
Handler for when the QGIS active layer is changed.

        If the active layer is changed and it has keywords and a report,
        show the report.

        :param layer: QgsMapLayer instance that is now active.
        :type layer: QgsMapLayer, QgsRasterLayer, QgsVectorLayer