Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions packages/SystemUI/res/drawable/qs_user_online_circle.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
<stroke
android:color="?androidprv:attr/colorSurface"
android:width="2dp" />
<solid android:color="@androidprv:color/materialColorOnSurface" />
<corners android:radius="8dp" />
</shape>
22 changes: 19 additions & 3 deletions packages/SystemUI/res/layout/qs_user_detail_item.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,33 @@
systemui:activatedTextAppearance="@style/TextAppearance.QS.UserSwitcher"
systemui:regularTextAppearance="@style/TextAppearance.QS.UserSwitcher">

<FrameLayout
android:layout_width="@dimen/qs_framed_avatar_size"
android:layout_height="@dimen/qs_framed_avatar_size"
android:layout_marginBottom="7dp">

<com.android.systemui.statusbar.phone.UserAvatarView
android:id="@+id/user_picture"
android:layout_width="@dimen/qs_framed_avatar_size"
android:layout_height="@dimen/qs_framed_avatar_size"
android:layout_marginBottom="7dp"
android:layout_width="match_parent"
android:layout_height="match_parent"
systemui:frameWidth="6dp"
systemui:badgeDiameter="15dp"
systemui:badgeMargin="5dp"
systemui:framePadding="-1dp"
systemui:frameColor="@color/qs_user_avatar_frame"/>

<!-- Online indicator (small dot) in the top-right corner -->
<View
android:id="@+id/online_indicator"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_gravity="top|end"
android:layout_marginTop="0dp"
android:layout_marginEnd="0dp"
android:background="@drawable/qs_user_online_circle"
android:visibility="gone" />
</FrameLayout>

<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@

import javax.inject.Inject;

import android.view.MenuItem;
import android.widget.PopupMenu;
import android.app.ActivityManager;
import android.os.UserManager;
import android.view.ContextThemeWrapper;

/**
* Quick settings detail view for user switching.
*/
Expand Down Expand Up @@ -124,6 +130,25 @@ public void injectDialogShower(UserSwitchDialogController.DialogShower shower) {
mDialogShower = shower;
}

// GrapheneOS End Session functionality
private void showUserContextMenu(UserRecord user, View view) {
UserManager um = (UserManager)view.getContext().getSystemService(Context.USER_SERVICE);
if(user != null && user.info != null) {
boolean isUnlocked = um.isUserUnlocked(user.info.id);
boolean isOwner = um.isUserAdmin(user.info.id);
if(isUnlocked && !isOwner) {
PopupMenu menu = new PopupMenu(view.getContext(), view);
menu.getMenu().add("End Session").setOnMenuItemClickListener(i -> {
ActivityManager am = (ActivityManager)view.getContext().getSystemService(Context.ACTIVITY_SERVICE);
am.logoutUser(user.info.id);
return true;
});

menu.show();
}
}
}

public UserDetailItemView createUserDetailItemView(View convertView, ViewGroup parent,
UserRecord item) {
UserDetailItemView v = UserDetailItemView.convertOrInflate(
Expand All @@ -134,12 +159,31 @@ public UserDetailItemView createUserDetailItemView(View convertView, ViewGroup p
v.setOnClickListener(null);
v.setClickable(false);
}

// GrapheneOS: adding the "End session" functionality to the user selection widget
// As it is convenient to always have an opportunity to end sessions of other users
v.setOnLongClickListener(view -> {
showUserContextMenu(item, view);
return true;
});

String name = getName(mContext, item);
if (item.picture == null) {
v.bind(name, getDrawable(mContext, item).mutate(), item.resolveId());
} else {
int avatarSize =
(int) mContext.getResources().getDimension(R.dimen.qs_framed_avatar_size);

UserManager um = (UserManager)parent.getContext().getSystemService(Context.USER_SERVICE);
View onlineIndicator = v.findViewById(R.id.online_indicator);
onlineIndicator.setVisibility(View.GONE);
if(item != null && item.info != null) {
boolean isUnlocked = um.isUserUnlocked(item.info.id);
if(isUnlocked) {
onlineIndicator.setVisibility(View.VISIBLE);
}
}

Drawable drawable = new CircleFramedDrawable(item.picture, avatarSize);
drawable.setColorFilter(
item.isSwitchToEnabled ? null : getDisabledUserAvatarColorFilter());
Expand Down