Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
e
os
BlissLauncher
Commits
160ab1a2
Commit
160ab1a2
authored
Jul 08, 2021
by
Amit Kumar
💻
Browse files
Add more quickstep related code
parent
0dc03860
Pipeline
#123788
failed with stage
in 1 minute and 51 seconds
Changes
66
Pipelines
1
Expand all
Hide whitespace changes
Inline
Side-by-side
app/build.gradle
View file @
160ab1a2
...
...
@@ -95,6 +95,8 @@ android {
res
.
srcDirs
=
[
'src/apiOreo/res'
]
}
}
addFrameworkJar
(
'framework.jar'
)
}
dependencies
{
...
...
@@ -103,7 +105,7 @@ dependencies {
implementation
'androidx.constraintlayout:constraintlayout:2.0.4'
implementation
"androidx.dynamicanimation:dynamicanimation:1.0.0"
implementation
files
(
'libs/sysui_shared.jar'
)
compileOnly
files
(
'libs/framework.jar'
)
apiNougatImplementation
'org.cyanogenmod:platform.sdk:6.0'
apiOreoImplementation
files
(
'libs/lineage-sdk-oreo.jar'
)
...
...
app/libs/framework.jar
0 → 100644
View file @
160ab1a2
File added
app/src/main/java/foundation/e/blisslauncher/core/Utilities.java
View file @
160ab1a2
...
...
@@ -13,9 +13,12 @@ import android.graphics.Canvas;
import
android.graphics.Matrix
;
import
android.graphics.Paint
;
import
android.graphics.Rect
;
import
android.graphics.RectF
;
import
android.graphics.drawable.BitmapDrawable
;
import
android.graphics.drawable.Drawable
;
import
android.os.Build
;
import
android.os.Handler
;
import
android.os.Message
;
import
android.os.PowerManager
;
import
android.text.TextUtils
;
import
android.util.DisplayMetrics
;
...
...
@@ -69,6 +72,8 @@ public class Utilities {
public
static
final
boolean
ATLEAST_MARSHMALLOW
=
Build
.
VERSION
.
SDK_INT
>=
23
;
public
static
final
int
SINGLE_FRAME_MS
=
16
;
// These values are same as that in {@link AsyncTask}.
private
static
final
int
CPU_COUNT
=
Runtime
.
getRuntime
().
availableProcessors
();
private
static
final
int
CORE_POOL_SIZE
=
CPU_COUNT
+
1
;
...
...
@@ -398,4 +403,26 @@ public class Utilities {
throw
new
RuntimeException
(
e
);
}
}
public
static
void
scaleRectFAboutCenter
(
RectF
r
,
float
scale
)
{
if
(
scale
!=
1.0f
)
{
float
cx
=
r
.
centerX
();
float
cy
=
r
.
centerY
();
r
.
offset
(-
cx
,
-
cy
);
r
.
left
=
r
.
left
*
scale
;
r
.
top
=
r
.
top
*
scale
;
r
.
right
=
r
.
right
*
scale
;
r
.
bottom
=
r
.
bottom
*
scale
;
r
.
offset
(
cx
,
cy
);
}
}
/**
* Utility method to post a runnable on the handler, skipping the synchronization barriers.
*/
public
static
void
postAsyncCallback
(
Handler
handler
,
Runnable
callback
)
{
Message
msg
=
Message
.
obtain
(
handler
,
callback
);
msg
.
setAsynchronous
(
true
);
handler
.
sendMessage
(
msg
);
}
}
app/src/main/java/foundation/e/blisslauncher/core/customviews/InsettableFrameLayout.kt
View file @
160ab1a2
...
...
@@ -15,6 +15,18 @@ open class InsettableFrameLayout(private val mContext: Context, attrs: Attribute
var
windowInsets
:
WindowInsets
?
=
null
val
insets
:
Rect
get
()
{
var
tempInsets
=
Rect
()
if
(
this
.
windowInsets
!=
null
)
{
tempInsets
.
left
=
this
.
windowInsets
!!
.
systemWindowInsetLeft
tempInsets
.
top
=
this
.
windowInsets
!!
.
systemWindowInsetTop
tempInsets
.
right
=
this
.
windowInsets
!!
.
systemWindowInsetRight
tempInsets
.
bottom
=
this
.
windowInsets
!!
.
systemWindowInsetBottom
}
return
tempInsets
}
private
fun
setFrameLayoutChildInsets
(
child
:
View
,
newInsets
:
WindowInsets
?,
oldInsets
:
Rect
)
{
if
(
newInsets
==
null
)
return
val
lp
:
LayoutParams
=
...
...
app/src/main/java/foundation/e/blisslauncher/core/customviews/PagedView.java
View file @
160ab1a2
...
...
@@ -576,7 +576,7 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
final
int
scrollOffsetRight
=
getWidth
()
-
getPaddingRight
()
-
mInsets
.
right
;
boolean
pageScrollChanged
=
false
;
for
(
int
i
=
startIndex
,
childLeft
=
scrollOffsetLeft
;
i
!=
endIndex
;
i
+=
delta
)
{
for
(
int
i
=
startIndex
,
childLeft
=
scrollOffsetLeft
+
offsetForPageScrolls
()
;
i
!=
endIndex
;
i
+=
delta
)
{
final
View
child
=
getPageAt
(
i
);
if
(
scrollLogic
.
shouldIncludeView
(
child
))
{
final
int
childWidth
=
child
.
getMeasuredWidth
();
...
...
@@ -654,6 +654,10 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
return
getPageAt
(
index
).
getLeft
();
}
protected
int
offsetForPageScrolls
()
{
return
0
;
}
@Override
public
boolean
requestChildRectangleOnScreen
(
View
child
,
Rect
rectangle
,
boolean
immediate
)
{
int
page
=
indexToPage
(
indexOfChild
(
child
));
...
...
@@ -1016,6 +1020,10 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
mAllowOverScroll
=
enable
;
}
protected
void
restoreScrollOnLayout
()
{
setCurrentPage
(
getNextPage
());
}
@Override
public
boolean
onTouchEvent
(
MotionEvent
ev
)
{
super
.
onTouchEvent
(
ev
);
...
...
@@ -1398,7 +1406,7 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
return
snapToPage
(
whichPage
,
duration
,
false
);
}
p
rotected
boolean
snapToPage
(
int
whichPage
,
int
duration
,
boolean
immediate
)
{
p
ublic
boolean
snapToPage
(
int
whichPage
,
int
duration
,
boolean
immediate
)
{
whichPage
=
validateNewPage
(
whichPage
);
int
newX
=
getScrollForPage
(
whichPage
);
...
...
@@ -1477,6 +1485,15 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
return
mDownMotionY
;
}
protected
boolean
isPageOrderFlipped
()
{
return
false
;
}
protected
String
getCurrentPageDescription
()
{
return
getContext
().
getString
(
R
.
string
.
default_scroll_format
,
getNextPage
()
+
1
,
getChildCount
());
}
protected
interface
ComputePageScrollsLogic
{
boolean
shouldIncludeView
(
View
view
);
...
...
app/src/main/java/foundation/e/blisslauncher/core/executors/LooperExecutor.java
0 → 100644
View file @
160ab1a2
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
package
foundation.e.blisslauncher.core.executors
;
import
android.os.Handler
;
import
android.os.Looper
;
import
java.util.List
;
import
java.util.concurrent.AbstractExecutorService
;
import
java.util.concurrent.TimeUnit
;
/**
* Extension of {@link AbstractExecutorService} which executed on a provided looper.
*/
public
class
LooperExecutor
extends
AbstractExecutorService
{
private
final
Handler
mHandler
;
public
LooperExecutor
(
Looper
looper
)
{
mHandler
=
new
Handler
(
looper
);
}
public
Handler
getHandler
()
{
return
mHandler
;
}
@Override
public
void
execute
(
Runnable
runnable
)
{
if
(
mHandler
.
getLooper
()
==
Looper
.
myLooper
())
{
runnable
.
run
();
}
else
{
mHandler
.
post
(
runnable
);
}
}
/**
* Not supported and throws an exception when used.
*/
@Override
@Deprecated
public
void
shutdown
()
{
throw
new
UnsupportedOperationException
();
}
/**
* Not supported and throws an exception when used.
*/
@Override
@Deprecated
public
List
<
Runnable
>
shutdownNow
()
{
throw
new
UnsupportedOperationException
();
}
@Override
public
boolean
isShutdown
()
{
return
false
;
}
@Override
public
boolean
isTerminated
()
{
return
false
;
}
/**
* Not supported and throws an exception when used.
*/
@Override
@Deprecated
public
boolean
awaitTermination
(
long
l
,
TimeUnit
timeUnit
)
throws
InterruptedException
{
throw
new
UnsupportedOperationException
();
}
}
app/src/main/java/foundation/e/blisslauncher/core/executors/MainThreadExecutor.java
View file @
160ab1a2
...
...
@@ -8,45 +8,10 @@ import java.util.List;
import
java.util.concurrent.AbstractExecutorService
;
import
java.util.concurrent.TimeUnit
;
public
class
MainThreadExecutor
extends
AbstractExecutorService
{
private
final
Handler
mHandler
;
public
class
MainThreadExecutor
extends
LooperExecutor
{
public
MainThreadExecutor
()
{
mHandler
=
new
Handler
(
Looper
.
getMainLooper
());
}
@Override
public
void
shutdown
()
{
throw
new
UnsupportedOperationException
();
}
@NonNull
@Override
public
List
<
Runnable
>
shutdownNow
()
{
throw
new
UnsupportedOperationException
();
}
@Override
public
boolean
isShutdown
()
{
return
false
;
super
(
Looper
.
getMainLooper
());
}
@Override
public
boolean
isTerminated
()
{
return
false
;
}
@Override
public
boolean
awaitTermination
(
long
timeout
,
@NonNull
TimeUnit
unit
)
throws
InterruptedException
{
throw
new
UnsupportedOperationException
();
}
@Override
public
void
execute
(
@NonNull
Runnable
runnable
)
{
if
(
mHandler
.
getLooper
()
==
Looper
.
myLooper
())
{
runnable
.
run
();
}
else
{
mHandler
.
post
(
runnable
);
}
}
}
app/src/main/java/foundation/e/blisslauncher/core/touch/SwipeDetector.java
0 → 100644
View file @
160ab1a2
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
foundation.e.blisslauncher.core.touch
;
import
android.content.Context
;
import
android.graphics.PointF
;
import
android.util.Log
;
import
android.view.MotionEvent
;
import
android.view.ViewConfiguration
;
import
androidx.annotation.NonNull
;
import
androidx.annotation.VisibleForTesting
;
import
static
android
.
view
.
MotionEvent
.
INVALID_POINTER_ID
;
/**
* One dimensional scroll/drag/swipe gesture detector.
*
* Definition of swipe is different from android system in that this detector handles
* 'swipe to dismiss', 'swiping up/down a container' but also keeps scrolling state before
* swipe action happens
*/
public
class
SwipeDetector
{
private
static
final
boolean
DBG
=
false
;
private
static
final
String
TAG
=
"SwipeDetector"
;
private
int
mScrollConditions
;
public
static
final
int
DIRECTION_POSITIVE
=
1
<<
0
;
public
static
final
int
DIRECTION_NEGATIVE
=
1
<<
1
;
public
static
final
int
DIRECTION_BOTH
=
DIRECTION_NEGATIVE
|
DIRECTION_POSITIVE
;
private
static
final
float
ANIMATION_DURATION
=
1200
;
protected
int
mActivePointerId
=
INVALID_POINTER_ID
;
/**
* The minimum release velocity in pixels per millisecond that triggers fling..
*/
public
static
final
float
RELEASE_VELOCITY_PX_MS
=
1.0f
;
/**
* The time constant used to calculate dampening in the low-pass filter of scroll velocity.
* Cutoff frequency is set at 10 Hz.
*/
public
static
final
float
SCROLL_VELOCITY_DAMPENING_RC
=
1000
f
/
(
2
f
*
(
float
)
Math
.
PI
*
10
);
/* Scroll state, this is set to true during dragging and animation. */
private
ScrollState
mState
=
ScrollState
.
IDLE
;
enum
ScrollState
{
IDLE
,
DRAGGING
,
// onDragStart, onDrag
SETTLING
// onDragEnd
}
public
static
abstract
class
Direction
{
abstract
float
getDisplacement
(
MotionEvent
ev
,
int
pointerIndex
,
PointF
refPoint
);
/**
* Distance in pixels a touch can wander before we think the user is scrolling.
*/
abstract
float
getActiveTouchSlop
(
MotionEvent
ev
,
int
pointerIndex
,
PointF
downPos
);
}
public
static
final
Direction
VERTICAL
=
new
Direction
()
{
@Override
float
getDisplacement
(
MotionEvent
ev
,
int
pointerIndex
,
PointF
refPoint
)
{
return
ev
.
getY
(
pointerIndex
)
-
refPoint
.
y
;
}
@Override
float
getActiveTouchSlop
(
MotionEvent
ev
,
int
pointerIndex
,
PointF
downPos
)
{
return
Math
.
abs
(
ev
.
getX
(
pointerIndex
)
-
downPos
.
x
);
}
};
public
static
final
Direction
HORIZONTAL
=
new
Direction
()
{
@Override
float
getDisplacement
(
MotionEvent
ev
,
int
pointerIndex
,
PointF
refPoint
)
{
return
ev
.
getX
(
pointerIndex
)
-
refPoint
.
x
;
}
@Override
float
getActiveTouchSlop
(
MotionEvent
ev
,
int
pointerIndex
,
PointF
downPos
)
{
return
Math
.
abs
(
ev
.
getY
(
pointerIndex
)
-
downPos
.
y
);
}
};
//------------------- ScrollState transition diagram -----------------------------------
//
// IDLE -> (mDisplacement > mTouchSlop) -> DRAGGING
// DRAGGING -> (MotionEvent#ACTION_UP, MotionEvent#ACTION_CANCEL) -> SETTLING
// SETTLING -> (MotionEvent#ACTION_DOWN) -> DRAGGING
// SETTLING -> (View settled) -> IDLE
private
void
setState
(
ScrollState
newState
)
{
if
(
DBG
)
{
Log
.
d
(
TAG
,
"setState:"
+
mState
+
"->"
+
newState
);
}
// onDragStart and onDragEnd is reported ONLY on state transition
if
(
newState
==
ScrollState
.
DRAGGING
)
{
initializeDragging
();
if
(
mState
==
ScrollState
.
IDLE
)
{
reportDragStart
(
false
/* recatch */
);
}
else
if
(
mState
==
ScrollState
.
SETTLING
)
{
reportDragStart
(
true
/* recatch */
);
}
}
if
(
newState
==
ScrollState
.
SETTLING
)
{
reportDragEnd
();
}
mState
=
newState
;
}
public
boolean
isDraggingOrSettling
()
{
return
mState
==
ScrollState
.
DRAGGING
||
mState
==
ScrollState
.
SETTLING
;
}
/**
* There's no touch and there's no animation.
*/
public
boolean
isIdleState
()
{
return
mState
==
ScrollState
.
IDLE
;
}
public
boolean
isSettlingState
()
{
return
mState
==
ScrollState
.
SETTLING
;
}
public
boolean
isDraggingState
()
{
return
mState
==
ScrollState
.
DRAGGING
;
}
private
final
PointF
mDownPos
=
new
PointF
();
private
final
PointF
mLastPos
=
new
PointF
();
private
Direction
mDir
;
private
final
float
mTouchSlop
;
/* Client of this gesture detector can register a callback. */
private
final
Listener
mListener
;
private
long
mCurrentMillis
;
private
float
mVelocity
;
private
float
mLastDisplacement
;
private
float
mDisplacement
;
private
float
mSubtractDisplacement
;
private
boolean
mIgnoreSlopWhenSettling
;
public
interface
Listener
{
void
onDragStart
(
boolean
start
);
boolean
onDrag
(
float
displacement
,
float
velocity
);
void
onDragEnd
(
float
velocity
,
boolean
fling
);
}
public
SwipeDetector
(
@NonNull
Context
context
,
@NonNull
Listener
l
,
@NonNull
Direction
dir
)
{
this
(
ViewConfiguration
.
get
(
context
).
getScaledTouchSlop
(),
l
,
dir
);
}
@VisibleForTesting
protected
SwipeDetector
(
float
touchSlope
,
@NonNull
Listener
l
,
@NonNull
Direction
dir
)
{
mTouchSlop
=
touchSlope
;
mListener
=
l
;
mDir
=
dir
;
}
public
void
updateDirection
(
Direction
dir
)
{
mDir
=
dir
;
}
public
void
setDetectableScrollConditions
(
int
scrollDirectionFlags
,
boolean
ignoreSlop
)
{
mScrollConditions
=
scrollDirectionFlags
;
mIgnoreSlopWhenSettling
=
ignoreSlop
;
}
public
int
getScrollDirections
()
{
return
mScrollConditions
;
}
private
boolean
shouldScrollStart
(
MotionEvent
ev
,
int
pointerIndex
)
{
// reject cases where the angle or slop condition is not met.
if
(
Math
.
max
(
mDir
.
getActiveTouchSlop
(
ev
,
pointerIndex
,
mDownPos
),
mTouchSlop
)
>
Math
.
abs
(
mDisplacement
))
{
return
false
;
}
// Check if the client is interested in scroll in current direction.
if
(((
mScrollConditions
&
DIRECTION_NEGATIVE
)
>
0
&&
mDisplacement
>
0
)
||
((
mScrollConditions
&
DIRECTION_POSITIVE
)
>
0
&&
mDisplacement
<
0
))
{
return
true
;
}
return
false
;
}
public
boolean
onTouchEvent
(
MotionEvent
ev
)
{
switch
(
ev
.
getActionMasked
())
{
case
MotionEvent
.
ACTION_DOWN
:
mActivePointerId
=
ev
.
getPointerId
(
0
);
mDownPos
.
set
(
ev
.
getX
(),
ev
.
getY
());
mLastPos
.
set
(
mDownPos
);
mLastDisplacement
=
0
;
mDisplacement
=
0
;
mVelocity
=
0
;
if
(
mState
==
ScrollState
.
SETTLING
&&
mIgnoreSlopWhenSettling
)
{
setState
(
ScrollState
.
DRAGGING
);
}
break
;
//case MotionEvent.ACTION_POINTER_DOWN:
case
MotionEvent
.
ACTION_POINTER_UP
:
int
ptrIdx
=
ev
.
getActionIndex
();
int
ptrId
=
ev
.
getPointerId
(
ptrIdx
);
if
(
ptrId
==
mActivePointerId
)
{
final
int
newPointerIdx
=
ptrIdx
==
0
?
1
:
0
;
mDownPos
.
set
(
ev
.
getX
(
newPointerIdx
)
-
(
mLastPos
.
x
-
mDownPos
.
x
),
ev
.
getY
(
newPointerIdx
)
-
(
mLastPos
.
y
-
mDownPos
.
y
));
mLastPos
.
set
(
ev
.
getX
(
newPointerIdx
),
ev
.
getY
(
newPointerIdx
));
mActivePointerId
=
ev
.
getPointerId
(
newPointerIdx
);
}
break
;
case
MotionEvent
.
ACTION_MOVE
:
int
pointerIndex
=
ev
.
findPointerIndex
(
mActivePointerId
);
if
(
pointerIndex
==
INVALID_POINTER_ID
)
{
break
;
}
mDisplacement
=
mDir
.
getDisplacement
(
ev
,
pointerIndex
,
mDownPos
);
computeVelocity
(
mDir
.
getDisplacement
(
ev
,
pointerIndex
,
mLastPos
),
ev
.
getEventTime
());
// handle state and listener calls.
if
(
mState
!=
ScrollState
.
DRAGGING
&&
shouldScrollStart
(
ev
,
pointerIndex
))
{
setState
(
ScrollState
.
DRAGGING
);
}
if
(
mState
==
ScrollState
.
DRAGGING
)
{
reportDragging
();
}
mLastPos
.
set
(
ev
.
getX
(
pointerIndex
),
ev
.
getY
(
pointerIndex
));
break
;
case
MotionEvent
.
ACTION_CANCEL
:
case
MotionEvent
.
ACTION_UP
:
// These are synthetic events and there is no need to update internal values.
if
(
mState
==
ScrollState
.
DRAGGING
)
{
setState
(
ScrollState
.
SETTLING
);
}
break
;
default
:
break
;
}
return
true
;
}
public
void
finishedScrolling
()
{
setState
(
ScrollState
.
IDLE
);
}
private
boolean
reportDragStart
(
boolean
recatch
)
{
mListener
.
onDragStart
(!
recatch
);
if
(
DBG
)
{
Log
.
d
(
TAG
,
"onDragStart recatch:"
+
recatch
);
}
return
true
;
}
private
void
initializeDragging
()
{
if
(
mState
==
ScrollState
.
SETTLING
&&
mIgnoreSlopWhenSettling
)
{
mSubtractDisplacement
=
0
;
}
if
(
mDisplacement
>
0
)
{
mSubtractDisplacement
=
mTouchSlop
;
}
else
{
mSubtractDisplacement
=
-
mTouchSlop
;
}
}
/**
* Returns if the start drag was towards the positive direction or negative.
*
* @see #setDetectableScrollConditions(int, boolean)
* @see #DIRECTION_BOTH