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
0dc03860
Commit
0dc03860
authored
Jul 08, 2021
by
Amit Kumar
💻
Browse files
Add recent tasks related stuff
parent
8e3241f7
Pipeline
#123767
failed with stage
in 2 minutes and 1 second
Changes
19
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
app/build.gradle
View file @
0dc03860
...
...
@@ -102,11 +102,10 @@ dependencies {
implementation
'androidx.appcompat:appcompat:1.2.0'
implementation
'androidx.constraintlayout:constraintlayout:2.0.4'
implementation
"androidx.dynamicanimation:dynamicanimation:1.0.0"
implementation
files
(
'libs/sysui_shared.jar'
)
apiNougatImplementation
'org.cyanogenmod:platform.sdk:6.0'
apiOreoImplementation
files
(
'libs/lineage-sdk-oreo.jar'
)
implementation
files
(
'libs/sysui_shared.jar'
)
debugImplementation
'com.amitshekhar.android:debug-db:1.0.4'
...
...
app/src/main/java/foundation/e/blisslauncher/core/Utilities.java
View file @
0dc03860
...
...
@@ -26,6 +26,7 @@ import android.view.ViewGroup;
import
java.io.ByteArrayOutputStream
;
import
java.io.IOException
;
import
java.lang.reflect.InvocationTargetException
;
import
java.lang.reflect.Method
;
import
java.text.SimpleDateFormat
;
import
java.util.ArrayList
;
...
...
@@ -378,4 +379,23 @@ public class Utilities {
PowerManager
powerManager
=
(
PowerManager
)
context
.
getSystemService
(
Context
.
POWER_SERVICE
);
return
powerManager
.
isPowerSaveMode
();
}
public
static
<
T
>
T
getOverrideObject
(
Class
<
T
>
clazz
,
Context
context
,
int
resId
)
{
String
className
=
context
.
getString
(
resId
);
if
(!
TextUtils
.
isEmpty
(
className
))
{
try
{
Class
<?>
cls
=
Class
.
forName
(
className
);
return
(
T
)
cls
.
getDeclaredConstructor
(
Context
.
class
).
newInstance
(
context
);
}
catch
(
ClassNotFoundException
|
InstantiationException
|
IllegalAccessException
|
ClassCastException
|
NoSuchMethodException
|
InvocationTargetException
e
)
{
Log
.
e
(
TAG
,
"Bad overriden class"
,
e
);
}
}
try
{
return
clazz
.
newInstance
();
}
catch
(
InstantiationException
|
IllegalAccessException
e
)
{
throw
new
RuntimeException
(
e
);
}
}
}
app/src/main/java/foundation/e/blisslauncher/core/utils/PackageManagerHelper.java
0 → 100644
View file @
0dc03860
/*
* Copyright (C) 2016 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.utils
;
import
android.app.AppOpsManager
;
import
android.content.ActivityNotFoundException
;
import
android.content.ComponentName
;
import
android.content.Context
;
import
android.content.Intent
;
import
android.content.pm.ApplicationInfo
;
import
android.content.pm.LauncherActivityInfo
;
import
android.content.pm.LauncherApps
;
import
android.content.pm.PackageManager
;
import
android.content.pm.PackageManager.NameNotFoundException
;
import
android.content.pm.ResolveInfo
;
import
android.graphics.Rect
;
import
android.net.Uri
;
import
android.os.Build
;
import
android.os.Bundle
;
import
android.os.UserHandle
;
import
android.text.TextUtils
;
import
android.util.Log
;
import
android.widget.Toast
;
import
java.net.URISyntaxException
;
import
java.util.List
;
import
foundation.e.blisslauncher.R
;
import
foundation.e.blisslauncher.core.Utilities
;
import
foundation.e.blisslauncher.core.database.model.ApplicationItem
;
import
foundation.e.blisslauncher.core.database.model.LauncherItem
;
import
foundation.e.blisslauncher.core.database.model.ShortcutItem
;
/**
* Utility methods using package manager
*/
public
class
PackageManagerHelper
{
private
static
final
String
TAG
=
"PackageManagerHelper"
;
private
final
Context
mContext
;
private
final
PackageManager
mPm
;
private
final
LauncherApps
mLauncherApps
;
public
PackageManagerHelper
(
Context
context
)
{
mContext
=
context
;
mPm
=
context
.
getPackageManager
();
mLauncherApps
=
(
LauncherApps
)
context
.
getSystemService
(
Context
.
LAUNCHER_APPS_SERVICE
);
}
/**
* Returns true if the app can possibly be on the SDCard. This is just a workaround and doesn't
* guarantee that the app is on SD card.
*/
public
boolean
isAppOnSdcard
(
String
packageName
,
UserHandle
user
)
{
ApplicationInfo
info
=
null
;
try
{
info
=
mLauncherApps
.
getApplicationInfo
(
packageName
,
PackageManager
.
MATCH_UNINSTALLED_PACKAGES
,
user
);
return
info
!=
null
&&
info
.
enabled
&&
((
info
.
flags
&
ApplicationInfo
.
FLAG_INSTALLED
)
!=
0
)
&&
(
info
.
flags
&
ApplicationInfo
.
FLAG_EXTERNAL_STORAGE
)
!=
0
;
}
catch
(
NameNotFoundException
e
)
{
e
.
printStackTrace
();
return
false
;
}
}
/**
* Returns whether the target app is suspended for a given user as per
* {@link android.app.admin.DevicePolicyManager#isPackageSuspended}.
*/
public
boolean
isAppSuspended
(
String
packageName
,
UserHandle
user
)
{
ApplicationInfo
info
=
null
;
try
{
info
=
mLauncherApps
.
getApplicationInfo
(
packageName
,
0
,
user
);
}
catch
(
NameNotFoundException
e
)
{
e
.
printStackTrace
();
}
return
info
!=
null
&&
info
.
enabled
&&
((
info
.
flags
&
ApplicationInfo
.
FLAG_INSTALLED
)
!=
0
)
&&
isAppSuspended
(
info
);
}
public
boolean
isSafeMode
()
{
return
mContext
.
getPackageManager
().
isSafeMode
();
}
public
Intent
getAppLaunchIntent
(
String
pkg
,
UserHandle
user
)
{
List
<
LauncherActivityInfo
>
activities
=
mLauncherApps
.
getActivityList
(
pkg
,
user
);
return
activities
.
isEmpty
()
?
null
:
ApplicationItem
.
makeLaunchIntent
(
activities
.
get
(
0
));
}
/**
* Returns whether an application is suspended as per
* {@link android.app.admin.DevicePolicyManager#isPackageSuspended}.
*/
public
static
boolean
isAppSuspended
(
ApplicationInfo
info
)
{
// The value of FLAG_SUSPENDED was reused by a hidden constant
// ApplicationInfo.FLAG_PRIVILEGED prior to N, so only check for suspended flag on N
// or later.
if
(
Utilities
.
ATLEAST_NOUGAT
)
{
return
(
info
.
flags
&
ApplicationInfo
.
FLAG_SUSPENDED
)
!=
0
;
}
else
{
return
false
;
}
}
/**
* Returns true if {@param srcPackage} has the permission required to start the activity from
* {@param intent}. If {@param srcPackage} is null, then the activity should not need
* any permissions
*/
public
boolean
hasPermissionForActivity
(
Intent
intent
,
String
srcPackage
)
{
ResolveInfo
target
=
mPm
.
resolveActivity
(
intent
,
0
);
if
(
target
==
null
)
{
// Not a valid target
return
false
;
}
if
(
TextUtils
.
isEmpty
(
target
.
activityInfo
.
permission
))
{
// No permission is needed
return
true
;
}
if
(
TextUtils
.
isEmpty
(
srcPackage
))
{
// The activity requires some permission but there is no source.
return
false
;
}
// Source does not have sufficient permissions.
if
(
mPm
.
checkPermission
(
target
.
activityInfo
.
permission
,
srcPackage
)
!=
PackageManager
.
PERMISSION_GRANTED
)
{
return
false
;
}
if
(!
Utilities
.
ATLEAST_MARSHMALLOW
)
{
// These checks are sufficient for below M devices.
return
true
;
}
// On M and above also check AppOpsManager for compatibility mode permissions.
if
(
TextUtils
.
isEmpty
(
AppOpsManager
.
permissionToOp
(
target
.
activityInfo
.
permission
)))
{
// There is no app-op for this permission, which could have been disabled.
return
true
;
}
// There is no direct way to check if the app-op is allowed for a particular app. Since
// app-op is only enabled for apps running in compatibility mode, simply block such apps.
try
{
return
mPm
.
getApplicationInfo
(
srcPackage
,
0
).
targetSdkVersion
>=
Build
.
VERSION_CODES
.
M
;
}
catch
(
NameNotFoundException
e
)
{
}
return
false
;
}
/**
* Starts the details activity for {@code info}
*/
public
void
startDetailsActivityForInfo
(
LauncherItem
info
,
Rect
sourceBounds
,
Bundle
opts
)
{
ComponentName
componentName
=
null
;
if
(
info
instanceof
ApplicationItem
)
{
componentName
=
((
ApplicationItem
)
info
).
componentName
;
}
else
if
(
info
instanceof
ShortcutItem
)
{
componentName
=
info
.
getTargetComponent
();
}
if
(
componentName
!=
null
)
{
try
{
mLauncherApps
.
startAppDetailsActivity
(
componentName
,
info
.
user
.
getRealHandle
(),
sourceBounds
,
opts
);
}
catch
(
SecurityException
|
ActivityNotFoundException
e
)
{
Toast
.
makeText
(
mContext
,
R
.
string
.
activity_not_found
,
Toast
.
LENGTH_SHORT
).
show
();
Log
.
e
(
TAG
,
"Unable to launch settings"
,
e
);
}
}
}
}
app/src/main/java/foundation/e/blisslauncher/features/quickstep/ActivityControlHelper.java
View file @
0dc03860
...
...
@@ -546,7 +546,7 @@ public interface ActivityControlHelper<T extends BaseDraggingActivity> {
void
open
();
void
setHandler
(
com
.
android
.
quickstep
.
WindowTransformSwipeHandler
handler
);
void
setHandler
(
WindowTransformSwipeHandler
handler
);
void
finish
();
}
...
...
app/src/main/java/foundation/e/blisslauncher/features/quickstep/ScrimView.java
deleted
100644 → 0
View file @
8e3241f7
/*
* Copyright (C) 2018 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.features.quickstep
;
import
android.animation.Animator
;
import
android.animation.AnimatorListenerAdapter
;
import
android.animation.Keyframe
;
import
android.animation.ObjectAnimator
;
import
android.animation.PropertyValuesHolder
;
import
android.animation.RectEvaluator
;
import
android.content.Context
;
import
android.graphics.Canvas
;
import
android.graphics.Color
;
import
android.graphics.Rect
;
import
android.graphics.RectF
;
import
android.graphics.drawable.Drawable
;
import
android.os.Bundle
;
import
android.util.AttributeSet
;
import
android.util.Property
;
import
android.view.KeyEvent
;
import
android.view.MotionEvent
;
import
android.view.View
;
import
android.view.accessibility.AccessibilityManager
;
import
android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener
;
import
androidx.annotation.NonNull
;
import
androidx.annotation.Nullable
;
import
androidx.core.view.ViewCompat
;
import
java.util.List
;
import
foundation.e.blisslauncher.R
;
import
foundation.e.blisslauncher.core.customviews.Insettable
;
import
static
android
.
content
.
Context
.
ACCESSIBILITY_SERVICE
;
import
static
android
.
view
.
MotionEvent
.
ACTION_DOWN
;
/**
* Simple scrim which draws a flat color
*/
public
class
ScrimView
extends
View
implements
Insettable
,
AccessibilityStateChangeListener
,
StateListener
{
public
static
final
Property
<
ScrimView
,
Integer
>
DRAG_HANDLE_ALPHA
=
new
Property
<
ScrimView
,
Integer
>(
Integer
.
TYPE
,
"dragHandleAlpha"
)
{
@Override
public
Integer
get
(
ScrimView
scrimView
)
{
return
scrimView
.
mDragHandleAlpha
;
}
@Override
public
void
set
(
ScrimView
scrimView
,
Integer
value
)
{
scrimView
.
setDragHandleAlpha
(
value
);
}
};
private
static
final
int
WALLPAPERS
=
R
.
string
.
wallpaper_button_text
;
private
static
final
int
WIDGETS
=
R
.
string
.
widget_button_text
;
private
static
final
int
SETTINGS
=
R
.
string
.
settings_button_text
;
private
final
Rect
mTempRect
=
new
Rect
();
private
final
int
[]
mTempPos
=
new
int
[
2
];
protected
final
Launcher
mLauncher
;
private
final
AccessibilityManager
mAM
;
protected
final
int
mEndScrim
;
protected
float
mMaxScrimAlpha
;
protected
float
mProgress
=
1
;
protected
int
mScrimColor
;
protected
int
mCurrentFlatColor
;
protected
int
mEndFlatColor
;
protected
int
mEndFlatColorAlpha
;
protected
final
int
mDragHandleSize
;
private
final
Rect
mDragHandleBounds
;
private
final
RectF
mHitRect
=
new
RectF
();
private
final
AccessibilityHelper
mAccessibilityHelper
;
@Nullable
protected
Drawable
mDragHandle
;
private
int
mDragHandleAlpha
=
255
;
public
ScrimView
(
Context
context
,
AttributeSet
attrs
)
{
super
(
context
,
attrs
);
mLauncher
=
Launcher
.
getLauncher
(
context
);
mWallpaperColorInfo
=
WallpaperColorInfo
.
getInstance
(
context
);
mEndScrim
=
Themes
.
getAttrColor
(
context
,
R
.
attr
.
allAppsScrimColor
);
mMaxScrimAlpha
=
0.7f
;
mDragHandleSize
=
context
.
getResources
()
.
getDimensionPixelSize
(
R
.
dimen
.
vertical_drag_handle_size
);
mDragHandleBounds
=
new
Rect
(
0
,
0
,
mDragHandleSize
,
mDragHandleSize
);
mAccessibilityHelper
=
createAccessibilityHelper
();
ViewCompat
.
setAccessibilityDelegate
(
this
,
mAccessibilityHelper
);
mAM
=
(
AccessibilityManager
)
context
.
getSystemService
(
ACCESSIBILITY_SERVICE
);
setFocusable
(
false
);
}
@NonNull
protected
AccessibilityHelper
createAccessibilityHelper
()
{
return
new
AccessibilityHelper
();
}
@Override
public
void
setInsets
(
Rect
insets
)
{
updateDragHandleBounds
();
updateDragHandleVisibility
(
null
);
}
@Override
protected
void
onMeasure
(
int
widthMeasureSpec
,
int
heightMeasureSpec
)
{
super
.
onMeasure
(
widthMeasureSpec
,
heightMeasureSpec
);
updateDragHandleBounds
();
}
@Override
protected
void
onAttachedToWindow
()
{
super
.
onAttachedToWindow
();
mAM
.
addAccessibilityStateChangeListener
(
this
);
onAccessibilityStateChanged
(
mAM
.
isEnabled
());
}
@Override
protected
void
onDetachedFromWindow
()
{
super
.
onDetachedFromWindow
();
mAM
.
removeAccessibilityStateChangeListener
(
this
);
}
@Override
public
boolean
hasOverlappingRendering
()
{
return
false
;
}
@Override
public
void
onExtractedColorsChanged
(
WallpaperColorInfo
wallpaperColorInfo
)
{
mScrimColor
=
wallpaperColorInfo
.
getMainColor
();
mEndFlatColor
=
compositeColors
(
mEndScrim
,
setAlphaComponent
(
mScrimColor
,
Math
.
round
(
mMaxScrimAlpha
*
255
)));
mEndFlatColorAlpha
=
Color
.
alpha
(
mEndFlatColor
);
updateColors
();
invalidate
();
}
public
void
setProgress
(
float
progress
)
{
if
(
mProgress
!=
progress
)
{
mProgress
=
progress
;
updateColors
();
updateDragHandleAlpha
();
invalidate
();
}
}
public
void
reInitUi
()
{
}
protected
void
updateColors
()
{
mCurrentFlatColor
=
mProgress
>=
1
?
0
:
setAlphaComponent
(
mEndFlatColor
,
Math
.
round
((
1
-
mProgress
)
*
mEndFlatColorAlpha
));
}
protected
void
updateDragHandleAlpha
()
{
if
(
mDragHandle
!=
null
)
{
mDragHandle
.
setAlpha
(
mDragHandleAlpha
);
}
}
private
void
setDragHandleAlpha
(
int
alpha
)
{
if
(
alpha
!=
mDragHandleAlpha
)
{
mDragHandleAlpha
=
alpha
;
if
(
mDragHandle
!=
null
)
{
mDragHandle
.
setAlpha
(
mDragHandleAlpha
);
invalidate
();
}
}
}
@Override
protected
void
onDraw
(
Canvas
canvas
)
{
if
(
mCurrentFlatColor
!=
0
)
{
canvas
.
drawColor
(
mCurrentFlatColor
);
}
if
(
mDragHandle
!=
null
)
{
mDragHandle
.
draw
(
canvas
);
}
}
@Override
public
boolean
onTouchEvent
(
MotionEvent
event
)
{
boolean
value
=
super
.
onTouchEvent
(
event
);
if
(!
value
&&
mDragHandle
!=
null
&&
event
.
getAction
()
==
ACTION_DOWN
&&
mDragHandle
.
getAlpha
()
==
255
&&
mHitRect
.
contains
(
event
.
getX
(),
event
.
getY
()))
{
final
Drawable
drawable
=
mDragHandle
;
mDragHandle
=
null
;
drawable
.
setBounds
(
mDragHandleBounds
);
Rect
topBounds
=
new
Rect
(
mDragHandleBounds
);
topBounds
.
offset
(
0
,
-
mDragHandleBounds
.
height
()
/
2
);
Rect
invalidateRegion
=
new
Rect
(
mDragHandleBounds
);
invalidateRegion
.
top
=
topBounds
.
top
;
Keyframe
frameTop
=
Keyframe
.
ofObject
(
0.6f
,
topBounds
);
frameTop
.
setInterpolator
(
DEACCEL
);
Keyframe
frameBot
=
Keyframe
.
ofObject
(
1
,
mDragHandleBounds
);
frameBot
.
setInterpolator
(
ACCEL
);
PropertyValuesHolder
holder
=
PropertyValuesHolder
.
ofKeyframe
(
"bounds"
,
Keyframe
.
ofObject
(
0
,
mDragHandleBounds
),
frameTop
,
frameBot
);
holder
.
setEvaluator
(
new
RectEvaluator
());
ObjectAnimator
anim
=
ObjectAnimator
.
ofPropertyValuesHolder
(
drawable
,
holder
);
anim
.
addListener
(
new
AnimatorListenerAdapter
()
{
@Override
public
void
onAnimationEnd
(
Animator
animation
)
{
getOverlay
().
remove
(
drawable
);
updateDragHandleVisibility
(
drawable
);
}
});
anim
.
addUpdateListener
((
v
)
->
invalidate
(
invalidateRegion
));
getOverlay
().
add
(
drawable
);
anim
.
start
();
}
return
value
;
}
protected
void
updateDragHandleBounds
()
{
DeviceProfile
grid
=
mLauncher
.
getDeviceProfile
();
final
int
left
;
final
int
width
=
getMeasuredWidth
();
final
int
top
=
getMeasuredHeight
()
-
mDragHandleSize
-
grid
.
getInsets
().
bottom
;
final
int
topMargin
;
if
(
grid
.
isVerticalBarLayout
())
{
topMargin
=
grid
.
workspacePadding
.
bottom
;
if
(
grid
.
isSeascape
())
{
left
=
width
-
grid
.
getInsets
().
right
-
mDragHandleSize
;
}
else
{
left
=
mDragHandleSize
+
grid
.
getInsets
().
left
;
}
}
else
{
left
=
(
width
-
mDragHandleSize
)
/
2
;
topMargin
=
grid
.
hotseatBarSizePx
;
}
mDragHandleBounds
.
offsetTo
(
left
,
top
-
topMargin
);
mHitRect
.
set
(
mDragHandleBounds
);
float
inset
=
-
mDragHandleSize
/
2
;
mHitRect
.
inset
(
inset
,
inset
);
if
(
mDragHandle
!=
null
)
{
mDragHandle
.
setBounds
(
mDragHandleBounds
);
}
}
@Override
public
void
onAccessibilityStateChanged
(
boolean
enabled
)
{
LauncherStateManager
stateManager
=
mLauncher
.
getStateManager
();
stateManager
.
removeStateListener
(
this
);
if
(
enabled
)
{
stateManager
.
addStateListener
(
this
);
onStateSetImmediately
(
mLauncher
.
getStateManager
().
getState
());
}
else
{
setImportantForAccessibility
(
IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
);
}
updateDragHandleVisibility
(
null
);
}
private
void
updateDragHandleVisibility
(
Drawable
recycle
)
{
boolean
visible
=
mLauncher
.
getDeviceProfile
().
isVerticalBarLayout
()
||
mAM
.
isEnabled
();
boolean
wasVisible
=
mDragHandle
!=
null
;
if
(
visible
!=
wasVisible
)
{
if
(
visible
)
{
mDragHandle
=
recycle
!=
null
?
recycle
:
mLauncher
.
getDrawable
(
R
.
drawable
.
drag_handle_indicator
);
mDragHandle
.
setBounds
(
mDragHandleBounds
);
updateDragHandleAlpha
();
}
else
{
mDragHandle
=
null
;
}
invalidate
();
}
}
@Override
public
boolean
dispatchHoverEvent
(
MotionEvent
event
)
{
return
mAccessibilityHelper
.
dispatchHoverEvent
(
event
)
||
super
.
dispatchHoverEvent
(
event
);
}
@Override
public
boolean
dispatchKeyEvent
(
KeyEvent
event
)
{
return
mAccessibilityHelper
.
dispatchKeyEvent
(
event
)
||
super
.
dispatchKeyEvent
(
event
);
}
@Override
public
void
onFocusChanged
(
boolean
gainFocus
,
int
direction
,
Rect
previouslyFocusedRect
)
{
super
.
onFocusChanged
(
gainFocus
,
direction
,
previouslyFocusedRect
);
mAccessibilityHelper
.
onFocusChanged
(
gainFocus
,
direction
,
previouslyFocusedRect
);
}
@Override
public
void
onStateTransitionStart
(
LauncherState
toState
)
{}
@Override
public
void
onStateTransitionComplete
(
LauncherState
finalState
)
{