1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.example.android.intentplayground;
18 
19 
20 import android.app.Activity;
21 import android.app.ActivityManager;
22 import android.app.ActivityManager.AppTask;
23 import android.app.ActivityManager.RecentTaskInfo;
24 import android.content.Intent;
25 import android.view.LayoutInflater;
26 import android.view.View;
27 import android.view.ViewGroup;
28 import android.widget.ImageButton;
29 import android.widget.LinearLayout;
30 import android.widget.TextView;
31 
32 import androidx.annotation.NonNull;
33 import androidx.fragment.app.FragmentActivity;
34 import androidx.fragment.app.FragmentManager;
35 import androidx.recyclerview.widget.RecyclerView;
36 
37 import com.example.android.intentplayground.InlineAdapter.TaskViewHolder;
38 import com.example.android.intentplayground.Tracking.Task;
39 
40 import java.util.Collections;
41 import java.util.List;
42 
43 public class InlineAdapter extends RecyclerView.Adapter<TaskViewHolder> {
44 
45     private final List<Task> mTasks;
46     private int mCurrentTaskIndex;
47     private FragmentActivity mActivity;
48 
InlineAdapter(List<Task> tasks, FragmentActivity activity)49     public InlineAdapter(List<Task> tasks, FragmentActivity activity) {
50         this.mActivity = activity;
51         this.mTasks = tasks;
52         this.mCurrentTaskIndex = indexOfRunningTask();
53     }
54 
indexOfRunningTask()55     public int indexOfRunningTask() {
56         int currentTaskId = mActivity.getTaskId();
57 
58         int index = 0;
59         for (int i = 0; i < mTasks.size(); i++) {
60             Task task = mTasks.get(i);
61             if (task.id == currentTaskId) {
62                 index = i;
63                 break;
64             }
65         }
66 
67         return index;
68     }
69 
70 
71     @NonNull
72     @Override
onCreateViewHolder(@onNull ViewGroup parent, int viewType)73     public TaskViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
74         View task = LayoutInflater.from(parent.getContext())
75                 .inflate(R.layout.tree_node_composite, parent, false);
76         return new TaskViewHolder(task);
77     }
78 
79     @Override
onBindViewHolder(@onNull TaskViewHolder holder, int position)80     public void onBindViewHolder(@NonNull TaskViewHolder holder, int position) {
81         boolean highLightRunningActivity = position == mCurrentTaskIndex;
82         holder.setTask(mTasks.get(position), mActivity.getSupportFragmentManager(),
83                 highLightRunningActivity);
84     }
85 
86     @Override
getItemCount()87     public int getItemCount() {
88         return mTasks.size();
89     }
90 
91     public static class TaskViewHolder extends RecyclerView.ViewHolder {
92 
93         private final TextView mTaskIdTextView;
94         private final LinearLayout mActivitiesLayout;
95 
TaskViewHolder(@onNull View itemView)96         public TaskViewHolder(@NonNull View itemView) {
97             super(itemView);
98             mTaskIdTextView = itemView.findViewById(R.id.task_id);
99             mActivitiesLayout = itemView.findViewById(R.id.activity_node_container);
100         }
101 
setTask(Task task, FragmentManager manager, boolean highLightRunningActivity)102         public void setTask(Task task, FragmentManager manager, boolean highLightRunningActivity) {
103             mTaskIdTextView.setText(task.id == Node.NEW_TASK_ID
104                     ? mTaskIdTextView.getContext().getString(R.string.new_task)
105                     : String.valueOf(task.id));
106             int taskColor = mTaskIdTextView.getContext()
107                     .getResources().getColor(ColorManager.getColorForTask(task.id),
108                             null /* theme */);
109             mTaskIdTextView.setTextColor(taskColor);
110 
111             mActivitiesLayout.removeAllViews();
112             for (Activity activity : task.mActivities) {
113                 View activityView = LayoutInflater.from(mActivitiesLayout.getContext())
114                         .inflate(R.layout.activity_node, mActivitiesLayout, false);
115 
116                 TextView activityName = activityView.findViewById(R.id.activity_name);
117 
118                 activityName.setText(activity.getComponentName().getShortClassName());
119                 activityName.setOnClickListener(clickedView -> {
120                     Intent intent = activity.getIntent();
121                     List<String> flags;
122                     if (intent != null) {
123                         flags = FlagUtils.discoverFlags(intent);
124                         if (flags.size() == 0) {
125                             flags.add("None");
126                         }
127                     } else {
128                         flags = Collections.singletonList("None");
129                     }
130                     showDialogWithFlags(manager, activity.getComponentName().getShortClassName(),
131                             flags, task.id);
132                 });
133 
134 
135                 if (highLightRunningActivity) {
136                     highLightRunningActivity = false;
137                     activityName.setTextColor(taskColor);
138                 }
139 
140                 mActivitiesLayout.addView(activityView);
141             }
142         }
143 
144         /**
145          * Shows a dialog with a list.
146          *
147          * @param shortClassName The activity name and title of the dialog.
148          * @param flags          The flags to list.
149          */
showDialogWithFlags(FragmentManager manager, String shortClassName, List<String> flags, int taskId)150         private void showDialogWithFlags(FragmentManager manager,
151                 String shortClassName, List<String> flags, int taskId) {
152             IntentDialogFragment.newInstance(shortClassName, flags, taskId).show(manager,
153                     "intentDialog");
154         }
155     }
156 }
157