[Galaxy S 5 Android Development (Snapdragon)] txr33:
This is a how to add quick pin unlock and scramble pad to lollipop. It has been tested and working on s5, s6, note 3 and possibly note 4.

This is a guide for people to add it themselves, not for people to upload their files and expect it done for them. It does require the ability to decompile and compile apks and is done with making a toggle for it in custom settings which can be found in this great thread here so it can be toggled on or off depending on what people want to use.

For this mod we will be modifying SystemUI from system/priv-app. It requires 3 files to be modified and 2 to be added which are attached to this post.

Download and extract the attached zip and place the two smali files into

com/android/keyguard/

in the same folder com/android/keyguard/ look for these 3 files which we will need to modify for this.

KeyguardPINView.smali

PasswordTextView.smali

NumPadKey.smali

Lets start with NumPadKey.smali

look for this method which should be near the top

.method public constructor <init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V

and look for the following section of code in that method

iget-object v5, p0, Lcom/android/keyguard/NumPadKey;->mContext:Landroid/content/Context;

sget v6, Lcom/android/keyguard/R$drawable;->lock_ripple_drawable:I

invoke-virtual {v5, v6}, Landroid/content/Context;->getDrawable(I)Landroid/graphics/drawable/Drawable;

above the iget we will add this line

invoke-direct {p0}, Lcom/android/keyguard/NumPadKey;->updateText()V

so it should look something like this

invoke-direct {p0}, Lcom/android/keyguard/NumPadKey;->updateText()V

iget-object v5, p0, Lcom/android/keyguard/NumPadKey;->mContext:Landroid/content/Context;

sget v6, Lcom/android/keyguard/R$drawable;->lock_ripple_drawable:I

invoke-virtual {v5, v6}, Landroid/content/Context;->getDrawable(I)Landroid/graphics/drawable/Drawable;

Now look for the following line

# virtual methods

and add this whole method above it

.method private updateText()V
.locals 4

.prologue
.line 122
iget v2, p0, Lcom/android/keyguard/NumPadKey;->mDigit:I

if-ltz v2, :cond_1

.line 123
iget-object v2, p0, Lcom/android/keyguard/NumPadKey;->mDigitText:Landroid/widget/TextView;

iget v3, p0, Lcom/android/keyguard/NumPadKey;->mDigit:I

invoke-static {v3}, Ljava/lang/Integer;->toString(I)Ljava/lang/String;

move-result-object v3

invoke-virtual {v2, v3}, Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V

.line 124
sget-object v2, Lcom/android/keyguard/NumPadKey;->sKlondike:[Ljava/lang/String;

if-nez v2, :cond_0

.line 125
invoke-virtual {p0}, Lcom/android/keyguard/NumPadKey;->getResources()Landroid/content/res/Resources;

move-result-object v2

sget v3, Lcom/android/keyguard/R$array;->lockscreen_num_pad_klondike:I

invoke-virtual {v2, v3}, Landroid/content/res/Resources;->getStringArray(I)[Ljava/lang/String;

move-result-object v2

sput-object v2, Lcom/android/keyguard/NumPadKey;->sKlondike:[Ljava/lang/String;

.line 127
:cond_0
sget-object v2, Lcom/android/keyguard/NumPadKey;->sKlondike:[Ljava/lang/String;

if-eqz v2, :cond_1

sget-object v2, Lcom/android/keyguard/NumPadKey;->sKlondike:[Ljava/lang/String;

array-length v2, v2

iget v3, p0, Lcom/android/keyguard/NumPadKey;->mDigit:I

if-le v2, v3, :cond_1

.line 128
sget-object v2, Lcom/android/keyguard/NumPadKey;->sKlondike:[Ljava/lang/String;

iget v3, p0, Lcom/android/keyguard/NumPadKey;->mDigit:I

aget-object v0, v2, v3

.line 129
.local v0, "klondike":Ljava/lang/String;
invoke-virtual {v0}, Ljava/lang/String;->length()I

move-result v1

.line 130
.local v1, "len":I
if-lez v1, :cond_2

.line 131
iget-object v2, p0, Lcom/android/keyguard/NumPadKey;->mKlondikeText:Landroid/widget/TextView;

invoke-virtual {v2, v0}, Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V

.line 137
.end local v0 # "klondike":Ljava/lang/String;
.end local v1 # "len":I
:cond_1
:goto_0
return-void

.line 133
.restart local v0 # "klondike":Ljava/lang/String;
.restart local v1 # "len":I
:cond_2
iget-object v2, p0, Lcom/android/keyguard/NumPadKey;->mKlondikeText:Landroid/widget/TextView;

const/4 v3, 0x4

invoke-virtual {v2, v3}, Landroid/widget/TextView;->setVisibility(I)V

goto :goto_0
.end method

Now anywhere under the virtual method line add the following whole method. It can be right at the end of the smali if want, thats where I usually add it

.method public setDigit(I)V
.locals 0
.param p1, "digit" # I

.prologue
.line 117
iput p1, p0, Lcom/android/keyguard/NumPadKey;->mDigit:I

.line 118
invoke-direct {p0}, Lcom/android/keyguard/NumPadKey;->updateText()V

.line 119
return-void
.end method

That it for that smali and move onto the next

so now we will modify PasswordTextView.smali.

at the start of this file you will see

# annotations

To this annotation

.annotation system Ldalvik/annotation/MemberClasses;

we will add the following

Lcom/android/keyguard/PasswordTextView$QuickUnlockListener;

so it will look like this for example. Note some devices may have more values there, do not remove and values just ass the quick unlock listener value

# annotations
.annotation system Ldalvik/annotation/MemberClasses;
value = {
Lcom/android/keyguard/PasswordTextView$CharState;,
Lcom/android/keyguard/PasswordTextView$QuickUnlockListener;
}
.end annotation

now also up the top look for

# instance fields

and add the following field below that

.field protected mQuickUnlockListener:Lcom/android/keyguard/PasswordTextView$QuickUnlockListener;

now find the following method

.method public append(C)V

and in it look for the following section of code

:cond_1
invoke-direct {p0}, Lcom/android/keyguard/PasswordTextView;->userActivity()V

.line 296
const-wide/16 v4, 0x0

invoke-direct {p0, v4, v5}, Lcom/android/keyguard/PasswordTextView;->showAndHideHint(J)V

and add this below it

iget-object v4, p0, Lcom/android/keyguard/PasswordTextView;->mQuickUnlockListener:Lcom/android/keyguard/PasswordTextView$QuickUnlockListener;

if-eqz v4, :cond_next

.line 215
iget-object v4, p0, Lcom/android/keyguard/PasswordTextView;->mQuickUnlockListener:Lcom/android/keyguard/PasswordTextView$QuickUnlockListener;

iget-object v5, p0, Lcom/android/keyguard/PasswordTextView;->mText:Ljava/lang/String;

invoke-interface {v4, v5}, Lcom/android/keyguard/PasswordTextView$QuickUnlockListener;->onValidateQuickUnlock(Ljava/lang/String;)V

:cond_next
return-void

so it looks like this for example

:cond_1
invoke-direct {p0}, Lcom/android/keyguard/PasswordTextView;->userActivity()V

const-wide/16 v4, 0x0

invoke-direct {p0, v4, v5}, Lcom/android/keyguard/PasswordTextView;->showAndHideHint(J)V

iget-object v4, p0, Lcom/android/keyguard/PasswordTextView;->mQuickUnlockListener:Lcom/android/keyguard/PasswordTextView$QuickUnlockListener;

if-eqz v4, :cond_next

iget-object v4, p0, Lcom/android/keyguard/PasswordTextView;->mQuickUnlockListener:Lcom/android/keyguard/PasswordTextView$QuickUnlockListener;

iget-object v5, p0, Lcom/android/keyguard/PasswordTextView;->mText:Ljava/lang/String;

invoke-interface {v4, v5}, Lcom/android/keyguard/PasswordTextView$QuickUnlockListener;->onValidateQuickUnlock(Ljava/lang/String;)V

:cond_next

return-void

goto :goto_0

.end local v0 # "charState":Lcom/android/keyguard/PasswordTextView$CharState;
:cond_2
iget-object v4, p0, Lcom/android/keyguard/PasswordTextView;->mTextChars:Ljava/util/ArrayList;

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

invoke-virtual {v4, v5}, Ljava/util/ArrayList;->get(I)Ljava/lang/Object;

then at the end of the smali add this whole method

.method public setQuickUnlockListener(Lcom/android/keyguard/PasswordTextView$QuickUnlockListener;)V
.locals 0
.param p1, "listener" # Lcom/android/keyguard/PasswordTextView$QuickUnlockListener;

.prologue
.line 101
iput-object p1, p0, Lcom/android/keyguard/PasswordTextView;->mQuickUnlockListener:Lcom/android/keyguard/PasswordTextView$QuickUnlockListener;

.line 102
return-void
.end method

Now we move on to the final smali KeyguardPINView.smali

look for this at the top

# static fields

and add the following field

.field private static sNumbers:Ljava/util/List;
.annotation system Ldalvik/annotation/Signature;
value = {
"Ljava/util/List",
"<",
"Ljava/lang/Integer;",
">;"
}
.end annotation
.end field

also under this line

# instance fields

you may need to add the following line if it is not present already. It already exists on s5 and note 3 but needs to be added for s6. So if it is not there then add it

.field private mDivider:Landroid/view/View;

now look for

# direct methods

which should be not far from the above added lines and add the following constructor method

.method static constructor <clinit>()V
.locals 7

.prologue
const/4 v6, 0x4

const/4 v5, 0x3

const/4 v4, 0x2

const/4 v2, 0x1

const/4 v3, 0x0

.line 48
const/16 v0, 0xa

new-array v0, v0, [Ljava/lang/Integer;

invoke-static {v2}, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;

move-result-object v1

aput-object v1, v0, v3

invoke-static {v4}, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;

move-result-object v1

aput-object v1, v0, v2

invoke-static {v5}, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;

move-result-object v1

aput-object v1, v0, v4

invoke-static {v6}, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;

move-result-object v1

aput-object v1, v0, v5

const/4 v1, 0x5

invoke-static {v1}, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;

move-result-object v1

aput-object v1, v0, v6

const/4 v1, 0x5

const/4 v2, 0x6

invoke-static {v2}, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;

move-result-object v2

aput-object v2, v0, v1

const/4 v1, 0x6

const/4 v2, 0x7

invoke-static {v2}, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;

move-result-object v2

aput-object v2, v0, v1

const/4 v1, 0x7

const/16 v2, 0x8

invoke-static {v2}, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;

move-result-object v2

aput-object v2, v0, v1

const/16 v1, 0x8

const/16 v2, 0x9

invoke-static {v2}, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;

move-result-object v2

aput-object v2, v0, v1

const/16 v1, 0x9

invoke-static {v3}, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;

move-result-object v2

aput-object v2, v0, v1

invoke-static {v0}, Ljava/util/Arrays;->asList([Ljava/lang/Object;)Ljava/util/List;

move-result-object v0

sput-object v0, Lcom/android/keyguard/KeyguardPINView;->sNumbers:Ljava/util/List;

return-void
.end method

look for this access

.method static synthetic access$000(Lcom/android/keyguard/KeyguardPINView;Z)V

and add the following two methods below that method

.method static synthetic access$100(Lcom/android/keyguard/KeyguardPINView;Ljava/lang/String;)V
.locals 0
.param p0, "x0" # Lcom/android/keyguard/KeyguardPINView;
.param p1, "x1" # Ljava/lang/String;

.prologue
.line 37
invoke-direct {p0, p1}, Lcom/android/keyguard/KeyguardPINView;->validateQuickUnlock(Ljava/lang/String;)V

return-void
.end method

.method private validateQuickUnlock(Ljava/lang/String;)V
.locals 3
.param p1, "password" # Ljava/lang/String;

.prologue
const/4 v2, 0x1

.line 198
if-eqz p1, :cond_0

.line 199
invoke-virtual {p1}, Ljava/lang/String;->length()I

move-result v0

const/4 v1, 0x3

if-le v0, v1, :cond_0

iget-object v0, p0, Lcom/android/keyguard/KeyguardPINView;->mLockPatternUtils:Lcom/android/internal/widget/LockPatternUtils;

invoke-virtual {v0, p1}, Lcom/android/internal/widget/LockPatternUtils;->checkPassword(Ljava/lang/String;)Z

move-result v0

if-eqz v0, :cond_0

.line 201
iget-object v0, p0, Lcom/android/keyguard/KeyguardPINView;->mCallback:Lcom/android/keyguard/KeyguardSecurityCallback;

invoke-interface {v0, v2}, Lcom/android/keyguard/KeyguardSecurityCallback;->reportUnlockAttempt(Z)V

.line 202
iget-object v0, p0, Lcom/android/keyguard/KeyguardPINView;->mCallback:Lcom/android/keyguard/KeyguardSecurityCallback;

invoke-interface {v0, v2}, Lcom/android/keyguard/KeyguardSecurityCallback;->dismiss(Z)V

.line 203
invoke-virtual {p0, v2}, Lcom/android/keyguard/KeyguardPINView;->resetPasswordText(Z)V

.line 206
:cond_0
return-void
.end method

now look for this method

.method protected onFinishInflate()V

and replace the whole method with this one

.method protected onFinishInflate()V
.locals 12

.prologue
const/4 v9, 0x1

const/4 v10, 0x0

.line 77
invoke-super {p0}, Lcom/android/keyguard/KeyguardPinBasedInputView;->onFinishInflate()V

.line 78
sget v8, Lcom/android/keyguard/R$id;->keyguard_bouncer_frame:I

invoke-virtual {p0, v8}, Lcom/android/keyguard/KeyguardPINView;->findViewById(I)Landroid/view/View;

move-result-object v8

check-cast v8, Landroid/view/ViewGroup;

iput-object v8, p0, Lcom/android/keyguard/KeyguardPINView;->mKeyguardBouncerFrame:Landroid/view/ViewGroup;

.line 79
sget v8, Lcom/android/keyguard/R$id;->row0:I

invoke-virtual {p0, v8}, Lcom/android/keyguard/KeyguardPINView;->findViewById(I)Landroid/view/View;

move-result-object v8

check-cast v8, Landroid/view/ViewGroup;

iput-object v8, p0, Lcom/android/keyguard/KeyguardPINView;->mRow0:Landroid/view/ViewGroup;

.line 80
sget v8, Lcom/android/keyguard/R$id;->row1:I

invoke-virtual {p0, v8}, Lcom/android/keyguard/KeyguardPINView;->findViewById(I)Landroid/view/View;

move-result-object v8

check-cast v8, Landroid/view/ViewGroup;

iput-object v8, p0, Lcom/android/keyguard/KeyguardPINView;->mRow1:Landroid/view/ViewGroup;

.line 81
sget v8, Lcom/android/keyguard/R$id;->row2:I

invoke-virtual {p0, v8}, Lcom/android/keyguard/KeyguardPINView;->findViewById(I)Landroid/view/View;

move-result-object v8

check-cast v8, Landroid/view/ViewGroup;

iput-object v8, p0, Lcom/android/keyguard/KeyguardPINView;->mRow2:Landroid/view/ViewGroup;

.line 82
sget v8, Lcom/android/keyguard/R$id;->row3:I

invoke-virtual {p0, v8}, Lcom/android/keyguard/KeyguardPINView;->findViewById(I)Landroid/view/View;

move-result-object v8

check-cast v8, Landroid/view/ViewGroup;

iput-object v8, p0, Lcom/android/keyguard/KeyguardPINView;->mRow3:Landroid/view/ViewGroup;

.line 83
sget v8, Lcom/android/keyguard/R$id;->divider:I

invoke-virtual {p0, v8}, Lcom/android/keyguard/KeyguardPINView;->findViewById(I)Landroid/view/View;

move-result-object v8

iput-object v8, p0, Lcom/android/keyguard/KeyguardPINView;->mDivider:Landroid/view/View;

.line 85
invoke-virtual {p0}, Lcom/android/keyguard/KeyguardPINView;->getContext()Landroid/content/Context;

move-result-object v8

invoke-virtual {v8}, Landroid/content/Context;->getContentResolver()Landroid/content/ContentResolver;

move-result-object v8

const-string v11, "lockscreen_quick_unlock_control"

invoke-static {v8, v11, v10}, Landroid/provider/Settings$System;->getInt(Landroid/content/ContentResolver;Ljava/lang/String;I)I

move-result v8

if-ne v8, v9, :cond_1

move v4, v9

.line 88
.local v4, "quickUnlock":Z
:goto_0
invoke-virtual {p0}, Lcom/android/keyguard/KeyguardPINView;->getContext()Landroid/content/Context;

move-result-object v8

invoke-virtual {v8}, Landroid/content/Context;->getContentResolver()Landroid/content/ContentResolver;

move-result-object v8

const-string v11, "lockscreen_scramble_pin_layout"

invoke-static {v8, v11, v10}, Landroid/provider/Settings$System;->getInt(Landroid/content/ContentResolver;Ljava/lang/String;I)I

move-result v8

if-ne v8, v9, :cond_2

move v5, v9

.line 91

.local v5, "scramblePin":Z
:goto_1
if-eqz v5, :cond_5

.line 92
sget-object v8, Lcom/android/keyguard/KeyguardPINView;->sNumbers:Ljava/util/List;

invoke-static {v8}, Ljava/util/Collections;->shuffle(Ljava/util/List;)V

.line 94
sget v8, Lcom/android/keyguard/R$id;->keyguard_bouncer_frame:I

invoke-virtual {p0, v8}, Lcom/android/keyguard/KeyguardPINView;->findViewById(I)Landroid/view/View;

move-result-object v0

check-cast v0, Landroid/widget/LinearLayout;

.line 95
.local v0, "bouncer":Landroid/widget/LinearLayout;
new-instance v7, Ljava/util/ArrayList;

invoke-direct {v7}, Ljava/util/ArrayList;-><init>()V

.line 96
.local v7, "views":Ljava/util/List;, "Ljava/util/List<Lcom/android/keyguard/NumPadKey;>;"
const/4 v1, 0x0

.local v1, "i":I
:goto_2
invoke-virtual {v0}, Landroid/widget/LinearLayout;->getChildCount()I

move-result v8

if-ge v1, v8, :cond_4

.line 97
invoke-virtual {v0, v1}, Landroid/widget/LinearLayout;->getChildAt(I)Landroid/view/View;

move-result-object v8

instance-of v8, v8, Landroid/widget/LinearLayout;

if-eqz v8, :cond_3

.line 98
invoke-virtual {v0, v1}, Landroid/widget/LinearLayout;->getChildAt(I)Landroid/view/View;

move-result-object v3

check-cast v3, Landroid/widget/LinearLayout;

.line 99
.local v3, "nestedLayout":Landroid/widget/LinearLayout;
const/4 v2, 0x0

.local v2, "j":I
:goto_3
invoke-virtual {v3}, Landroid/widget/LinearLayout;->getChildCount()I

move-result v8

if-ge v2, v8, :cond_3

.line 100
invoke-virtual {v3, v2}, Landroid/widget/LinearLayout;->getChildAt(I)Landroid/view/View;

move-result-object v6

.line 101
.local v6, "view":Landroid/view/View;
invoke-virtual {v6}, Ljava/lang/Object;->getClass()Ljava/lang/Class;

move-result-object v8

const-class v9, Lcom/android/keyguard/NumPadKey;

if-ne v8, v9, :cond_0

.line 102
check-cast v6, Lcom/android/keyguard/NumPadKey;

.end local v6 # "view":Landroid/view/View;
invoke-interface {v7, v6}, Ljava/util/List;->add(Ljava/lang/Object;)Z

.line 99
:cond_0
add-int/lit8 v2, v2, 0x1

goto :goto_3

.end local v0 # "bouncer":Landroid/widget/LinearLayout;
.end local v1 # "i":I
.end local v2 # "j":I
.end local v3 # "nestedLayout":Landroid/widget/LinearLayout;
.end local v4 # "quickUnlock":Z
.end local v5 # "scramblePin":Z
.end local v7 # "views":Ljava/util/List;, "Ljava/util/List<Lcom/android/keyguard/NumPadKey;>;"
:cond_1
move v4, v10

.line 85
goto :goto_0

.restart local v4 # "quickUnlock":Z
:cond_2
move v5, v10

.line 88
goto :goto_1

.line 96
.restart local v0 # "bouncer":Landroid/widget/LinearLayout;
.restart local v1 # "i":I
.restart local v5 # "scramblePin":Z
.restart local v7 # "views":Ljava/util/List;, "Ljava/util/List<Lcom/android/keyguard/NumPadKey;>;"
:cond_3
add-int/lit8 v1, v1, 0x1

goto :goto_2

.line 109
:cond_4
const/4 v1, 0x0

:goto_4
sget-object v8, Lcom/android/keyguard/KeyguardPINView;->sNumbers:Ljava/util/List;

invoke-interface {v8}, Ljava/util/List;->size()I

move-result v8

if-ge v1, v8, :cond_5

.line 110
invoke-interface {v7, v1}, Ljava/util/List;->get(I)Ljava/lang/Object;

move-result-object v6

check-cast v6, Lcom/android/keyguard/NumPadKey;

.line 111
.local v6, "view":Lcom/android/keyguard/NumPadKey;
sget-object v8, Lcom/android/keyguard/KeyguardPINView;->sNumbers:Ljava/util/List;

invoke-interface {v8, v1}, Ljava/util/List;->get(I)Ljava/lang/Object;

move-result-object v8

check-cast v8, Ljava/lang/Integer;

invoke-virtual {v8}, Ljava/lang/Integer;->intValue()I

move-result v8

invoke-virtual {v6, v8}, Lcom/android/keyguard/NumPadKey;->setDigit(I)V

.line 109
add-int/lit8 v1, v1, 0x1

goto :goto_4

.line 115
.end local v0 # "bouncer":Landroid/widget/LinearLayout;
.end local v1 # "i":I
.end local v6 # "view":Lcom/android/keyguard/NumPadKey;
.end local v7 # "views":Ljava/util/List;, "Ljava/util/List<Lcom/android/keyguard/NumPadKey;>;"
:cond_5
if-eqz v4, :cond_6

.line 116
iget-object v8, p0, Lcom/android/keyguard/KeyguardPINView;->mPasswordEntry:Lcom/android/keyguard/PasswordTextView;

new-instance v9, Lcom/android/keyguard/KeyguardPINView$2;

invoke-direct {v9, p0}, Lcom/android/keyguard/KeyguardPINView$2;-><init>(Lcom/android/keyguard/KeyguardPINView;)V

invoke-virtual {v8, v9}, Lcom/android/keyguard/PasswordTextView;->setQuickUnlockListener(Lcom/android/keyguard/PasswordTextView$QuickUnlockListener;)V

.line 124
:goto_5
return-void

.line 122
:cond_6
iget-object v8, p0, Lcom/android/keyguard/KeyguardPINView;->mPasswordEntry:Lcom/android/keyguard/PasswordTextView;

const/4 v9, 0x0

invoke-virtual {v8, v9}, Lcom/android/keyguard/PasswordTextView;->setQuickUnlockListener(Lcom/android/keyguard/PasswordTextView$QuickUnlockListener;)V

goto :goto_5
.end method

Thats all we need to do for the modifications all that is left now is add the following keys to custom settings to toggle them on and off

<CheckBoxPreference android:title="Quick Unlock" android:key="lockscreen_quick_unlock_control" android:summaryOn="Enabled" android:summaryOff="Disabled" />
<CheckBoxPreference android:title="Pin Pad Scramble" android:key="lockscreen_scramble_pin_layout" android:summaryOn="Enabled" android:summaryOff="Disabled" />

Thats it.

If you use this in your rom please give credits.

An example of what scramble pad is, is attached to this post