text:
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision: 322055 $ -->

<refentry xml:id="cairomatrix.initidentity" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
 <refnamediv>
  <refname>CairoMatrix::initIdentity</refname>
  <refname>cairo_matrix_init_identity</refname>
  <refpurpose>Creates a new identity matrix</refpurpose>
 </refnamediv>

 <refsect1 role="description">
  &reftitle.description;
  <para>&style.oop; (method):</para>
  <methodsynopsis>
   <modifier>public</modifier> <modifier>static</modifier> <type>void</type><methodname>CairoMatrix::initIdentity</methodname>
   <void />
  </methodsynopsis>
  <para>&style.procedural;:</para>
  <methodsynopsis>
   <type>object</type><methodname>cairo_matrix_init_identity</methodname>
   <void />
  </methodsynopsis>
  <para>
   Creates a new matrix that is an identity transformation. An identity
   transformation means the source data is copied into the destination data
   without change
  </para>

 </refsect1>

 <refsect1 role="parameters">
  &reftitle.parameters;
  &no.function.parameters;
 </refsect1>

 <refsect1 role="returnvalues">
  &reftitle.returnvalues;
  <para>
   Returns a new CairoMatrix object that can be used with surfaces, contexts, and patterns.
  </para>
 </refsect1>

 <refsect1 role="examples">
  &reftitle.examples;
  <para>
   <example>
    <title>&style.oop;</title>
    <programlisting role="php">
<![CDATA[
<?php
/* Create a new Matrix */
$matrix = CairoMatrix::initIdentity();
?>
]]>
    </programlisting>
   </example>
  </para>
  <para>
   <example>
    <title>&style.procedural;</title>
    <programlisting role="php">
<![CDATA[
<?php
/* Create a new Matrix */
$matrix = cairo_matrix_init_identity();
?>
]]>
     </programlisting>
   </example>
  </para>
 </refsect1>

 <refsect1 role="seealso">
  &reftitle.seealso;
  <para>
   <simplelist>
    <member><methodname>CairoMatrix::__construct</methodname></member>
    <member><methodname>CairoMatrix::initRotate</methodname></member>
    <member><methodname>CairoMatrix::initScale</methodname></member>
    <member><methodname>CairoMatrix::initTranslate</methodname></member>
   </simplelist>
  </para>
 </refsect1>

</refentry>

<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->


text:
using System;
using System.Collections;
using System.Html;
using System.Net;
using System.Runtime.CompilerServices;

namespace jQueryApi.Templating {

    /// <summary>
    /// Provides access to jQuery Templating APIs.
    /// </summary>
    [ScriptIgnoreNamespace]
    [ScriptImport]
    public static class jQueryTemplating {

        /// <summary>
        /// Creates a template based on the specified template markup.
        /// </summary>
        /// <param name="template">The template markup.</param>
        /// <returns>A compiled template.</returns>
        [ScriptAlias("$.template")]
        public static jQueryTemplate CreateTemplate(string template) {
            return null;
        }

        /// <summary>
        /// Creates a template based on the specified template markup.
        /// </summary>
        /// <param name="templateName">The name to assign to the template.</param>
        /// <param name="template">The template markup.</param>
        /// <returns>A compiled template.</returns>
        [ScriptAlias("$.template")]
        public static jQueryTemplate CreateTemplate(string templateName, string template) {
            return null;
        }

        /// <summary>
        /// Creates a template based on the content of the specified element.
        /// </summary>
        /// <param name="templateElement">The element containing the template markup.</param>
        /// <returns>A compiled template.</returns>
        [ScriptAlias("$.template")]
        public static jQueryTemplate CreateTemplate(Element templateElement) {
            return null;
        }

        /// <summary>
        /// Creates a template based on the content of the specified element.
        /// </summary>
        /// <param name="templateName">The name to assign to the template.</param>
        /// <param name="templateElement">The element containing the template markup.</param>
        /// <returns>A compiled template.</returns>
        [ScriptAlias("$.template")]
        public static jQueryTemplate CreateTemplate(string templateName, Element templateElement) {
            return null;
        }

        /// <summary>
        /// Creates a template based on the first element of the matched set.
        /// </summary>
        /// <param name="o">The jQueryObject representing the element whose content is to be used as a template.</param>
        /// <returns>A compiled template.</returns>
        [ScriptAlias("$.template")]
        public static jQueryTemplate CreateTemplate(jQueryObject o) {
            return null;
        }

        /// <summary>
        /// Creates a template based on the first element of the matched set.
        /// </summary>
        /// <param name="templateName">The name to assign to the template.</param>
        /// <param name="template">The jQueryObject representing the element whose content is to be used as a template.</param>
        /// <returns>A compiled template.</returns>
        [ScriptAlias("$.template")]
        public static jQueryTemplate CreateTemplate(string templateName, jQueryObject template) {
            return null;
        }

        /// <summary>
        /// Gets the template by name, previously created using CreateTemplate.
        /// </summary>
        /// <param name="templateName">The template name.</param>
        /// <returns>A compiled template.</returns>
        [ScriptAlias("$.template")]
        public static jQueryTemplate GetTemplate(string templateName) {
            return null;
        }

        /// <summary>
        /// Gets the template instance associated with the specified element.
        /// </summary>
        /// <param name="element">The element associated with a template.</param>
        /// <returns>The associated template instance if one exists.</returns>
        [ScriptAlias("$.tmplItem")]
        public static jQueryTemplateInstance GetTemplateInstance(Element element) {
            return null;
        }

        /// <summary>
        /// Gets the template instance associated with the specified jQueryObject.
        /// </summary>
        /// <param name="o">The jQueryObject associated with a template.</param>
        /// <returns>The associated template instance if one exists.</returns>
        [ScriptAlias("$.tmplItem")]
        public static jQueryTemplateInstance GetTemplateInstance(jQueryObject o) {
            return null;
        }

        /// <summary>
        /// Creates a template based on the first element of the matched set
        /// and instantiates it using the specified data.
        /// </summary>
        /// <param name="template">The name of a template or markup to use.</param>
        /// <param name="data">The data associated with the template instance.</param>
        /// <returns>The resulting elements from instantiating the template.</returns>
        [ScriptAlias("$.tmpl")]
        public static jQueryObject RenderTemplate(string template, object data) {
            return null;
        }

        /// <summary>
        /// Creates a template based on the first element of the matched set
        /// and instantiates it using the specified data.
        /// </summary>
        /// <param name="template">The name of a template or markup to use.</param>
        /// <param name="data">The data associated with the template instance.</param>
        /// <param name="item">An object for use inside the template as $item.</param>
        /// <returns>The resulting elements from instantiating the template.</returns>
        [ScriptAlias("$.tmpl")]
        public static jQueryObject RenderTemplate(string template, object data, object item) {
            return null;
        }

        /// <summary>
        /// Creates a template based on the first element of the matched set
        /// and instantiates it using the specified data.
        /// </summary>
        /// <param name="templateElement">The element whose content is to be used as a template.</param>
        /// <param name="data">The data associated with the template instance.</param>
        /// <returns>The resulting elements from instantiating the template.</returns>
        [ScriptAlias("$.tmpl")]
        public static jQueryObject RenderTemplate(Element templateElement, object data) {
            return null;
        }

        /// <summary>
        /// Creates a template based on the first element of the matched set
        /// and instantiates it using the specified data.
        /// </summary>
        /// <param name="templateElement">The element whose content is to be used as a template.</param>
        /// <param name="data">The data associated with the template instance.</param>
        /// <param name="item">An object for use inside the template as $item.</param>
        /// <returns>The resulting elements from instantiating the template.</returns>
        [ScriptAlias("$.tmpl")]
        public static jQueryObject RenderTemplate(Element templateElement, object data, object item) {
            return null;
        }

        /// <summary>
        /// Creates a template based on the first element of the matched set
        /// and instantiates it using the specified data.
        /// </summary>
        /// <param name="template">The jQueryObject representing the element whose content is to be used as a template.</param>
        /// <param name="data">The data associated with the template instance.</param>
        /// <returns>The resulting elements from instantiating the template.</returns>
        [ScriptAlias("$.tmpl")]
        public static jQueryObject RenderTemplate(jQueryObject template, object data) {
            return null;
        }

        /// <summary>
        /// Creates a template based on the first element of the matched set
        /// and instantiates it using the specified data.
        /// </summary>
        /// <param name="template">The jQueryObject representing the element whose content is to be used as a template.</param>
        /// <param name="data">The data associated with the template instance.</param>
        /// <param name="item">An object for use inside the template as $item.</param>
        /// <returns>The resulting elements from instantiating the template.</returns>
        [ScriptAlias("$.tmpl")]
        public static jQueryObject RenderTemplate(jQueryObject template, object data, object item) {
            return null;
        }

        /// <summary>
        /// Creates a template based on the first element of the matched set
        /// and instantiates it using the specified data.
        /// </summary>
        /// <param name="template">The template to use.</param>
        /// <param name="data">The data associated with the template instance.</param>
        /// <returns>The resulting elements from instantiating the template.</returns>
        [ScriptAlias("$.tmpl")]
        public static jQueryObject RenderTemplate(jQueryTemplate template, object data) {
            return null;
        }

        /// <summary>
        /// Creates a template based on the first element of the matched set
        /// and instantiates it using the specified data.
        /// </summary>
        /// <param name="template">The template to use.</param>
        /// <param name="data">The data associated with the template instance.</param>
        /// <param name="item">An object for use inside the template as $item.</param>
        /// <returns>The resulting elements from instantiating the template.</returns>
        [ScriptAlias("$.tmpl")]
        public static jQueryObject RenderTemplate(jQueryTemplate template, object data, object item) {
            return null;
        }
    }
}

redpajama_set_name: RedPajamaGithub


text:
<?php
class Kwc_Basic_ImageParent_Admin extends Kwc_Abstract_Admin
{
    public function gridColumns()
    {
        $ret = array();
        return $ret;
    }
}


text:
package org.sagebionetworks.repo.manager.audit;

import java.io.IOException;

import org.sagebionetworks.audit.dao.ObjectRecordBatch;

/**
 * Abstraction for an in-memory queue that gathers ObjectRecords from various
 * thread. The queue is emptied from a timer thread that sends the ObjectRecords
 * to S3 in batches.
 *
 * @author John
 *
 */
public interface ObjectRecordQueue {

	/**
	 * Push a new batch of ObjectRecords to the in-memory queue.
	 * The batch will be sent to S3 from a timer thread.
	 *
	 * @param batch
	 */
	public void pushObjectRecordBatch(ObjectRecordBatch batch);

	/**
	 * Get the number of batches in the Queue.
	 *
	 * @return
	 */
	public int getQueueSize();

	/**
	 * When the timer fires the queue will be emptied.
	 *
	 * @throws IOException
	 */
	void timerFired() throws IOException;
}


text:
<?php
// vim: expandtab:ts=4:sw=4

namespace Tranquillity\Middlewares\WebAdmin;

// logout a user
class MiddlewareRouteLogoutUser extends \Tranquillity\Middlewares\AbstractMiddleware
{
    protected $container;

    /**
     * Middleware invokable class
     *
     * @param  \Psr\Http\Message\ServerRequestInterface $request  PSR7 request
     * @param  \Psr\Http\Message\ResponseInterface      $response PSR7 response
     * @param  callable                                 $next     Next middleware
     *
     * @return \Psr\Http\Message\ResponseInterface
     */
    public function __invoke($request, $response, $next)
    {
        $this->container->ServiceLog->addDebug(__METHOD__);
        /*
        $sesseg = $this->container->ServiceAuraSession->getSegment('Login');
        $sesseg->set("test","test");
        */

        $username = "";
        try {
            $username = $this->container->ServiceUser->loggedinUsername();
            $this->container->ServiceUser->logoutUser($username);
            $this->container->ServiceLog->addInfo("User \"" . $username . "\" logged out");
            $this->container->ServiceUser->setFlash('success', array('User logged out. Thanks for coming.'));
            return $next($request, $response);
        } catch(\Exception $e) {
                $this->container->ServiceLog->addError("Problem logging out user $username" . $e->getMessage());
        }

        // something bad happened, cannot logout the user, redirect the user to login
        $this->container->ServiceUser->setFlash('error', array('Error during logout process, please retry after cleaning up your cookies'));
        $this->container->ServiceLog->addInfo("Cannot logout user, redirecting to login");
        return $response->withStatus(302)->withHeader('Location', $this->c->ServiceConfig->get('adminConsoleUri').'/login');
    }
}

?>


text:
.class public final Lcom/android/internal/app/RingtonePickerActivity;
.super Lcom/android/internal/app/AlertActivity;
.source "RingtonePickerActivity.java"

# interfaces
.implements Landroid/widget/AdapterView$OnItemSelectedListener;
.implements Ljava/lang/Runnable;
.implements Landroid/content/DialogInterface$OnClickListener;
.implements Lcom/android/internal/app/AlertController$AlertParams$OnPrepareListViewListener;

# static fields
.field private static final DELAY_MS_SELECTION_PLAYED:I = 0x12c

.field private static final SAVE_CLICKED_POS:Ljava/lang/String; = "clicked_pos"

.field private static final TAG:Ljava/lang/String; = "RingtonePickerActivity"

# instance fields
.field private mClickedPos:I

.field private mCursor:Landroid/database/Cursor;

.field private mDefaultRingtone:Landroid/media/Ringtone;

.field private mDefaultRingtonePos:I

.field private mExistingUri:Landroid/net/Uri;

.field private mHandler:Landroid/os/Handler;

.field private mHasDefaultItem:Z

.field private mHasSilentItem:Z

.field private mRingtoneClickListener:Landroid/content/DialogInterface$OnClickListener;

.field private mRingtoneManager:Landroid/media/RingtoneManager;

.field private mSampleRingtonePos:I

.field private mSilentPos:I

.field private mStaticItemCount:I

.field private mUriForDefaultItem:Landroid/net/Uri;

# direct methods
.method public constructor <init>()V
    .locals 1

    .prologue
    const/4 v0, -0x1

    .line 43
    invoke-direct {p0}, Lcom/android/internal/app/AlertActivity;-><init>()V

    .line 59
    iput v0, p0, Lcom/android/internal/app/RingtonePickerActivity;->mSilentPos:I

    .line 62
    iput v0, p0, Lcom/android/internal/app/RingtonePickerActivity;->mDefaultRingtonePos:I

    .line 65
    iput v0, p0, Lcom/android/internal/app/RingtonePickerActivity;->mClickedPos:I

    .line 68
    iput v0, p0, Lcom/android/internal/app/RingtonePickerActivity;->mSampleRingtonePos:I

    .line 92
    new-instance v0, Lcom/android/internal/app/RingtonePickerActivity$1;

    invoke-direct {v0, p0}, Lcom/android/internal/app/RingtonePickerActivity$1;-><init>(Lcom/android/internal/app/RingtonePickerActivity;)V

    iput-object v0, p0, Lcom/android/internal/app/RingtonePickerActivity;->mRingtoneClickListener:Landroid/content/DialogInterface$OnClickListener;

    return-void
.end method

.method static synthetic access$002(Lcom/android/internal/app/RingtonePickerActivity;I)I
    .locals 0
    .parameter "x0"
    .parameter "x1"

    .prologue
    .line 43
    iput p1, p0, Lcom/android/internal/app/RingtonePickerActivity;->mClickedPos:I

    return p1
.end method

.method static synthetic access$100(Lcom/android/internal/app/RingtonePickerActivity;II)V
    .locals 0
    .parameter "x0"
    .parameter "x1"
    .parameter "x2"

    .prologue
    .line 43
    invoke-direct {p0, p1, p2}, Lcom/android/internal/app/RingtonePickerActivity;->playRingtone(II)V

    return-void
.end method

.method static synthetic access$200(Lcom/android/internal/app/RingtonePickerActivity;)Landroid/database/Cursor;
    .locals 1
    .parameter "x0"

    .prologue
    .line 43
    iget-object v0, p0, Lcom/android/internal/app/RingtonePickerActivity;->mCursor:Landroid/database/Cursor;

    return-object v0
.end method

.method private addDefaultRingtoneItem(Landroid/widget/ListView;)I
    .locals 1
    .parameter "listView"

    .prologue
    .line 226
    const v0, 0x10403e8

    invoke-direct {p0, p1, v0}, Lcom/android/internal/app/RingtonePickerActivity;->addStaticItem(Landroid/widget/ListView;I)I

    move-result v0

    return v0
.end method

.method private addSilentItem(Landroid/widget/ListView;)I
    .locals 1
    .parameter "listView"

    .prologue
    .line 230
    const v0, 0x10403ea

    invoke-direct {p0, p1, v0}, Lcom/android/internal/app/RingtonePickerActivity;->addStaticItem(Landroid/widget/ListView;I)I

    move-result v0

    return v0
.end method

.method private addStaticItem(Landroid/widget/ListView;I)I
    .locals 4
    .parameter "listView"
    .parameter "textResId"

    .prologue
    .line 217
    invoke-virtual {p0}, Lcom/android/internal/app/RingtonePickerActivity;->getLayoutInflater()Landroid/view/LayoutInflater;

    move-result-object v1

    const v2, 0x1090093

    const/4 v3, 0x0

    invoke-virtual {v1, v2, p1, v3}, Landroid/view/LayoutInflater;->inflate(ILandroid/view/ViewGroup;Z)Landroid/view/View;

    move-result-object v0

    check-cast v0, Landroid/widget/TextView;

    .line 219
    .local v0, textView:Landroid/widget/TextView;
    invoke-virtual {v0, p2}, Landroid/widget/TextView;->setText(I)V

    .line 220
    invoke-virtual {p1, v0}, Landroid/widget/ListView;->addHeaderView(Landroid/view/View;)V

    .line 221
    iget v1, p0, Lcom/android/internal/app/RingtonePickerActivity;->mStaticItemCount:I

    add-int/lit8 v1, v1, 0x1

    iput v1, p0, Lcom/android/internal/app/RingtonePickerActivity;->mStaticItemCount:I

    .line 222
    invoke-virtual {p1}, Landroid/widget/ListView;->getHeaderViewsCount()I

    move-result v1

    add-int/lit8 v1, v1, -0x1

    return v1
.end method

.method private getListPosition(I)I
    .locals 1
    .parameter "ringtoneManagerPos"

    .prologue
    .line 357
    if-gez p1, :cond_0

    .line 359
    .end local p1
    :goto_0
    return p1

    .restart local p1
    :cond_0
    iget v0, p0, Lcom/android/internal/app/RingtonePickerActivity;->mStaticItemCount:I

    add-int/2addr p1, v0

    goto :goto_0
.end method

.method private getRingtoneManagerPosition(I)I
    .locals 1
    .parameter "listPos"

    .prologue
    .line 351
    iget v0, p0, Lcom/android/internal/app/RingtonePickerActivity;->mStaticItemCount:I

    sub-int v0, p1, v0

    return v0
.end method

.method private playRingtone(II)V
    .locals 3
    .parameter "position"
    .parameter "delayMs"

    .prologue
    .line 282
    iget-object v0, p0, Lcom/android/internal/app/RingtonePickerActivity;->mHandler:Landroid/os/Handler;

    invoke-virtual {v0, p0}, Landroid/os/Handler;->removeCallbacks(Ljava/lang/Runnable;)V

    .line 283
    iput p1, p0, Lcom/android/internal/app/RingtonePickerActivity;->mSampleRingtonePos:I

    .line 284
    iget-object v0, p0, Lcom/android/internal/app/RingtonePickerActivity;->mHandler:Landroid/os/Handler;

    int-to-long v1, p2

    invoke-virtual {v0, p0, v1, v2}, Landroid/os/Handler;->postDelayed(Ljava/lang/Runnable;J)Z

    .line 285
    return-void
.end method

.method private stopAnyPlayingRingtone()V
    .locals 1

    .prologue
    .line 341
    iget-object v0, p0, Lcom/android/internal/app/RingtonePickerActivity;->mDefaultRingtone:Landroid/media/Ringtone;

    if-eqz v0, :cond_0

    iget-object v0, p0, Lcom/android/internal/app/RingtonePickerActivity;->mDefaultRingtone:Landroid/media/Ringtone;

    invoke-virtual {v0}, Landroid/media/Ringtone;->isPlaying()Z

    move-result v0

    if-eqz v0, :cond_0

    .line 342
    iget-object v0, p0, Lcom/android/internal/app/RingtonePickerActivity;->mDefaultRingtone:Landroid/media/Ringtone;

    invoke-virtual {v0}, Landroid/media/Ringtone;->stop()V

    .line 345
    :cond_0
    iget-object v0, p0, Lcom/android/internal/app/RingtonePickerActivity;->mRingtoneManager:Landroid/media/RingtoneManager;

    if-eqz v0, :cond_1

    .line 346
    iget-object v0, p0, Lcom/android/internal/app/RingtonePickerActivity;->mRingtoneManager:Landroid/media/RingtoneManager;

    invoke-virtual {v0}, Landroid/media/RingtoneManager;->stopPreviousRingtone()V

    .line 348
    :cond_1
    return-void
.end method

# virtual methods
.method public onClick(Landroid/content/DialogInterface;I)V
    .locals 6
    .parameter "dialog"
    .parameter "which"

    .prologue
    const/4 v3, 0x0

    const/4 v5, -0x1

    .line 237
    if-ne p2, v5, :cond_0

    const/4 v0, 0x1

    .line 240
    .local v0, positiveResult:Z
    :goto_0
    iget-object v4, p0, Lcom/android/internal/app/RingtonePickerActivity;->mRingtoneManager:Landroid/media/RingtoneManager;

    invoke-virtual {v4}, Landroid/media/RingtoneManager;->stopPreviousRingtone()V

    .line 242
    if-eqz v0, :cond_3

    .line 243
    new-instance v1, Landroid/content/Intent;

    invoke-direct {v1}, Landroid/content/Intent;-><init>()V

    .line 244
    .local v1, resultIntent:Landroid/content/Intent;
    const/4 v2, 0x0

    .line 246
    .local v2, uri:Landroid/net/Uri;
    iget v3, p0, Lcom/android/internal/app/RingtonePickerActivity;->mClickedPos:I

    iget v4, p0, Lcom/android/internal/app/RingtonePickerActivity;->mDefaultRingtonePos:I

    if-ne v3, v4, :cond_1

    .line 248
    iget-object v2, p0, Lcom/android/internal/app/RingtonePickerActivity;->mUriForDefaultItem:Landroid/net/Uri;

    .line 256
    :goto_1
    const-string v3, "android.intent.extra.ringtone.PICKED_URI"

    invoke-virtual {v1, v3, v2}, Landroid/content/Intent;->putExtra(Ljava/lang/String;Landroid/os/Parcelable;)Landroid/content/Intent;

    .line 257
    invoke-virtual {p0, v5, v1}, Lcom/android/internal/app/RingtonePickerActivity;->setResult(ILandroid/content/Intent;)V

    .line 262
    .end local v1           #resultIntent:Landroid/content/Intent;
    .end local v2           #uri:Landroid/net/Uri;
    :goto_2
    invoke-virtual {p0}, Lcom/android/internal/app/RingtonePickerActivity;->getWindow()Landroid/view/Window;

    move-result-object v3

    invoke-virtual {v3}, Landroid/view/Window;->getDecorView()Landroid/view/View;

    move-result-object v3

    new-instance v4, Lcom/android/internal/app/RingtonePickerActivity$2;

    invoke-direct {v4, p0}, Lcom/android/internal/app/RingtonePickerActivity$2;-><init>(Lcom/android/internal/app/RingtonePickerActivity;)V

    invoke-virtual {v3, v4}, Landroid/view/View;->post(Ljava/lang/Runnable;)Z

    .line 268
    invoke-virtual {p0}, Lcom/android/internal/app/RingtonePickerActivity;->finish()V

    .line 269
    return-void

    .end local v0           #positiveResult:Z
    :cond_0
    move v0, v3

    .line 237
    goto :goto_0

    .line 249
    .restart local v0       #positiveResult:Z
    .restart local v1       #resultIntent:Landroid/content/Intent;
    .restart local v2       #uri:Landroid/net/Uri;
    :cond_1
    iget v3, p0, Lcom/android/internal/app/RingtonePickerActivity;->mClickedPos:I

    iget v4, p0, Lcom/android/internal/app/RingtonePickerActivity;->mSilentPos:I

    if-ne v3, v4, :cond_2

    .line 251
    const/4 v2, 0x0

    goto :goto_1

    .line 253
    :cond_2
    iget-object v3, p0, Lcom/android/internal/app/RingtonePickerActivity;->mRingtoneManager:Landroid/media/RingtoneManager;

    iget v4, p0, Lcom/android/internal/app/RingtonePickerActivity;->mClickedPos:I

    invoke-direct {p0, v4}, Lcom/android/internal/app/RingtonePickerActivity;->getRingtoneManagerPosition(I)I

    move-result v4

    invoke-virtual {v3, v4}, Landroid/media/RingtoneManager;->getRingtoneUri(I)Landroid/net/Uri;

    move-result-object v2

    goto :goto_1

    .line 259
    .end local v1           #resultIntent:Landroid/content/Intent;
    .end local v2           #uri:Landroid/net/Uri;
    :cond_3
    invoke-virtual {p0, v3}, Lcom/android/internal/app/RingtonePickerActivity;->setResult(I)V

    goto :goto_2
.end method

.method protected onCreate(Landroid/os/Bundle;)V
    .locals 7
    .parameter "savedInstanceState"

    .prologue
    const/4 v6, -0x1

    const/4 v5, 0x1

    .line 110
    invoke-super {p0, p1}, Lcom/android/internal/app/AlertActivity;->onCreate(Landroid/os/Bundle;)V

    .line 112
    new-instance v4, Landroid/os/Handler;

    invoke-direct {v4}, Landroid/os/Handler;-><init>()V

    iput-object v4, p0, Lcom/android/internal/app/RingtonePickerActivity;->mHandler:Landroid/os/Handler;

    .line 114
    invoke-virtual {p0}, Lcom/android/internal/app/RingtonePickerActivity;->getIntent()Landroid/content/Intent;

    move-result-object v1

    .line 120
    .local v1, intent:Landroid/content/Intent;
    const-string v4, "android.intent.extra.ringtone.SHOW_DEFAULT"

    invoke-virtual {v1, v4, v5}, Landroid/content/Intent;->getBooleanExtra(Ljava/lang/String;Z)Z

    move-result v4

    iput-boolean v4, p0, Lcom/android/internal/app/RingtonePickerActivity;->mHasDefaultItem:Z

    .line 121
    const-string v4, "android.intent.extra.ringtone.DEFAULT_URI"

    invoke-virtual {v1, v4}, Landroid/content/Intent;->getParcelableExtra(Ljava/lang/String;)Landroid/os/Parcelable;

    move-result-object v4

    check-cast v4, Landroid/net/Uri;

    iput-object v4, p0, Lcom/android/internal/app/RingtonePickerActivity;->mUriForDefaultItem:Landroid/net/Uri;

    .line 122
    iget-object v4, p0, Lcom/android/internal/app/RingtonePickerActivity;->mUriForDefaultItem:Landroid/net/Uri;

    if-nez v4, :cond_0

    .line 123
    sget-object v4, Landroid/provider/Settings$System;->DEFAULT_RINGTONE_URI:Landroid/net/Uri;

    iput-object v4, p0, Lcom/android/internal/app/RingtonePickerActivity;->mUriForDefaultItem:Landroid/net/Uri;

    .line 126
    :cond_0
    if-eqz p1, :cond_1

    .line 127
    const-string v4, "clicked_pos"

    invoke-virtual {p1, v4, v6}, Landroid/os/Bundle;->getInt(Ljava/lang/String;I)I

    move-result v4

    iput v4, p0, Lcom/android/internal/app/RingtonePickerActivity;->mClickedPos:I

    .line 130
    :cond_1
    const-string v4, "android.intent.extra.ringtone.SHOW_SILENT"

    invoke-virtual {v1, v4, v5}, Landroid/content/Intent;->getBooleanExtra(Ljava/lang/String;Z)Z

    move-result v4

    iput-boolean v4, p0, Lcom/android/internal/app/RingtonePickerActivity;->mHasSilentItem:Z

    .line 133
    new-instance v4, Landroid/media/RingtoneManager;

    invoke-direct {v4, p0}, Landroid/media/RingtoneManager;-><init>(Landroid/app/Activity;)V

    iput-object v4, p0, Lcom/android/internal/app/RingtonePickerActivity;->mRingtoneManager:Landroid/media/RingtoneManager;

    .line 136
    const-string v4, "android.intent.extra.ringtone.INCLUDE_DRM"

    invoke-virtual {v1, v4, v5}, Landroid/content/Intent;->getBooleanExtra(Ljava/lang/String;Z)Z

    move-result v0

    .line 138
    .local v0, includeDrm:Z
    iget-object v4, p0, Lcom/android/internal/app/RingtonePickerActivity;->mRingtoneManager:Landroid/media/RingtoneManager;

    invoke-virtual {v4, v0}, Landroid/media/RingtoneManager;->setIncludeDrm(Z)V

    .line 141
    const-string v4, "android.intent.extra.ringtone.TYPE"

    invoke-virtual {v1, v4, v6}, Landroid/content/Intent;->getIntExtra(Ljava/lang/String;I)I

    move-result v3

    .line 142
    .local v3, types:I
    if-eq v3, v6, :cond_2

    .line 143
    iget-object v4, p0, Lcom/android/internal/app/RingtonePickerActivity;->mRingtoneManager:Landroid/media/RingtoneManager;

    invoke-virtual {v4, v3}, Landroid/media/RingtoneManager;->setType(I)V

    .line 146
    :cond_2
    iget-object v4, p0, Lcom/android/internal/app/RingtonePickerActivity;->mRingtoneManager:Landroid/media/RingtoneManager;

    invoke-virtual {v4}, Landroid/media/RingtoneManager;->getCursor()Landroid/database/Cursor;

    move-result-object v4

    iput-object v4, p0, Lcom/android/internal/app/RingtonePickerActivity;->mCursor:Landroid/database/Cursor;

    .line 149
    iget-object v4, p0, Lcom/android/internal/app/RingtonePickerActivity;->mRingtoneManager:Landroid/media/RingtoneManager;

    invoke-virtual {v4}, Landroid/media/RingtoneManager;->inferStreamType()I

    move-result v4

    invoke-virtual {p0, v4}, Lcom/android/internal/app/RingtonePickerActivity;->setVolumeControlStream(I)V

    .line 152
    const-string v4, "android.intent.extra.ringtone.EXISTING_URI"

    invoke-virtual {v1, v4}, Landroid/content/Intent;->getParcelableExtra(Ljava/lang/String;)Landroid/os/Parcelable;

    move-result-object v4

    check-cast v4, Landroid/net/Uri;

    iput-object v4, p0, Lcom/android/internal/app/RingtonePickerActivity;->mExistingUri:Landroid/net/Uri;

    .line 155
    iget-object v2, p0, Lcom/android/internal/app/AlertActivity;->mAlertParams:Lcom/android/internal/app/AlertController$AlertParams;

    .line 156
    .local v2, p:Lcom/android/internal/app/AlertController$AlertParams;
    iget-object v4, p0, Lcom/android/internal/app/RingtonePickerActivity;->mCursor:Landroid/database/Cursor;

    iput-object v4, v2, Lcom/android/internal/app/AlertController$AlertParams;->mCursor:Landroid/database/Cursor;

    .line 157
    iget-object v4, p0, Lcom/android/internal/app/RingtonePickerActivity;->mRingtoneClickListener:Landroid/content/DialogInterface$OnClickListener;

    iput-object v4, v2, Lcom/android/internal/app/AlertController$AlertParams;->mOnClickListener:Landroid/content/DialogInterface$OnClickListener;

    .line 158
    const-string/jumbo v4, "title"

    iput-object v4, v2, Lcom/android/internal/app/AlertController$AlertParams;->mLabelColumn:Ljava/lang/String;

    .line 159
    iput-boolean v5, v2, Lcom/android/internal/app/AlertController$AlertParams;->mIsSingleChoice:Z

    .line 160
    iput-object p0, v2, Lcom/android/internal/app/AlertController$AlertParams;->mOnItemSelectedListener:Landroid/widget/AdapterView$OnItemSelectedListener;

    .line 161
    const v4, 0x104000a

    invoke-virtual {p0, v4}, Lcom/android/internal/app/RingtonePickerActivity;->getString(I)Ljava/lang/String;

    move-result-object v4

    iput-object v4, v2, Lcom/android/internal/app/AlertController$AlertParams;->mPositiveButtonText:Ljava/lang/CharSequence;

    .line 162
    iput-object p0, v2, Lcom/android/internal/app/AlertController$AlertParams;->mPositiveButtonListener:Landroid/content/DialogInterface$OnClickListener;

    .line 163
    const/high16 v4, 0x104

    invoke-virtual {p0, v4}, Lcom/android/internal/app/RingtonePickerActivity;->getString(I)Ljava/lang/String;

    move-result-object v4

    iput-object v4, v2, Lcom/android/internal/app/AlertController$AlertParams;->mNegativeButtonText:Ljava/lang/CharSequence;

    .line 164
    iput-object p0, v2, Lcom/android/internal/app/AlertController$AlertParams;->mPositiveButtonListener:Landroid/content/DialogInterface$OnClickListener;

    .line 165
    iput-object p0, v2, Lcom/android/internal/app/AlertController$AlertParams;->mOnPrepareListViewListener:Lcom/android/internal/app/AlertController$AlertParams$OnPrepareListViewListener;

    .line 167
    const-string v4, "android.intent.extra.ringtone.TITLE"

    invoke-virtual {v1, v4}, Landroid/content/Intent;->getCharSequenceExtra(Ljava/lang/String;)Ljava/lang/CharSequence;

    move-result-object v4

    iput-object v4, v2, Lcom/android/internal/app/AlertController$AlertParams;->mTitle:Ljava/lang/CharSequence;

    .line 168
    iget-object v4, v2, Lcom/android/internal/app/AlertController$AlertParams;->mTitle:Ljava/lang/CharSequence;

    if-nez v4, :cond_3

    .line 169
    const v4, 0x10403eb

    invoke-virtual {p0, v4}, Lcom/android/internal/app/RingtonePickerActivity;->getString(I)Ljava/lang/String;

    move-result-object v4

    iput-object v4, v2, Lcom/android/internal/app/AlertController$AlertParams;->mTitle:Ljava/lang/CharSequence;

    .line 172
    :cond_3
    invoke-virtual {p0}, Lcom/android/internal/app/RingtonePickerActivity;->setupAlert()V

    .line 173
    return-void
.end method

.method public onItemSelected(Landroid/widget/AdapterView;Landroid/view/View;IJ)V
    .locals 1
    .parameter "parent"
    .parameter "view"
    .parameter "position"
    .parameter "id"

    .prologue
    .line 275
    const/16 v0, 0x12c

    invoke-direct {p0, p3, v0}, Lcom/android/internal/app/RingtonePickerActivity;->playRingtone(II)V

    .line 276
    return-void
.end method

.method public onNothingSelected(Landroid/widget/AdapterView;)V
    .locals 0
    .parameter "parent"

    .prologue
    .line 279
    return-void
.end method

.method protected onPause()V
    .locals 0

    .prologue
    .line 335
    invoke-super {p0}, Lcom/android/internal/app/AlertActivity;->onPause()V

    .line 336
    invoke-direct {p0}, Lcom/android/internal/app/RingtonePickerActivity;->stopAnyPlayingRingtone()V

    .line 337
    return-void
.end method

.method public onPrepareListView(Landroid/widget/ListView;)V
    .locals 2
    .parameter "listView"

    .prologue
    .line 183
    iget-boolean v0, p0, Lcom/android/internal/app/RingtonePickerActivity;->mHasDefaultItem:Z

    if-eqz v0, :cond_0

    .line 184
    invoke-direct {p0, p1}, Lcom/android/internal/app/RingtonePickerActivity;->addDefaultRingtoneItem(Landroid/widget/ListView;)I

    move-result v0

    iput v0, p0, Lcom/android/internal/app/RingtonePickerActivity;->mDefaultRingtonePos:I

    .line 186
    iget-object v0, p0, Lcom/android/internal/app/RingtonePickerActivity;->mExistingUri:Landroid/net/Uri;

    invoke-static {v0}, Landroid/media/RingtoneManager;->isDefault(Landroid/net/Uri;)Z

    move-result v0

    if-eqz v0, :cond_0

    .line 187
    iget v0, p0, Lcom/android/internal/app/RingtonePickerActivity;->mDefaultRingtonePos:I

    iput v0, p0, Lcom/android/internal/app/RingtonePickerActivity;->mClickedPos:I

    .line 191
    :cond_0
    iget-boolean v0, p0, Lcom/android/internal/app/RingtonePickerActivity;->mHasSilentItem:Z

    if-eqz v0, :cond_1

    .line 192
    invoke-direct {p0, p1}, Lcom/android/internal/app/RingtonePickerActivity;->addSilentItem(Landroid/widget/ListView;)I

    move-result v0

    iput v0, p0, Lcom/android/internal/app/RingtonePickerActivity;->mSilentPos:I

    .line 195
    iget-object v0, p0, Lcom/android/internal/app/RingtonePickerActivity;->mExistingUri:Landroid/net/Uri;

    if-nez v0, :cond_1

    .line 196
    iget v0, p0, Lcom/android/internal/app/RingtonePickerActivity;->mSilentPos:I

    iput v0, p0, Lcom/android/internal/app/RingtonePickerActivity;->mClickedPos:I

    .line 200
    :cond_1
    iget v0, p0, Lcom/android/internal/app/RingtonePickerActivity;->mClickedPos:I

    const/4 v1, -0x1

    if-ne v0, v1, :cond_2

    .line 201
    iget-object v0, p0, Lcom/android/internal/app/RingtonePickerActivity;->mRingtoneManager:Landroid/media/RingtoneManager;

    iget-object v1, p0, Lcom/android/internal/app/RingtonePickerActivity;->mExistingUri:Landroid/net/Uri;

    invoke-virtual {v0, v1}, Landroid/media/RingtoneManager;->getRingtonePosition(Landroid/net/Uri;)I

    move-result v0

    invoke-direct {p0, v0}, Lcom/android/internal/app/RingtonePickerActivity;->getListPosition(I)I

    move-result v0

    iput v0, p0, Lcom/android/internal/app/RingtonePickerActivity;->mClickedPos:I

    .line 205
    :cond_2
    iget-object v0, p0, Lcom/android/internal/app/AlertActivity;->mAlertParams:Lcom/android/internal/app/AlertController$AlertParams;

    iget v1, p0, Lcom/android/internal/app/RingtonePickerActivity;->mClickedPos:I

    iput v1, v0, Lcom/android/internal/app/AlertController$AlertParams;->mCheckedItem:I

    .line 206
    return-void
.end method

.method public onSaveInstanceState(Landroid/os/Bundle;)V
    .locals 2
    .parameter "outState"

    .prologue
    .line 177
    invoke-super {p0, p1}, Lcom/android/internal/app/AlertActivity;->onSaveInstanceState(Landroid/os/Bundle;)V

    .line 178
    const-string v0, "clicked_pos"

    iget v1, p0, Lcom/android/internal/app/RingtonePickerActivity;->mClickedPos:I

    invoke-virtual {p1, v0, v1}, Landroid/os/Bundle;->putInt(Ljava/lang/String;I)V

    .line 179
    return-void
.end method

.method protected onStop()V
    .locals 0

    .prologue
    .line 329
    invoke-super {p0}, Lcom/android/internal/app/AlertActivity;->onStop()V

    .line 330
    invoke-direct {p0}, Lcom/android/internal/app/RingtonePickerActivity;->stopAnyPlayingRingtone()V

    .line 331
    return-void
.end method

.method public run()V
    .locals 3

    .prologue
    .line 289
    iget v1, p0, Lcom/android/internal/app/RingtonePickerActivity;->mSampleRingtonePos:I

    iget v2, p0, Lcom/android/internal/app/RingtonePickerActivity;->mSilentPos:I

    if-ne v1, v2, :cond_1

    .line 290
    iget-object v1, p0, Lcom/android/internal/app/RingtonePickerActivity;->mRingtoneManager:Landroid/media/RingtoneManager;

    invoke-virtual {v1}, Landroid/media/RingtoneManager;->stopPreviousRingtone()V

    .line 325
    :cond_0
    :goto_0
    return-void

    .line 298
    :cond_1
    iget-object v1, p0, Lcom/android/internal/app/RingtonePickerActivity;->mDefaultRingtone:Landroid/media/Ringtone;

    if-eqz v1, :cond_2

    iget-object v1, p0, Lcom/android/internal/app/RingtonePickerActivity;->mDefaultRingtone:Landroid/media/Ringtone;

    invoke-virtual {v1}, Landroid/media/Ringtone;->isPlaying()Z

    move-result v1

    if-eqz v1, :cond_2

    .line 299
    iget-object v1, p0, Lcom/android/internal/app/RingtonePickerActivity;->mDefaultRingtone:Landroid/media/Ringtone;

    invoke-virtual {v1}, Landroid/media/Ringtone;->stop()V

    .line 300
    const/4 v1, 0x0

    iput-object v1, p0, Lcom/android/internal/app/RingtonePickerActivity;->mDefaultRingtone:Landroid/media/Ringtone;

    .line 304
    :cond_2
    iget v1, p0, Lcom/android/internal/app/RingtonePickerActivity;->mSampleRingtonePos:I

    iget v2, p0, Lcom/android/internal/app/RingtonePickerActivity;->mDefaultRingtonePos:I

    if-ne v1, v2, :cond_4

    .line 305
    iget-object v1, p0, Lcom/android/internal/app/RingtonePickerActivity;->mDefaultRingtone:Landroid/media/Ringtone;

    if-nez v1, :cond_3

    .line 306
    iget-object v1, p0, Lcom/android/internal/app/RingtonePickerActivity;->mUriForDefaultItem:Landroid/net/Uri;

    invoke-static {p0, v1}, Landroid/media/RingtoneManager;->getRingtone(Landroid/content/Context;Landroid/net/Uri;)Landroid/media/Ringtone;

    move-result-object v1

    iput-object v1, p0, Lcom/android/internal/app/RingtonePickerActivity;->mDefaultRingtone:Landroid/media/Ringtone;

    .line 308
    :cond_3
    iget-object v0, p0, Lcom/android/internal/app/RingtonePickerActivity;->mDefaultRingtone:Landroid/media/Ringtone;

    .line 316
    .local v0, ringtone:Landroid/media/Ringtone;
    iget-object v1, p0, Lcom/android/internal/app/RingtonePickerActivity;->mRingtoneManager:Landroid/media/RingtoneManager;

    invoke-virtual {v1}, Landroid/media/RingtoneManager;->stopPreviousRingtone()V

    .line 322
    :goto_1
    if-eqz v0, :cond_0

    .line 323
    invoke-virtual {v0}, Landroid/media/Ringtone;->play()V

    goto :goto_0

    .line 319
    .end local v0           #ringtone:Landroid/media/Ringtone;
    :cond_4
    iget-object v1, p0, Lcom/android/internal/app/RingtonePickerActivity;->mRingtoneManager:Landroid/media/RingtoneManager;

    iget v2, p0, Lcom/android/internal/app/RingtonePickerActivity;->mSampleRingtonePos:I

    invoke-direct {p0, v2}, Lcom/android/internal/app/RingtonePickerActivity;->getRingtoneManagerPosition(I)I

    move-result v2

    invoke-virtual {v1, v2}, Landroid/media/RingtoneManager;->getRingtone(I)Landroid/media/Ringtone;

    move-result-object v0

    .restart local v0       #ringtone:Landroid/media/Ringtone;
    goto :goto_1
.end method


text:
<?xml version="1.0" encoding="utf-8"?>
<extension type="module" version="3.1" client="administrator" method="upgrade">
	<name>mod_quickicon</name>
	<author>Joomla! Project</author>
	<creationDate>Nov 2005</creationDate>
	<copyright>Copyright (C) 2005 - 2017 Open Source Matters. All rights reserved.</copyright>
	<license>GNU General Public License version 2 or later; see LICENSE.txt</license>
	<authorEmail>admin@joomla.org</authorEmail>
	<authorUrl>www.joomla.org</authorUrl>
	<version>3.0.0</version>
	<description>MOD_QUICKICON_XML_DESCRIPTION</description>
	<files>
		<filename module="mod_quickicon">mod_quickicon.php</filename>
		<folder>tmpl</folder>
		<filename>helper.php</filename>
	</files>
	<languages>
		<language tag="en-GB">en-GB.mod_quickicon.ini</language>
		<language tag="en-GB">en-GB.mod_quickicon.sys.ini</language>
	</languages>
	<help key="JHELP_EXTENSIONS_MODULE_MANAGER_ADMIN_QUICKICON" />
	<config>
		<fields name="params">
			<fieldset name="basic">
				<field
					name="context"
					type="text"
					label="MOD_QUICKICON_GROUP_LABEL"
					description="MOD_QUICKICON_GROUP_DESC"
					default="mod_quickicon"
				/>
			</fieldset>
			<fieldset name="advanced">
				<field
					name="layout"
					type="modulelayout"
					label="JFIELD_ALT_LAYOUT_LABEL"
					description="JFIELD_ALT_MODULE_LAYOUT_DESC"
				/>

				<field
					name="moduleclass_sfx"
					type="textarea"
					label="COM_MODULES_FIELD_MODULECLASS_SFX_LABEL"
					description="COM_MODULES_FIELD_MODULECLASS_SFX_DESC"
					rows="3"
				/>

				<field
					name="cache"
					type="list"
					label="COM_MODULES_FIELD_CACHING_LABEL"
					description="COM_MODULES_FIELD_CACHING_DESC"
					default="1"
					>
					<option value="1">JGLOBAL_USE_GLOBAL</option>
					<option value="0">COM_MODULES_FIELD_VALUE_NOCACHING</option>
				</field>

				<field
					name="cache_time"
					type="text"
					label="COM_MODULES_FIELD_CACHE_TIME_LABEL"
					description="COM_MODULES_FIELD_CACHE_TIME_DESC"
					default="900"
				/>
			</fieldset>
		</fields>
	</config>
</extension>


text:
using base::ProcessHandle;
using base::TimeTicks;
using content::BrowserThread;

namespace resource_coordinator {
namespace {

// The default interval after which to adjust OOM scores.
constexpr base::TimeDelta kAdjustmentInterval = base::Seconds(10);

// When switching to a new tab the tab's renderer's OOM score needs to be
// updated to reflect its front-most status and protect it from discard.
// However, doing this immediately might slow down tab switch time, so wait
// a little while before doing the adjustment.
const int kFocusedProcessScoreAdjustIntervalMs = 500;

wm::ActivationClient* GetActivationClient() {
  if (!ash::Shell::HasInstance())
    return nullptr;
  return wm::GetActivationClient(ash::Shell::GetPrimaryRootWindow());
}

void OnSetOomScoreAdj(bool success, const std::string& output) {
  VLOG(2) << "OnSetOomScoreAdj " << success << " " << output;
  if (!success)
    LOG(ERROR) << "Set OOM score error: " << output;
  else if (!output.empty())
    LOG(WARNING) << "Set OOM score: " << output;
}

}  // namespace

// static
const int TabManagerDelegate::kPersistentArcAppOomScore = -100;

std::ostream& operator<<(std::ostream& os, const ProcessType& type) {
  switch (type) {
    case ProcessType::FOCUSED_TAB:
      return os << "FOCUSED_TAB";
    case ProcessType::FOCUSED_APP:
      return os << "FOCUSED_APP";
    case ProcessType::UNKNOWN_TYPE:
      return os << "UNKNOWN_TYPE";
    case ProcessType::BACKGROUND:
      return os << "BACKGROUND";
    case ProcessType::PROTECTED_BACKGROUND:
      return os << "PROTECTED_BACKGROUND";
    case ProcessType::CACHED_APP:
      return os << "CACHED_APP";
    default:
      return os << "NOT_IMPLEMENTED_ERROR";
  }
}

// TabManagerDelegate::Candidate implementation.
std::ostream& operator<<(std::ostream& out,
                         const TabManagerDelegate::Candidate& candidate) {
  if (candidate.app())
    out << "app " << *candidate.app();
  else if (candidate.lifecycle_unit())
    out << "tab (id: " << candidate.lifecycle_unit()->GetID()
        << ", pid: " << candidate.lifecycle_unit()->GetProcessHandle() << ")";
  out << ", process_type " << candidate.process_type();
  return out;
}

TabManagerDelegate::Candidate& TabManagerDelegate::Candidate::operator=(
    TabManagerDelegate::Candidate&& other) = default;

bool TabManagerDelegate::Candidate::operator<(
    const TabManagerDelegate::Candidate& rhs) const {
  if (process_type() != rhs.process_type())
    return process_type() < rhs.process_type();
  return LastActivityTime() > rhs.LastActivityTime();
}

ProcessType TabManagerDelegate::Candidate::GetProcessTypeInternal() const {
  if (app()) {
    if (app()->is_focused())
      return ProcessType::FOCUSED_APP;
    if (app()->IsBackgroundProtected())
      return ProcessType::PROTECTED_BACKGROUND;
    if (app()->IsCached())
      return ProcessType::CACHED_APP;
    return ProcessType::BACKGROUND;
  }
  if (lifecycle_unit()) {
    if (LastActivityTime() == base::TimeTicks::Max())
      return ProcessType::FOCUSED_TAB;
    DecisionDetails decision_details;
    if (!lifecycle_unit()->CanDiscard(
            ::mojom::LifecycleUnitDiscardReason::EXTERNAL, &decision_details)) {
      return ProcessType::PROTECTED_BACKGROUND;
    }
    return ProcessType::BACKGROUND;
  }
  return ProcessType::UNKNOWN_TYPE;
}

base::TimeTicks TabManagerDelegate::Candidate::LastActivityTime() const {
  if (app()) {
    return base::TimeTicks::FromUptimeMillis(app()->last_activity_time());
  }
  if (lifecycle_unit()) {
    return lifecycle_unit()->GetLastFocusedTime();
  }
  NOTREACHED();
  return base::TimeTicks();
}

// Holds the info of a newly focused tab or app window. The focused process is
// set to highest priority (lowest OOM score), but not immediately. To avoid
// redundant settings the OOM score adjusting only happens after a timeout. If
// the process loses focus before the timeout, the adjustment is canceled.
class TabManagerDelegate::FocusedProcess {
 public:
  static const int kInvalidArcAppNspid = 0;

  FocusedProcess() { Reset(); }

  void SetTabPid(const base::ProcessHandle pid) {
    pid_ = pid;
    nspid_ = kInvalidArcAppNspid;
  }

  void SetArcAppNspid(const int nspid) {
    pid_ = base::kNullProcessHandle;
    nspid_ = nspid;
  }

  base::ProcessHandle GetTabPid() const { return pid_; }

  int GetArcAppNspid() const { return nspid_; }

  // Checks whether the containing instance is an ARC app. If so it resets the
  // data and returns true. Useful when canceling an ongoing OOM score setting
  // for a focused ARC app because the focus has been shifted away shortly.
  bool ResetIfIsArcApp() {
    if (nspid_ != kInvalidArcAppNspid) {
      Reset();
      return true;
    }
    return false;
  }

 private:
  void Reset() {
    pid_ = base::kNullProcessHandle;
    nspid_ = kInvalidArcAppNspid;
  }

  // The focused app could be a Chrome tab or an Android app, but not both.
  // At most one of them contains a valid value at any time.

  // If a chrome tab.
  base::ProcessHandle pid_;
  // If an Android app.
  int nspid_;
};

// TabManagerDelegate::MemoryStat implementation.

// Target memory to free is the amount which brings available
// memory back to the margin.
int TabManagerDelegate::MemoryStat::TargetMemoryToFreeKB() {
  auto* monitor = ash::memory::SystemMemoryPressureEvaluator::Get();
  if (monitor) {
    return monitor->GetCachedReclaimTargetKB();
  } else {
    // When TabManager::DiscardTab(LifecycleUnitDiscardReason::EXTERNAL) is
    // called by an integration test, TabManagerDelegate might be used without
    // chromeos SystemMemoryPressureEvaluator, e.g. the browser test
    // DiscardTabsWithMinimizedWindow. Return 50 MB to force discarding a tab to
    // pass the test.
    // TODO(vovoy): Remove this code path and modify the related browser tests.
    LOG(WARNING) << "SystemMemoryPressureEvaluator is not available";
    constexpr int kDefaultLowMemoryMarginKb = 50 * 1024;
    return kDefaultLowMemoryMarginKb;
  }
}

int TabManagerDelegate::MemoryStat::EstimatedMemoryFreedKB(
    base::ProcessHandle handle) {
  return GetPrivateMemoryKB(handle);
}

TabManagerDelegate::TabManagerDelegate(
    const base::WeakPtr<TabManager>& tab_manager)
    : TabManagerDelegate(tab_manager, new MemoryStat()) {}

TabManagerDelegate::TabManagerDelegate(
    const base::WeakPtr<TabManager>& tab_manager,
    TabManagerDelegate::MemoryStat* mem_stat)
    : tab_manager_(tab_manager),
      focused_process_(new FocusedProcess()),
      mem_stat_(mem_stat) {
  registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
                 content::NotificationService::AllBrowserContextsAndSources());
  registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED,
                 content::NotificationService::AllBrowserContextsAndSources());
  registrar_.Add(this, content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED,
                 content::NotificationService::AllBrowserContextsAndSources());
  auto* activation_client = GetActivationClient();
  if (activation_client)
    activation_client->AddObserver(this);
  BrowserList::GetInstance()->AddObserver(this);
}

TabManagerDelegate::~TabManagerDelegate() {
  BrowserList::GetInstance()->RemoveObserver(this);
  auto* activation_client = GetActivationClient();
  if (activation_client)
    activation_client->RemoveObserver(this);
}

void TabManagerDelegate::OnBrowserSetLastActive(Browser* browser) {
  // Set OOM score to the selected tab when a browser window is activated.
  // content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED didn't catch the
  // case (like when switching focus between 2 browser windows) so we need to
  // handle it here.
  TabStripModel* tab_strip_model = browser->tab_strip_model();
  int selected_index = tab_strip_model->active_index();
  content::WebContents* contents =
      tab_strip_model->GetWebContentsAt(selected_index);
  if (!contents)
    return;

  base::ProcessHandle pid =
      contents->GetPrimaryMainFrame()->GetProcess()->GetProcess().Handle();
  AdjustFocusedTabScore(pid);
}

void TabManagerDelegate::OnWindowActivated(
    wm::ActivationChangeObserver::ActivationReason reason,
    aura::Window* gained_active,
    aura::Window* lost_active) {
  if (ash::IsArcWindow(gained_active)) {
    // Currently there is no way to know which app is displayed in the ARC
    // window, so schedule an early adjustment for all processes to reflect
    // the change.
    // Put a dummy FocusedProcess with nspid = kInvalidArcAppNspid for now to
    // indicate the focused process is an arc app.
    // TODO(cylee): Fix it when we have nspid info in ARC windows.
    focused_process_->SetArcAppNspid(FocusedProcess::kInvalidArcAppNspid);
    // If the timer is already running (possibly for a tab), it'll be reset
    // here.
    focus_process_score_adjust_timer_.Start(
        FROM_HERE, base::Milliseconds(kFocusedProcessScoreAdjustIntervalMs),
        this, &TabManagerDelegate::ScheduleEarlyOomPrioritiesAdjustment);
  }
  if (ash::IsArcWindow(lost_active)) {
    // Do not bother adjusting OOM score if the ARC window is deactivated
    // shortly.
    if (focused_process_->ResetIfIsArcApp() &&
        focus_process_score_adjust_timer_.IsRunning())
      focus_process_score_adjust_timer_.Stop();
  }
}

void TabManagerDelegate::StartPeriodicOOMScoreUpdate() {
  DCHECK(!adjust_oom_priorities_timer_.IsRunning());
  adjust_oom_priorities_timer_.Start(FROM_HERE, kAdjustmentInterval, this,
                                     &TabManagerDelegate::AdjustOomPriorities);
}

void TabManagerDelegate::ScheduleEarlyOomPrioritiesAdjustment() {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  AdjustOomPriorities();
}

// If able to get the list of ARC processes, prioritize tabs and apps as a
// whole. Otherwise try to kill tabs only.
void TabManagerDelegate::LowMemoryKill(
    ::mojom::LifecycleUnitDiscardReason reason,
    TabManager::TabDiscardDoneCB tab_discard_done) {
  arc::ArcProcessService* arc_process_service = arc::ArcProcessService::Get();
  base::TimeTicks now = base::TimeTicks::Now();
  // ARCVM defers to Android's LMK to kill apps in low memory situations because
  // memory can't be reclaimed directly to ChromeOS.
  if (arc_process_service && !arc::IsArcVmEnabled()) {
    arc_process_service->RequestAppProcessList(base::BindOnce(
        &TabManagerDelegate::LowMemoryKillImpl, weak_ptr_factory_.GetWeakPtr(),
        now, reason, std::move(tab_discard_done)));
  } else {
    LowMemoryKillImpl(now, reason, std::move(tab_discard_done), absl::nullopt);
  }
}

int TabManagerDelegate::GetCachedOomScore(ProcessHandle process_handle) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  auto it = oom_score_map_.find(process_handle);
  if (it != oom_score_map_.end()) {
    return it->second;
  }
  // An impossible value for oom_score_adj.
  return -1001;
}

LifecycleUnitVector TabManagerDelegate::GetLifecycleUnits() {
  if (tab_manager_)
    return tab_manager_->GetSortedLifecycleUnits();
  return LifecycleUnitVector();
}

void TabManagerDelegate::OnFocusTabScoreAdjustmentTimeout() {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  base::ProcessHandle pid = focused_process_->GetTabPid();
  // The focused process doesn't render a tab. Could happen when the focus
  // just switched to an ARC app before the timeout. We can not avoid the race.
  if (pid == base::kNullProcessHandle)
    return;

  // Update the OOM score cache.
  oom_score_map_[pid] = content::kLowestRendererOomScore;

  // Sets OOM score.
  VLOG(3) << "Set OOM score " << content::kLowestRendererOomScore
          << " for focused tab " << pid;
  if (!base::AdjustOOMScore(pid, content::kLowestRendererOomScore))
    LOG(ERROR) << "Failed to set oom_score_adj to "
               << content::kLowestRendererOomScore
               << " for focused tab, pid: " << pid;
}

void TabManagerDelegate::AdjustFocusedTabScore(base::ProcessHandle pid) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  // Clear running timer if one was set for a previous focused tab/app.
  if (focus_process_score_adjust_timer_.IsRunning())
    focus_process_score_adjust_timer_.Stop();
  focused_process_->SetTabPid(pid);

  // If the currently focused tab already has a lower score, do not
  // set it. This can happen in case the newly focused tab is script
  // connected to the previous tab.
  ProcessScoreMap::iterator it = oom_score_map_.find(pid);
  const bool not_lowest_score =
      (it == oom_score_map_.end() ||
       it->second != content::kLowestRendererOomScore);

  if (not_lowest_score) {
    // By starting a timer we guarantee that the tab is focused for
    // certain amount of time. Secondly, it also does not add overhead
    // to the tab switching time.
    // If there's an existing running timer (could be for ARC app), it
    // would be replaced by a new task.
    focus_process_score_adjust_timer_.Start(
        FROM_HERE, base::Milliseconds(kFocusedProcessScoreAdjustIntervalMs),
        this, &TabManagerDelegate::OnFocusTabScoreAdjustmentTimeout);
  }
}

void TabManagerDelegate::Observe(int type,
                                 const content::NotificationSource& source,
                                 const content::NotificationDetails& details) {
  switch (type) {
    case content::NOTIFICATION_RENDERER_PROCESS_CLOSED:
    case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: {
      content::RenderProcessHost* host =
          content::Source<content::RenderProcessHost>(source).ptr();
      oom_score_map_.erase(host->GetProcess().Handle());
      break;
    }
    case content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED: {
      bool visible = *content::Details<bool>(details).ptr();
      if (visible) {
        content::RenderProcessHost* render_host =
            content::Source<content::RenderWidgetHost>(source)
                .ptr()
                ->GetProcess();
        AdjustFocusedTabScore(render_host->GetProcess().Handle());
      }
      // Do not handle the "else" case when it changes to invisible because
      // 1. The behavior is a bit awkward in that when switching from tab A to
      // tab B, the event "invisible of B" comes after "visible of A". It can
      // cause problems when the 2 tabs have the same content (e.g., New Tab
      // Page). To be more clear, if we try to cancel the timer when losing
      // focus it may cancel the timer for the same renderer process.
      // 2. When another window is launched on top of an existing browser
      // window, the selected tab in the existing browser didn't receive this
      // event, so an attempt to cancel timer in this case doesn't work.
      break;
    }
    default:
      NOTREACHED() << "Received unexpected notification";
      break;
  }
}

// Here we collect most of the information we need to sort the existing
// renderers in priority order, and hand out oom_score_adj scores based on that
// sort order.
//
// Things we need to collect on the browser thread (because
// TabStripModel isn't thread safe):
// 1) whether or not a tab is pinned
// 2) last time a tab was selected
// 3) is the tab currently selected
void TabManagerDelegate::AdjustOomPriorities() {
  // If Chrome is shutting down, do not do anything
  if (g_browser_process->IsShuttingDown())
    return;

  arc::ArcProcessService* arc_process_service = arc::ArcProcessService::Get();
  // ARCVM defers to Android's LMK to manage low memory situations, so don't
  // adjust OOM scores for VM processes.
  if (arc_process_service && !arc::IsArcVmEnabled()) {
    arc_process_service->RequestAppProcessList(
        base::BindOnce(&TabManagerDelegate::AdjustOomPrioritiesImpl,
                       weak_ptr_factory_.GetWeakPtr()));
  } else {
    // Pass in nullopt if unable to get ARC processes.
    AdjustOomPrioritiesImpl(absl::nullopt);
  }
}

// Get a list of candidates to kill, sorted by descending importance.
// static
std::vector<TabManagerDelegate::Candidate>
TabManagerDelegate::GetSortedCandidates(
    const LifecycleUnitVector& lifecycle_units,
    const OptionalArcProcessList& arc_processes) {
  std::vector<Candidate> candidates;
  candidates.reserve(lifecycle_units.size() +
                     (arc_processes ? (*arc_processes).size() : 0));

  for (LifecycleUnit* lifecycle_unit : lifecycle_units) {
    candidates.emplace_back(lifecycle_unit);
  }

  if (arc_processes) {
    for (const auto& app : *arc_processes) {
      candidates.emplace_back(&app);
    }
  }

  // Sort candidates according to priority.
  std::sort(candidates.begin(), candidates.end());

  return candidates;
}

bool TabManagerDelegate::IsRecentlyKilledArcProcess(
    const std::string& process_name,
    const TimeTicks& now) {
  const auto it = recently_killed_arc_processes_.find(process_name);
  if (it == recently_killed_arc_processes_.end())
    return false;
  return (now - it->second) <= GetArcRespawnKillDelay();
}

bool TabManagerDelegate::KillArcProcess(const int nspid) {
  auto* arc_service_manager = arc::ArcServiceManager::Get();
  if (!arc_service_manager)
    return false;

  auto* arc_process_instance = ARC_GET_INSTANCE_FOR_METHOD(
      arc_service_manager->arc_bridge_service()->process(), KillProcess);
  if (!arc_process_instance)
    return false;

  arc_process_instance->KillProcess(nspid, "LowMemoryKill");
  return true;
}

bool TabManagerDelegate::KillTab(LifecycleUnit* lifecycle_unit,
                                 ::mojom::LifecycleUnitDiscardReason reason) {
  bool did_discard = lifecycle_unit->Discard(reason);
  return did_discard;
}

ash::DebugDaemonClient* TabManagerDelegate::GetDebugDaemonClient() {
  return ash::DebugDaemonClient::Get();
}

void TabManagerDelegate::LowMemoryKillImpl(
    base::TimeTicks start_time,
    ::mojom::LifecycleUnitDiscardReason reason,
    TabManager::TabDiscardDoneCB tab_discard_done,
    OptionalArcProcessList arc_processes) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  VLOG(2) << "LowMemoryKillImpl";

  // Prevent persistent ARC processes from being killed.
  if (arc_processes) {
    base::EraseIf(*arc_processes,
                  [](auto& proc) { return proc.IsPersistent(); });
  }

  std::vector<Candidate> candidates =
      GetSortedCandidates(GetLifecycleUnits(), arc_processes);

  int target_memory_to_free_kb = mem_stat_->TargetMemoryToFreeKB();

  MEMORY_LOG(ERROR) << "List of low memory kill candidates "
                       "(sorted from low priority to high priority):";
  for (const Candidate& candidate : base::Reversed(candidates)) {
    MEMORY_LOG(ERROR) << candidate;
  }

  // Kill processes until the estimated amount of freed memory is sufficient to
  // bring the system memory back to a normal level.
  // The list is sorted by descending importance, so we go through the list
  // backwards.
  const TimeTicks now = TimeTicks::Now();
  base::TimeTicks first_kill_time;
  for (Candidate& candidate : base::Reversed(candidates)) {
    MEMORY_LOG(ERROR) << "Target memory to free: " << target_memory_to_free_kb
                      << " KB";
    if (target_memory_to_free_kb <= 0)
      break;

    // Never kill selected tab and foreground app regardless of whether they're
    // in the active window. Since the user experience would be bad.
    if (candidate.app()) {
      if (candidate.process_type() == ProcessType::FOCUSED_APP) {
        MEMORY_LOG(ERROR) << "Skipped killing focused app "
                          << candidate.app()->process_name();
        continue;
      }
      if (IsRecentlyKilledArcProcess(candidate.app()->process_name(), now)) {
        MEMORY_LOG(ERROR) << "Avoided killing "
                          << candidate.app()->process_name() << " too often";
        continue;
      }
      int estimated_memory_freed_kb =
          mem_stat_->EstimatedMemoryFreedKB(candidate.app()->pid());
      if (KillArcProcess(candidate.app()->nspid())) {
        if (first_kill_time.is_null()) {
          first_kill_time = base::TimeTicks::Now();
        }
        recently_killed_arc_processes_[candidate.app()->process_name()] = now;
        target_memory_to_free_kb -= estimated_memory_freed_kb;
        memory::MemoryKillsMonitor::LogLowMemoryKill("APP",
                                                     estimated_memory_freed_kb);
        MEMORY_LOG(ERROR) << "Killed app " << candidate.app()->process_name()
                          << " (" << candidate.app()->pid() << ")"
                          << ", estimated " << estimated_memory_freed_kb
                          << " KB freed";
      } else {
        MEMORY_LOG(ERROR) << "Failed to kill "
                          << candidate.app()->process_name();
      }
    } else if (candidate.lifecycle_unit()) {
      if (candidate.process_type() == ProcessType::FOCUSED_TAB) {
        MEMORY_LOG(ERROR) << "Skipped killing focused tab (id: "
                          << candidate.lifecycle_unit()->GetID() << ")";
        continue;
      }

      // The estimation is problematic since multiple tabs may share the same
      // process, while the calculation counts memory used by the whole process.
      // So |estimated_memory_freed_kb| is an over-estimation.
      int estimated_memory_freed_kb =
          candidate.lifecycle_unit()->GetEstimatedMemoryFreedOnDiscardKB();
      if (KillTab(candidate.lifecycle_unit(), reason)) {
        if (first_kill_time.is_null()) {
          first_kill_time = base::TimeTicks::Now();
        }
        target_memory_to_free_kb -= estimated_memory_freed_kb;
        memory::MemoryKillsMonitor::LogLowMemoryKill("TAB",
                                                     estimated_memory_freed_kb);
        MEMORY_LOG(ERROR) << "Killed tab (id: "
                          << candidate.lifecycle_unit()->GetID()
                          << "), estimated " << estimated_memory_freed_kb
                          << " KB freed";
      }
    }
  }
  if (target_memory_to_free_kb > 0) {
    MEMORY_LOG(ERROR)
        << "Unable to kill enough candidates to meet target_memory_to_free_kb ";
  }
  if (!first_kill_time.is_null()) {
    base::TimeDelta delta = first_kill_time - start_time;
    MEMORY_LOG(ERROR) << "Time to first kill " << delta;
    UMA_HISTOGRAM_MEDIUM_TIMES("Memory.LowMemoryKiller.FirstKillLatency",
                               delta);
  }

  // tab_discard_done runs when it goes out of the scope.
}

void TabManagerDelegate::AdjustOomPrioritiesImpl(
    OptionalArcProcessList arc_processes) {
  std::vector<TabManagerDelegate::Candidate> candidates;
  std::vector<TabManagerDelegate::Candidate> apps_persistent;

  // Least important first.
  LifecycleUnitVector lifecycle_units = GetLifecycleUnits();
  auto all_candidates =
      GetSortedCandidates(std::move(lifecycle_units), arc_processes);
  for (auto& candidate : all_candidates) {
    // TODO(cylee|yusukes): Consider using IsImportant() instead of
    // IsPersistent() for simplicity.
    // TODO(cylee): Also consider protecting FOCUSED_TAB from the kernel OOM
    // killer so that Chrome and the kernel do the same regarding OOM handling.
    if (candidate.app() && candidate.app()->IsPersistent()) {
      // Add persistent apps to |apps_persistent|.
      apps_persistent.emplace_back(std::move(candidate));
    } else {
      // Add tabs and killable apps to |candidates|.
      candidates.emplace_back(std::move(candidate));
    }
  }

  // Now we assign priorities based on the sorted list. We're assigning
  // priorities in the range of kLowestRendererOomScore to
  // kHighestRendererOomScore (defined in chrome_constants.h). oom_score_adj
  // takes values from -1000 to 1000. Negative values are reserved for system
  // processes, and we want to give some room below the range we're using to
  // allow for things that want to be above the renderers in priority, so the
  // defined range gives us some variation in priority without taking up the
  // whole range. In the end, however, it's a pretty arbitrary range to use.
  // Higher values are more likely to be killed by the OOM killer.

  // Break the processes into 2 parts. This is to help lower the chance of
  // altering OOM score for many processes on any small change.
  int range_middle =
      (content::kLowestRendererOomScore + content::kHighestRendererOomScore) /
      2;

  // Find some pivot point. FOCUSED_TAB, FOCUSED_APP, and PROTECTED_BACKGROUND
  // processes are in the first half and BACKGROUND and CACHED_APP processes
  // are in the second half.
  auto lower_priority_part = candidates.end();
  ProcessType pivot_type = ProcessType::BACKGROUND;
  for (auto it = candidates.begin(); it != candidates.end(); ++it) {
    if (it->process_type() >= pivot_type) {
      lower_priority_part = it;
      break;
    }
  }

  ProcessScoreMap new_map;

  // Make the apps harder to kill.
  DistributeOomScoreInRange(apps_persistent.begin(), apps_persistent.end(),
                            kPersistentArcAppOomScore,
                            kPersistentArcAppOomScore, &new_map);

  // Higher priority part.
  DistributeOomScoreInRange(candidates.begin(), lower_priority_part,
                            content::kLowestRendererOomScore, range_middle,
                            &new_map);
  // Lower priority part.
  DistributeOomScoreInRange(lower_priority_part, candidates.end(), range_middle,
                            content::kHighestRendererOomScore, &new_map);

  oom_score_map_.swap(new_map);
}

void TabManagerDelegate::DistributeOomScoreInRange(
    std::vector<TabManagerDelegate::Candidate>::iterator begin,
    std::vector<TabManagerDelegate::Candidate>::iterator end,
    int range_begin,
    int range_end,
    ProcessScoreMap* new_map) {
  // Processes whose OOM scores should be updated. Ignore duplicated pids but
  // the last occurrence.
  std::map<base::ProcessHandle, int32_t> oom_scores_to_change;

  // Though there might be duplicate process handles, it doesn't matter to
  // overestimate the number of processes here since the we don't need to
  // use up the full range.
  int num = (end - begin);
  const float priority_increment =
      static_cast<float>(range_end - range_begin) / num;

  float priority = range_begin;
  for (auto cur = begin; cur != end; ++cur) {
    const int score = round(priority);

    base::ProcessHandle pid = base::kNullProcessHandle;
    if (cur->app()) {
      pid = cur->app()->pid();
    } else {
      pid = cur->lifecycle_unit()->GetProcessHandle();
      // 1. tab_list contains entries for already-discarded tabs. If the PID
      // (renderer_handle) is zero, we don't need to adjust the oom_score.
      // 2. Only add unseen process handle so if there's multiple tab maps to
      // the same process, the process is set to an OOM score based on its "most
      // important" tab.
      if (pid == base::kNullProcessHandle ||
          new_map->find(pid) != new_map->end())
        continue;
    }

    if (pid == base::kNullProcessHandle)
      continue;

    // Update the to-be-cached OOM score map. Use pid as map keys so it's
    // globally unique.
    (*new_map)[pid] = score;

    // Need to update OOM score if the calculated score is different from
    // current cached score.
    if (oom_score_map_[pid] != score) {
      VLOG(3) << "Update OOM score " << score << " for " << *cur;
      if (cur->app()) {
        oom_scores_to_change[pid] = static_cast<int32_t>(score);
      } else {
        if (!base::AdjustOOMScore(pid, score))
          LOG(ERROR) << "Failed to set oom_score_adj to " << score
                     << " for process " << pid;
      }
    }
    priority += priority_increment;
  }

  if (oom_scores_to_change.size()) {
    GetDebugDaemonClient()->SetOomScoreAdj(oom_scores_to_change,
                                           base::BindOnce(&OnSetOomScoreAdj));
  }
}

}  // namespace resource_coordinator


text:
'use strict';

const _ = require('lodash');
const checkClassStructure = require('./check-class-structure');
let combine = require('./combine');

/*
  Inline CSS function. This is the half-way point until multiple inheritance exists
  @param declaredClasses: Object{ 'class-name': true / false }
  @returns object
*/

module.exports = function(declaredClasses) {
  // What?
  combine = require('./combine');

  const arrayOfStyles = [];

  if (!this.classes) {
    throw console.warn(`Define this.classes on \`${ this.constructor.name }\``);
  }

  // Checks structure and warns if its odd
  checkClassStructure(this.classes());

  const activateClass = (name, options) => {
    if (this.classes()[name]) {
      arrayOfStyles.push(this.classes()[name]);
    } else if (name && options && options.warn === true) {
      console.warn(`The \`${ name }\` css class does not exist on \`${ this.constructor.name }\``);
    }
  };

  activateClass('default');

  for (var prop in this.props) {
    let value = this.props[prop];
    if (!_.isObject(value)) {

      if (value === true) {
        activateClass(prop);
        activateClass(`${ prop }-true`);
      } else if (value) {
        activateClass(`${ prop }-${ value }`);
      } else {
        activateClass(`${ prop }-false`);
      }

    }
  }

  for (var name in declaredClasses) {
    let condition = declaredClasses[name];

    if (condition === true) {
      activateClass(name, { warn: true });
    }
  }

  let customMixins = {};
  if (this.context && this.context.mixins) {
    customMixins = this.context.mixins;
  }

  return combine(arrayOfStyles, customMixins);
};


text:
body {
	background-color: lightpink;
	color: purple;
}

h1 {
	color: white;
	text-decoration-color: purple;
	border: solid darkgrey 10px;
	text-align: center;
	background-color: darkgrey;
}

h2 {
	text-align: center;
	color: white;

}


text:
function SponsorsWindow(navGroup) {
	//load component dependencies
	var ListView = require('ui/common/jobfair/ListView'),
		DetailView = require('ui/common/jobfair/DetailView');

	//create object instance
	var self = Ti.UI.createWindow({
		backgroundImage: 'images/bg_bigTex.png',
		title: 'Sponsors',
		navBarHidden: false
	});

	//construct UI
	var listView = new ListView(0),
		detailView = new DetailView();

	//create list view container
	var listContainerWindow = Ti.UI.createWindow({
		title:'Sponsors'
	});
	self.add(listView);

	//create detail view container
	var detailContainerWindow = Ti.UI.createWindow({
		title:'Sponsor Details',
		backgroundImage: 'images/bg_bigTex.png'
	});
	detailContainerWindow.add(detailView);

	//add behavior for master view
	listView.addEventListener('itemSelected', function(e) {
		detailView.fireEvent('itemSelected',e);
		self.parentTab.open(detailContainerWindow);
	});

	var homeButton = Ti.UI.createButton({
		title: 'Home'
	});
	self.leftNavButton = homeButton;

	homeButton.addEventListener('click', function(){
		navGroup.close(self.tabGroup);
	});

	return self;
}

//make constructor function the public component interface
module.exports = SponsorsWindow;


text:
This three-part tutorial introduces RSpec, one of the most popular (unit) testing frameworks for Ruby.

This third part covers how to apply RSpec to perform integration ("or end-to-end") testing. This style of testing allows us to check whether the various units (e.g., classes) are working together correctly.

The [first part](1_basics.md) of this tutorial covered writing your first RSpec tests, and the [second part](2_doubles.md) covered test doubles.

*Note that this tutorial will not work with the Ruby installation on the CS student lab machines. You can instead use the Vagrant setup for DAMS practicals as discussed at the end of the [Vagrant tutorial](../tools/vagrant.md).*

## Integration testing

Integration tests are high-level tests that are meant to check whether entire pieces of functionality in an application are working correctly. Integration tests normally drive the application via its external interface, such as its graphical-user interface. For example, an integration test might check whether we can log in to an application via its webpages.

Integration tests are complementary to unit tests: we typically need both. Integration tests are more likely to be understandable to the product owner than unit tests. Unit tests are more likely to be useful to developers when designing and maintaining an application than integration tests.

## Integration testing in RSpec

In terms of syntax, an RSpec integration test is very similar to a unit test:

```ruby
feature "Sign in" do
  scenario "works for a valid username and password" do
    # ...
  end
end
```

Note that we use `feature` rather than `describe` and `scenario` rather than `it`. But otherwise, the structure of an integration test is very similar to that of a unit test.

A more important difference, however, is that an integration test uses some mechanism for driving the application via its external interface. For example, if we developing a command-line application, our integration tests would use a Ruby library or language construct for issuing shell commands. On the other hand, if we were developing a web application, our integration tests would drive a (fake) web browser. The rest of this tutorial is concerned with the latter: integration testing web applications.

## Integration testing of web applications with RSpec and Capybara

There are several mechanisms for integration testing a web application with RSpec, including via [Capybara](https://github.com/jnicklas/capybara) gem. Capybara simulates how a real user would interact with your web application.

Let's first take a look at some code that uses Capybara:

```ruby
feature "Sign in" do
  scenario "works for a valid username and password" do
    visit('/signin')
    fill_in('Name', with: 'Joe Bloggs')
    fill_in('Email', with: 'joe@bloggs.com')
    click_on('Sign In')

    expect(page).to have_content('Hello, Joe Bloggs!')
  end
end
```

Capybara provides two sets of useful methods that can be used in RSpec integration tests, *commands* and *matchers*. The commands can be used to simulate a real user visiting our web application in their browser. The test above simulates a user who has:

* Visited the '/signin' page of our web application
* Filled in the value 'Joe Bloggs' into a text field named 'Name'
* Filled in the value 'joe@bloggs.com' into a text field named 'Email'
* Clicked on a button named 'Sign In'

There are many more Capybara commands in addition to `visit`, `fill_in`, and `click_on`: see the [Capybara documentation on 'the DSL'](https://github.com/jnicklas/capybara#the-dsl) for a brief overview and links to complete lists.

Commands are used to setup some state in the web application, and then matchers can be used to make assertions about the current web page. For example, the integration test above will pass only if the current page contains the text "Hello, Joe Bloggs!" somewhere. Some useful Capybara matchers are:

* `expect(page).to have_content(text)` - passes only if the current page contains `text`
* `expect(page).to have_link(title)` - passes only if the current page contains a link named `title`
* `expect(page).to have_link(title, href: target)` - passes only if the current page contains a link named `title` which links to the `target` page
* `expect(current_path).to eq(address)` - passes only if the (fake) web browser is currently at `address`

There are plenty more Capybara matchers: see the [Capybara documentation on querying](https://github.com/jnicklas/capybara#querying) for a brief overview and a link to a complete list.

Q1. Take a look at Flippd's integration tests, starting with those for the [phase](https://github.com/flippd/flippd/blob/master/spec/features/phase_spec.rb) and [video](https://github.com/flippd/flippd/blob/master/spec/features/video_spec.rb) pages. Replicate each of these tests by navigating through the application manually, following the Capybara commands. Which of these tests should pass?

Q2. Suppose Flippd was to be extended such that if a user watched a video to the end, the video page would then display a "watched" label when that user visited the page again in the future. Write down, in plain English, two or three test cases for this functionality.

Q3. Translate your plain English test cases from Q2 to RSpec integration tests that use Capybara. (You may assume that there is a Capybara command called `watch_video` which will simulate playing a video until the end, if we are currently `visit`ing the page for that video).


text:
package org.apache.ibatis.annotations;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.TypeHandler;
import org.apache.ibatis.type.UnknownTypeHandler;

/**
 * @author Clinton Begin
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface TypeDiscriminator {
  String column();

  Class<?> javaType() default void.class;

  JdbcType jdbcType() default JdbcType.UNDEFINED;

  Class<? extends TypeHandler> typeHandler() default UnknownTypeHandler.class;

  Case[] cases();
}


text:
package com.planet_ink.coffee_mud.Abilities.Prayers;
import com.planet_ink.coffee_mud.core.interfaces.*;
import com.planet_ink.coffee_mud.core.*;
import com.planet_ink.coffee_mud.core.collections.*;
import com.planet_ink.coffee_mud.Abilities.interfaces.*;
import com.planet_ink.coffee_mud.Areas.interfaces.*;
import com.planet_ink.coffee_mud.Behaviors.interfaces.*;
import com.planet_ink.coffee_mud.CharClasses.interfaces.*;
import com.planet_ink.coffee_mud.Commands.interfaces.*;
import com.planet_ink.coffee_mud.Common.interfaces.*;
import com.planet_ink.coffee_mud.Exits.interfaces.*;
import com.planet_ink.coffee_mud.Items.interfaces.*;
import com.planet_ink.coffee_mud.Libraries.interfaces.*;
import com.planet_ink.coffee_mud.Locales.interfaces.*;
import com.planet_ink.coffee_mud.MOBS.interfaces.*;
import com.planet_ink.coffee_mud.Races.interfaces.*;

import java.util.*;

@SuppressWarnings("rawtypes")
public class Prayer_PeaceRitual extends Prayer
{
	@Override public String ID() { return "Prayer_PeaceRitual"; }
	private final static String localizedName = CMLib.lang()._("Peace Ritual");
	@Override public String name() { return localizedName; }
	private final static String localizedStaticDisplay = CMLib.lang()._("(Peace Ritual)");
	@Override public String displayText() { return localizedStaticDisplay; }
	@Override public int classificationCode(){return Ability.ACODE_PRAYER|Ability.DOMAIN_NEUTRALIZATION;}
	@Override public int abstractQuality(){ return Ability.QUALITY_OK_SELF;}
	@Override public long flags(){return Ability.FLAG_HOLY;}
	@Override protected int canAffectCode(){return 0;}
	@Override protected int canTargetCode(){return 0;}
	public Clan clan1=null;
	public Clan clan2=null;
	public Iterable<Pair<Clan,Integer>> clan2Set=null;

	@Override
	public boolean tick(Tickable ticking, int tickID)
	{
		if(!(affected instanceof MOB))
			return false;

		if(invoker==null)
			return false;

		final MOB mob=(MOB)affected;
		if(clan2Set==null)
		{
			if(clan2==null)
				return super.tick(ticking, tickID);
			final Vector<Pair<Clan,Integer>> V=new Vector<Pair<Clan,Integer>>();
			V.add(new Pair<Clan,Integer>(clan2,Integer.valueOf(clan2.getGovernment().getAcceptPos())));
			clan2Set=V;
		}
		final List<String> channels=CMLib.channels().getFlaggedChannelNames(ChannelsLibrary.ChannelFlag.CLANINFO);
		for(int i=0;i<channels.size();i++)
			CMLib.commands().postChannel(channels.get(i),clan2Set,mob.name()+" located in '"+mob.location().displayText(mob)+"' is performing a peace ritual on behalf of "+clan1.name()+".",false);
		return super.tick(ticking,tickID);
	}

	@Override
	public boolean okMessage(final Environmental myHost, final CMMsg msg)
	{
		if(!super.okMessage(myHost,msg))
			return false;
		if(affected==null) return true;
		if(!(affected instanceof MOB)) return true;

		if((msg.target()==affected)
		&&(msg.source()!=affected)
		&&(CMath.bset(msg.targetMajor(),CMMsg.MASK_MALICIOUS)))
		{
			msg.source().location().show((MOB)affected,null,CMMsg.MSG_OK_VISUAL,_("The peace ritual is disrupted!"));
			clan1=null;
			clan2=null;
			unInvoke();
		}
		else
		if(msg.amISource((MOB)affected)
		&&((msg.targetMinor()==CMMsg.TYP_ENTER)||(msg.targetMinor()==CMMsg.TYP_LEAVE)))
		{
			msg.source().location().show((MOB)affected,null,CMMsg.MSG_OK_VISUAL,_("The peace ritual is disrupted!"));
			clan1=null;
			clan2=null;
			unInvoke();
		}
		return true;
	}

	@Override
	public void unInvoke()
	{
		// undo the affects of this spell
		if(!(affected instanceof MOB))
			return;
		super.unInvoke();

		if((canBeUninvoked())&&(clan1!=null)&&(clan2!=null))
		{
			final Clan C1=clan1;
			final Clan C2=clan2;
			if((C1!=null)&&(C2!=null))
			{
				if(C1.getClanRelations(C2.clanID())==Clan.REL_WAR)
				{
					C1.setClanRelations(C2.clanID(),Clan.REL_HOSTILE,System.currentTimeMillis());
					C1.update();
				}
				if(C2.getClanRelations(C1.clanID())==Clan.REL_WAR)
				{
					C2.setClanRelations(C1.clanID(),Clan.REL_HOSTILE,System.currentTimeMillis());
					C2.update();
				}
				final List<String> channels=CMLib.channels().getFlaggedChannelNames(ChannelsLibrary.ChannelFlag.CLANINFO);
				for(int i=0;i<channels.size();i++)
					CMLib.commands().postChannel(channels.get(i),CMLib.clans().clanRoles(),"There is now peace between "+C1.name()+" and "+C2.name()+".",false);
			}
		}
	}

	@Override
	public boolean invoke(MOB mob, Vector commands, Physical givenTarget, boolean auto, int asLevel)
	{
		Physical target=mob;
		if((auto)&&(givenTarget!=null)) target=givenTarget;
		if(target.fetchEffect(this.ID())!=null)
		{
			mob.tell(mob,target,null,_("<T-NAME> <T-IS-ARE> already affected by @x1.",name()));
			return false;
		}
		clan1=CMLib.clans().findRivalrousClan(mob);
		if(clan1==null)
		{
			mob.tell(_("You must belong to a clan to use this prayer."));
			return false;
		}
		if(commands.size()<1)
		{
			mob.tell(_("You must specify the clan you wish to see peace with."));
			return false;
		}
		final String clan2Name=CMParms.combine(commands,0);
		clan2=CMLib.clans().findClan(clan2Name);
		if((clan2==null)
		||((clan1.getClanRelations(clan2.clanID())!=Clan.REL_WAR)&&(clan2.getClanRelations(clan1.clanID())!=Clan.REL_WAR)))
		{
			mob.tell(_("Your @x1 is not at war with @x2!",clan1.getGovernmentName(),clan2.name()));
			return false;
		}
		boolean found=false;
		for(final Enumeration e=CMLib.players().players();e.hasMoreElements();)
		{
			final MOB M=(MOB)e.nextElement();
			if(M.getClanRole(clan2.clanID())!=null)
			{ found=true; break;}
		}
		if(!found)
		{
			mob.tell(_("You must wait until a member of @x1 is online before beginning the ritual.",clan2.name()));
			return false;
		}

		if(!super.invoke(mob,commands,givenTarget,auto,asLevel))
			return false;

		final boolean success=proficiencyCheck(mob,0,auto);

		if(success)
		{
			// it worked, so build a copy of this ability,
			// and add it to the affects list of the
			// affected MOB.  Then tell everyone else
			// what happened.
			final CMMsg msg=CMClass.getMsg(mob,target,this,verbalCastCode(mob,target,auto),auto?_("<T-NAME> begin(s) a peace ritual."):_("^S<S-NAME> @x1 for peace between @x2 and @x3.^?",prayWord(mob),clan1.name(),clan2.name()));
			if(mob.location().okMessage(mob,msg))
			{
				mob.location().send(mob,msg);
				beneficialAffect(mob,target,asLevel,(int)CMProps.getTicksPerMinute()*5);
			}
		}
		else
			return beneficialWordsFizzle(mob,null,_("<S-NAME> @x1 for peace between @x2 and @x3, but there is no answer.",prayWord(mob),clan1.name(),clan2.name()));

		// return whether it worked
		return success;
	}
}