Merge "Create & populate People Space activity"
This commit is contained in:
@@ -572,6 +572,13 @@
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<!-- People Space UI Screen -->
|
||||
<activity
|
||||
android:name=".people.PeopleSpaceActivity"
|
||||
android:exported="true"
|
||||
android:theme="@android:style/Theme.Material.NoActionBar">
|
||||
</activity>
|
||||
|
||||
<!-- a gallery of delicious treats -->
|
||||
<service
|
||||
android:name=".DessertCaseDream"
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
<!--
|
||||
~ Copyright (C) 2020 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.
|
||||
-->
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="@android:color/white" />
|
||||
<padding
|
||||
android:left="1dp"
|
||||
android:top="1dp"
|
||||
android:right="1dp"
|
||||
android:bottom="1dp" />
|
||||
<corners
|
||||
android:bottomRightRadius="7dp"
|
||||
android:bottomLeftRadius="7dp"
|
||||
android:topRightRadius="7dp"
|
||||
android:topLeftRadius="7dp" />
|
||||
</shape>
|
||||
45
packages/SystemUI/res/layout/people_space_activity.xml
Normal file
45
packages/SystemUI/res/layout/people_space_activity.xml
Normal file
@@ -0,0 +1,45 @@
|
||||
<!--
|
||||
~ Copyright (C) 2020 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.
|
||||
-->
|
||||
<androidx.core.widget.NestedScrollView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/scroll"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@android:color/holo_blue_light">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/people_space_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/people_space_cloud"
|
||||
android:layout_width="67dp"
|
||||
android:layout_height="67dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:scaleType="fitCenter"
|
||||
android:focusable="false"
|
||||
android:paddingBottom="16dp"
|
||||
android:tint="?android:attr/colorControlNormal"
|
||||
android:src="@drawable/cloud" />
|
||||
|
||||
</LinearLayout>
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
65
packages/SystemUI/res/layout/people_space_tile_view.xml
Normal file
65
packages/SystemUI/res/layout/people_space_tile_view.xml
Normal file
@@ -0,0 +1,65 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (C) 2020 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.
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/tile_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:background="@drawable/people_space_tile_view_card"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:elevation="4dp"
|
||||
android:gravity="start">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/tile_view_package_icon"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:layout_gravity="end" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/tile_view_person_icon"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:layout_gravity="start" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tile_view_name"
|
||||
android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem"
|
||||
android:paddingVertical="4dp"
|
||||
android:textSize="22sp"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tile_view_status"
|
||||
android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem"
|
||||
android:paddingVertical="4dp"
|
||||
android:textSize="16sp"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:layout_gravity="start" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
@@ -2834,4 +2834,10 @@
|
||||
<string name="build_number_clip_data_label">Build number</string>
|
||||
<!-- Text to display when copying the build number off QS [CHAR LIMIT=NONE]-->
|
||||
<string name="build_number_copy_toast">Build number copied to clipboard.</string>
|
||||
|
||||
<!-- Status for last interaction [CHAR LIMIT=120] -->
|
||||
<string name="last_interaction_status" translatable="false">You last chatted <xliff:g id="duration" example="5 hours">%1$s</xliff:g> ago</string>
|
||||
<!-- Status for conversation without interaction data [CHAR LIMIT=120] -->
|
||||
<string name="basic_status" translatable="false">Open conversation</string>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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 com.android.systemui.people;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.INotificationManager;
|
||||
import android.app.people.IPeopleManager;
|
||||
import android.content.Context;
|
||||
import android.content.pm.LauncherApps;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.icu.text.MeasureFormat;
|
||||
import android.icu.util.Measure;
|
||||
import android.icu.util.MeasureUnit;
|
||||
import android.os.Bundle;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.UserHandle;
|
||||
import android.service.notification.ConversationChannelWrapper;
|
||||
import android.util.Log;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.android.systemui.R;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Shows the user their tiles for their priority People (go/live-status).
|
||||
*/
|
||||
public class PeopleSpaceActivity extends Activity {
|
||||
|
||||
private static String sTAG = "PeopleSpaceActivity";
|
||||
|
||||
private ViewGroup mPeopleSpaceLayout;
|
||||
private IPeopleManager mPeopleManager;
|
||||
private INotificationManager mNotificationManager;
|
||||
private PackageManager mPackageManager;
|
||||
private LauncherApps mLauncherApps;
|
||||
private List<ConversationChannelWrapper> mConversations;
|
||||
private Context mContext;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.people_space_activity);
|
||||
mPeopleSpaceLayout = findViewById(R.id.people_space_layout);
|
||||
mContext = getApplicationContext();
|
||||
mNotificationManager =
|
||||
INotificationManager.Stub.asInterface(
|
||||
ServiceManager.getService(Context.NOTIFICATION_SERVICE));
|
||||
mPackageManager = getPackageManager();
|
||||
mPeopleManager = IPeopleManager.Stub.asInterface(
|
||||
ServiceManager.getService(Context.PEOPLE_SERVICE));
|
||||
mLauncherApps = mContext.getSystemService(LauncherApps.class);
|
||||
setTileViewsWithPriorityConversations();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all priority conversations and sets a {@link PeopleSpaceTileView}s for each
|
||||
* priority conversation.
|
||||
*/
|
||||
private void setTileViewsWithPriorityConversations() {
|
||||
try {
|
||||
List<ConversationChannelWrapper> conversations =
|
||||
mNotificationManager.getConversations(
|
||||
true /* priority only */).getList();
|
||||
mConversations = conversations.stream().filter(
|
||||
c -> shouldKeepConversation(c)).collect(Collectors.toList());
|
||||
for (ConversationChannelWrapper conversation : mConversations) {
|
||||
PeopleSpaceTileView tileView = new PeopleSpaceTileView(mContext,
|
||||
mPeopleSpaceLayout,
|
||||
conversation.getShortcutInfo().getId());
|
||||
setTileView(tileView, conversation);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(sTAG, "Couldn't retrieve conversations", e);
|
||||
}
|
||||
}
|
||||
|
||||
/** Sets {@code tileView} with the data in {@code conversation}. */
|
||||
private void setTileView(PeopleSpaceTileView tileView,
|
||||
ConversationChannelWrapper conversation) {
|
||||
try {
|
||||
ShortcutInfo shortcutInfo = conversation.getShortcutInfo();
|
||||
int userId = UserHandle.getUserHandleForUid(
|
||||
conversation.getUid()).getIdentifier();
|
||||
|
||||
String pkg = shortcutInfo.getPackage();
|
||||
long lastInteraction = mPeopleManager.getLastInteraction(
|
||||
pkg, userId,
|
||||
shortcutInfo.getId());
|
||||
String status = lastInteraction != 0l ? mContext.getString(
|
||||
R.string.last_interaction_status,
|
||||
getLastInteractionString(
|
||||
lastInteraction)) : mContext.getString(R.string.basic_status);
|
||||
tileView.setStatus(status);
|
||||
|
||||
tileView.setName(shortcutInfo.getLabel().toString());
|
||||
tileView.setPackageIcon(mPackageManager.getApplicationIcon(pkg));
|
||||
tileView.setPersonIcon(mLauncherApps.getShortcutIconDrawable(shortcutInfo, 0));
|
||||
tileView.setOnClickListener(mLauncherApps, shortcutInfo);
|
||||
} catch (Exception e) {
|
||||
Log.e(sTAG, "Couldn't retrieve shortcut information", e);
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns a readable representation of {@code lastInteraction}. */
|
||||
private String getLastInteractionString(long lastInteraction) {
|
||||
long now = System.currentTimeMillis();
|
||||
Duration durationSinceLastInteraction = Duration.ofMillis(
|
||||
now - lastInteraction);
|
||||
MeasureFormat formatter = MeasureFormat.getInstance(Locale.getDefault(),
|
||||
MeasureFormat.FormatWidth.WIDE);
|
||||
if (durationSinceLastInteraction.toDays() >= 1) {
|
||||
return
|
||||
formatter
|
||||
.formatMeasures(new Measure(durationSinceLastInteraction.toDays(),
|
||||
MeasureUnit.DAY));
|
||||
} else if (durationSinceLastInteraction.toHours() >= 1) {
|
||||
return formatter.formatMeasures(new Measure(durationSinceLastInteraction.toHours(),
|
||||
MeasureUnit.HOUR));
|
||||
} else if (durationSinceLastInteraction.toMinutes() >= 1) {
|
||||
return formatter.formatMeasures(new Measure(durationSinceLastInteraction.toMinutes(),
|
||||
MeasureUnit.MINUTE));
|
||||
} else {
|
||||
return formatter.formatMeasures(
|
||||
new Measure(durationSinceLastInteraction.toMillis() / 1000,
|
||||
MeasureUnit.SECOND));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the {@code conversation} should be kept for display in the People Space.
|
||||
*
|
||||
* <p>A valid {@code conversation} must:
|
||||
* <ul>
|
||||
* <li>Have a non-null {@link ShortcutInfo}
|
||||
* <li>Have an associated label in the {@link ShortcutInfo}
|
||||
* </ul>
|
||||
* </li>
|
||||
*/
|
||||
private boolean shouldKeepConversation(ConversationChannelWrapper conversation) {
|
||||
ShortcutInfo shortcutInfo = conversation.getShortcutInfo();
|
||||
return shortcutInfo != null && shortcutInfo.getLabel().length() != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
// Refresh tile views to sync new conversations.
|
||||
setTileViewsWithPriorityConversations();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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 com.android.systemui.people;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.LauncherApps;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.systemui.R;
|
||||
|
||||
/**
|
||||
* PeopleSpaceTileView renders an individual person's tile with associated status.
|
||||
*/
|
||||
public class PeopleSpaceTileView extends LinearLayout {
|
||||
|
||||
private View mTileView;
|
||||
private TextView mNameView;
|
||||
private TextView mStatusView;
|
||||
private ImageView mPackageIconView;
|
||||
private ImageView mPersonIconView;
|
||||
|
||||
public PeopleSpaceTileView(Context context, ViewGroup view, String shortcutId) {
|
||||
super(context);
|
||||
mTileView = view.findViewWithTag(shortcutId);
|
||||
if (mTileView == null) {
|
||||
LayoutInflater inflater = LayoutInflater.from(context);
|
||||
mTileView = inflater.inflate(R.layout.people_space_tile_view, view, false);
|
||||
view.addView(mTileView, LayoutParams.MATCH_PARENT,
|
||||
LayoutParams.MATCH_PARENT);
|
||||
mTileView.setTag(shortcutId);
|
||||
}
|
||||
mNameView = mTileView.findViewById(R.id.tile_view_name);
|
||||
mStatusView = mTileView.findViewById(R.id.tile_view_status);
|
||||
mPackageIconView = mTileView.findViewById(R.id.tile_view_package_icon);
|
||||
mPersonIconView = mTileView.findViewById(R.id.tile_view_person_icon);
|
||||
}
|
||||
|
||||
/** Sets the name text on the tile. */
|
||||
public void setName(String name) {
|
||||
mNameView.setText(name);
|
||||
}
|
||||
|
||||
/** Sets the status text on the tile. */
|
||||
public void setStatus(String status) {
|
||||
mStatusView.setText(status);
|
||||
}
|
||||
|
||||
/** Sets the package drawable on the tile. */
|
||||
public void setPackageIcon(Drawable drawable) {
|
||||
mPackageIconView.setImageDrawable(drawable);
|
||||
}
|
||||
|
||||
/** Sets the person drawable on the tile. */
|
||||
public void setPersonIcon(Drawable drawable) {
|
||||
mPersonIconView.setImageDrawable(drawable);
|
||||
}
|
||||
|
||||
/** Sets the click listener of the tile. */
|
||||
public void setOnClickListener(LauncherApps launcherApps, ShortcutInfo shortcutInfo) {
|
||||
mTileView.setOnClickListener(v -> launcherApps.startShortcut(shortcutInfo, null, null));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user