Skip to content

Commit e87b4c7

Browse files
Fireperf: create an activity with fragments in dev-app for testing (#3133)
* add a new activity with fragments * copyright * more listeners * decor view hardware accel * 2021 copyright * adding gifs * gJF * fix copyright * switch statement returns * pretty toolbar * add laggy recyclerview to one of the fragments * gJF
1 parent 10cacef commit e87b4c7

26 files changed

+970
-54
lines changed

firebase-perf/dev-app/dev-app.gradle

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,18 @@ dependencies {
9696
implementation 'androidx.annotation:annotation:1.1.0'
9797
implementation 'androidx.multidex:multidex:2.0.1'
9898
implementation 'com.google.android.gms:play-services-tasks:17.2.0'
99+
implementation 'androidx.appcompat:appcompat:1.3.1'
100+
implementation 'androidx.constraintlayout:constraintlayout:2.1.1'
101+
implementation 'androidx.vectordrawable:vectordrawable:1.1.0'
102+
implementation 'androidx.lifecycle:lifecycle-livedata:2.4.0'
103+
implementation 'androidx.lifecycle:lifecycle-viewmodel:2.4.0'
104+
implementation 'androidx.navigation:navigation-fragment:2.3.5'
105+
implementation 'androidx.navigation:navigation-ui:2.3.5'
106+
implementation 'com.google.android.material:material:1.4.0'
99107

100108
// 3rd party Deps
101109
implementation 'com.squareup.okhttp3:okhttp:4.9.0'
110+
implementation 'com.github.bumptech.glide:glide:4.12.0'
102111

103112
// Integration Test Deps
104113
androidTestImplementation 'junit:junit:4.13.1'
Lines changed: 54 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,56 @@
11
<?xml version="1.0" encoding="utf-8"?> <!-- Copyright 2020 Google Inc. All Rights Reserved. -->
2-
32
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
4-
xmlns:tools="http://schemas.android.com/tools"
5-
package="com.googletest.firebase.perf.testapp">
6-
7-
<uses-permission android:name="android.permission.INTERNET" />
8-
9-
<application
10-
android:allowBackup="true"
11-
android:icon="@drawable/ic_launcher"
12-
android:label="@string/app_name"
13-
android:usesCleartextTraffic="true"
14-
tools:targetApi="m">
15-
16-
<activity
17-
android:label="Perf Test App"
18-
android:name=".PerfTestActivity">
19-
<intent-filter>
20-
<action android:name="android.intent.action.MAIN" />
21-
<category android:name="android.intent.category.LAUNCHER" />
22-
</intent-filter>
23-
</activity>
24-
25-
<activity
26-
android:exported="true"
27-
android:name=".AnotherActivity" />
28-
29-
<meta-data
30-
android:name="firebase_performance_logcat_enabled"
31-
android:value="true" />
32-
33-
<meta-data
34-
android:name="sessions_sampling_percentage"
35-
android:value="100.0" />
36-
37-
<receiver
38-
android:exported="true"
39-
android:name=".FirebasePerfTestReceiver">
40-
<intent-filter>
41-
<action android:name="com.googletest.firebase.perf.testapp.ACTION_START" />
42-
</intent-filter>
43-
</receiver>
44-
45-
<service
46-
android:exported="true"
47-
android:name=".FirebasePerfTestService" />
48-
49-
<uses-library
50-
android:name="org.apache.http.legacy"
51-
android:required="false" />
52-
53-
</application>
54-
55-
</manifest>
3+
xmlns:tools="http://schemas.android.com/tools"
4+
package="com.googletest.firebase.perf.testapp">
5+
6+
<uses-permission android:name="android.permission.INTERNET" />
7+
8+
<application
9+
android:allowBackup="true"
10+
android:icon="@drawable/ic_launcher"
11+
android:label="@string/app_name"
12+
android:usesCleartextTraffic="true"
13+
tools:targetApi="m">
14+
<activity
15+
android:name=".FragmentActivity"
16+
android:exported="false"
17+
android:label="@string/title_activity_fragment"
18+
android:theme="@style/Theme.MaterialComponents.DayNight.NoActionBar" />
19+
<activity
20+
android:name=".PerfTestActivity"
21+
android:label="Perf Test App">
22+
<intent-filter>
23+
<action android:name="android.intent.action.MAIN" />
24+
25+
<category android:name="android.intent.category.LAUNCHER" />
26+
</intent-filter>
27+
</activity>
28+
<activity
29+
android:name=".AnotherActivity"
30+
android:exported="true" />
31+
32+
<meta-data
33+
android:name="firebase_performance_logcat_enabled"
34+
android:value="true" />
35+
<meta-data
36+
android:name="sessions_sampling_percentage"
37+
android:value="100.0" />
38+
39+
<receiver
40+
android:name=".FirebasePerfTestReceiver"
41+
android:exported="true">
42+
<intent-filter>
43+
<action android:name="com.googletest.firebase.perf.testapp.ACTION_START" />
44+
</intent-filter>
45+
</receiver>
46+
47+
<service
48+
android:name=".FirebasePerfTestService"
49+
android:exported="true" />
50+
51+
<uses-library
52+
android:name="org.apache.http.legacy"
53+
android:required="false" />
54+
</application>
55+
56+
</manifest>
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
// Copyright 2021 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
//
6+
// You may obtain a copy of the License at
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package com.googletest.firebase.perf.testapp;
16+
17+
import android.os.Bundle;
18+
import android.util.Log;
19+
import android.view.Menu;
20+
import android.view.MenuItem;
21+
import android.view.View;
22+
import androidx.annotation.NonNull;
23+
import androidx.annotation.Nullable;
24+
import androidx.appcompat.app.AppCompatActivity;
25+
import androidx.appcompat.widget.Toolbar;
26+
import androidx.fragment.app.Fragment;
27+
import androidx.fragment.app.FragmentManager;
28+
import androidx.lifecycle.ViewModelProvider;
29+
import androidx.navigation.NavController;
30+
import androidx.navigation.Navigation;
31+
import androidx.navigation.ui.AppBarConfiguration;
32+
import androidx.navigation.ui.NavigationUI;
33+
import com.google.android.material.bottomnavigation.BottomNavigationView;
34+
35+
public class FragmentActivity extends AppCompatActivity {
36+
SharedViewModel model;
37+
38+
@Override
39+
protected void onCreate(Bundle savedInstanceState) {
40+
// Listening on FragmentManager's FragmentLifeCycleCallbacks
41+
registerListeners();
42+
super.onCreate(savedInstanceState);
43+
setContentView(R.layout.activity_fragment);
44+
Toolbar toolbar = findViewById(R.id.toolbar_fragment_activity);
45+
setSupportActionBar(toolbar);
46+
BottomNavigationView navView = findViewById(R.id.nav_view);
47+
// Passing each menu ID as a set of Ids because each
48+
// menu should be considered as top level destinations.
49+
AppBarConfiguration appBarConfiguration =
50+
new AppBarConfiguration.Builder(
51+
R.id.navigation_home, R.id.navigation_dashboard, R.id.navigation_notifications)
52+
.build();
53+
NavController navController =
54+
Navigation.findNavController(this, R.id.nav_host_fragment_activity_fragment);
55+
// Listening on navigation events using NavController
56+
navController.addOnDestinationChangedListener(
57+
(controller, destination, arguments) -> {
58+
Log.d("Navigation", destination.getLabel().toString() + "Fragment");
59+
});
60+
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
61+
NavigationUI.setupWithNavController(
62+
(BottomNavigationView) findViewById(R.id.nav_view), navController);
63+
model = new ViewModelProvider(this).get(SharedViewModel.class);
64+
}
65+
66+
@Override
67+
public boolean onCreateOptionsMenu(Menu menu) {
68+
getMenuInflater().inflate(R.menu.menu, menu);
69+
return true;
70+
}
71+
72+
@Override
73+
public boolean onOptionsItemSelected(MenuItem item) {
74+
switch (item.getItemId()) {
75+
case R.id.action_change_gif:
76+
model.changeImage();
77+
return true;
78+
default:
79+
return super.onOptionsItemSelected(item);
80+
}
81+
}
82+
83+
@Override
84+
protected void onStart() {
85+
super.onStart();
86+
Log.d(
87+
"FragmentActivity",
88+
"onStart; View Hardware Accel: "
89+
+ decorViewAcceleratedFlag()
90+
+ ", FrameMetricsObservers won't be observing, only queued.");
91+
}
92+
93+
@Override
94+
public void onAttachedToWindow() {
95+
super.onAttachedToWindow();
96+
Log.d(
97+
"FragmentActivity",
98+
"onAttachedToWindow; View Hardware Accel: "
99+
+ decorViewAcceleratedFlag()
100+
+ ", FrameMetricsObservers in queue and any new observers will start observing.");
101+
}
102+
103+
private boolean decorViewAcceleratedFlag() {
104+
View v = this.getWindow().getDecorView();
105+
return v.isHardwareAccelerated();
106+
}
107+
108+
private void registerListeners() {
109+
getSupportFragmentManager()
110+
.registerFragmentLifecycleCallbacks(
111+
new FragmentManager.FragmentLifecycleCallbacks() {
112+
@Override
113+
public void onFragmentCreated(
114+
@NonNull FragmentManager fm,
115+
@NonNull Fragment f,
116+
@Nullable Bundle savedInstanceState) {
117+
super.onFragmentCreated(fm, f, savedInstanceState);
118+
Log.d("FragmentManager", "Fragment created " + f.getClass().getSimpleName());
119+
}
120+
121+
@Override
122+
public void onFragmentViewCreated(
123+
@NonNull FragmentManager fm,
124+
@NonNull Fragment f,
125+
@NonNull View v,
126+
@Nullable Bundle savedInstanceState) {
127+
super.onFragmentViewCreated(fm, f, v, savedInstanceState);
128+
Log.d("FragmentManager", "View created " + f.getClass().getSimpleName());
129+
}
130+
131+
@Override
132+
public void onFragmentStarted(@NonNull FragmentManager fm, @NonNull Fragment f) {
133+
super.onFragmentStarted(fm, f);
134+
Log.d("FragmentManager", "Fragment started " + f.getClass().getSimpleName());
135+
}
136+
137+
@Override
138+
public void onFragmentResumed(@NonNull FragmentManager fm, @NonNull Fragment f) {
139+
super.onFragmentResumed(fm, f);
140+
Log.d("FragmentManager", "Fragment resumed " + f.getClass().getSimpleName());
141+
}
142+
143+
@Override
144+
public void onFragmentStopped(@NonNull FragmentManager fm, @NonNull Fragment f) {
145+
super.onFragmentStopped(fm, f);
146+
Log.d("FragmentManager", "Fragment stopped " + f.getClass().getSimpleName());
147+
}
148+
149+
@Override
150+
public void onFragmentViewDestroyed(
151+
@NonNull FragmentManager fm, @NonNull Fragment f) {
152+
super.onFragmentViewDestroyed(fm, f);
153+
Log.d("FragmentManager", "View destroyed " + f.getClass().getSimpleName());
154+
}
155+
},
156+
true);
157+
}
158+
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
// Copyright 2020 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
//
6+
// You may obtain a copy of the License at
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package com.googletest.firebase.perf.testapp;
16+
17+
import android.util.Log;
18+
import android.view.LayoutInflater;
19+
import android.view.View;
20+
import android.view.ViewGroup;
21+
import android.widget.TextView;
22+
import androidx.recyclerview.widget.RecyclerView;
23+
import org.jetbrains.annotations.NotNull;
24+
25+
/** The Adapter for the ScreenTraces test ListView. */
26+
public class ListAdapter extends RecyclerView.Adapter<ListAdapter.NumberViewHolder> {
27+
28+
private static final String LOG_TAG = ListAdapter.class.getSimpleName();
29+
private final int numberOfItems;
30+
31+
/**
32+
* Constructor for ListAdapter that accepts a number of items to display.
33+
*
34+
* @param numberOfItems Number of items to display in list
35+
*/
36+
public ListAdapter(int numberOfItems) {
37+
this.numberOfItems = numberOfItems;
38+
}
39+
40+
@NotNull
41+
@Override
42+
public NumberViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
43+
return new NumberViewHolder(
44+
LayoutInflater.from(viewGroup.getContext())
45+
.inflate(R.layout.number_list_item, viewGroup, /* attachToRoot= */ false));
46+
}
47+
48+
@Override
49+
public void onBindViewHolder(@NotNull NumberViewHolder holder, int position) {
50+
try {
51+
if (position % 15 == 0) {
52+
Thread.sleep(900);
53+
} else if (position % 5 == 0) {
54+
Thread.sleep(50);
55+
}
56+
} catch (InterruptedException e) {
57+
Log.e(LOG_TAG, e.getMessage(), e);
58+
}
59+
60+
holder.bind(position);
61+
}
62+
63+
@Override
64+
public int getItemCount() {
65+
return numberOfItems;
66+
}
67+
68+
/** Cache of the children views for a list item. */
69+
static class NumberViewHolder extends RecyclerView.ViewHolder {
70+
71+
// Displays the position in the list, i.e 0 through getItemCount() - 1
72+
TextView listItemNumberView;
73+
74+
/**
75+
* Constructor for our ViewHolder.
76+
*
77+
* @param itemView The View that you inflated in {@link
78+
* ListAdapter#onCreateViewHolder(ViewGroup, int)}
79+
*/
80+
NumberViewHolder(View itemView) {
81+
super(itemView);
82+
83+
listItemNumberView = itemView.findViewById(R.id.tv_item_number);
84+
}
85+
86+
/**
87+
* Sets the new index number for the view as it is to be displayed.
88+
*
89+
* @param listIndex The new listIndex this view will displayed for.
90+
*/
91+
void bind(int listIndex) {
92+
listItemNumberView.setText(String.valueOf(listIndex));
93+
}
94+
}
95+
}

firebase-perf/dev-app/src/main/java/com/googletest/firebase/perf/testapp/PerfTestActivity.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,10 @@ private void initViews() {
195195
.setOnClickListener(logAllFirebaseRcKeysForFireperfNamespace);
196196
}
197197

198+
public void openFragmentActivity(View view) {
199+
startActivity(new Intent(this, FragmentActivity.class));
200+
}
201+
198202
private void readUrlsFromFile() {
199203
try {
200204
InputStream inputStream = getResources().openRawResource(R.raw.urls);

0 commit comments

Comments
 (0)