Commit 74f512c9 authored by Hazem Ashmawy's avatar Hazem Ashmawy Committed by Commit Bot

[AW] DEV UI: add a basic main activity

* Add a basic main activity that shows some info about the webview
  package in use:
  - WebView package name.
  - WebView version name and code.
  - Device build fingerprint.
* Use activity action bar menu to provide navigation options to other
  existing webview dev UIs, Crash UI in this case.
* Use device default theme for more natural look.
* Copy info content to clipboard when tapped.
* Add the shared navigation menu to Crash UI, and show the refresh
  option outside the menu "ifRoom" available.
* Set DevUI activities launch mode to be "singleTask" and "SingleTop"
  for more intuitive navigation.

Fixed: 981154
Test: Manually verify it on SystemWebView and Trichrome on Android Q and MonoChrome on Android P
Change-Id: I61dbcbb714b1b5a18cc4a61a894257a77bcd20b6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1877267
Commit-Queue: Hazem Ashmawy <hazems@chromium.org>
Auto-Submit: Hazem Ashmawy <hazems@chromium.org>
Reviewed-by: default avatarRichard Coles <torne@chromium.org>
Reviewed-by: default avatarNate Fischer <ntfschr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#710195}
parent 613bc8fc
......@@ -37,7 +37,9 @@ android_library("apk_java") {
android_library("devui_java") {
java_files = [
"java/src/org/chromium/android_webview/devui/CrashesListActivity.java",
"java/src/org/chromium/android_webview/devui/MainActivity.java",
"java/src/org/chromium/android_webview/devui/util/CrashInfoLoader.java",
"java/src/org/chromium/android_webview/devui/util/NavigationMenuHelper.java",
"java/src/org/chromium/android_webview/devui/util/UnuploadedFilesStateLoader.java",
"java/src/org/chromium/android_webview/devui/util/UploadedCrashesInfoLoader.java",
"java/src/org/chromium/android_webview/devui/util/WebViewCrashInfoCollector.java",
......@@ -49,6 +51,7 @@ android_library("devui_java") {
"//android_webview:system_webview_manifest",
"//base:base_java",
"//components/minidump_uploader:minidump_uploader_java",
"//ui/android:ui_java",
]
android_manifest_for_lint = system_webview_android_manifest
min_sdk_version = 21
......
......@@ -28,6 +28,23 @@
{% macro common(manifest_package, webview_lib) %}
<meta-data android:name="com.android.webview.WebViewLibrary"
android:value="{{ webview_lib }}" />
<!-- WebView Developer UI Activties -->
<!--suppress HardcodedText -->
<activity android:name="org.chromium.android_webview.devui.MainActivity"
android:label="WebView DevTools"
android:theme="@android:style/Theme.DeviceDefault"
android:launchMode="singleTask"
android:process=":webview_apk"> {# Explicit process required for monochrome compatibility. #}
</activity>
<activity android:name="org.chromium.android_webview.devui.CrashesListActivity"
android:label="WebView Crashes"
android:theme="@android:style/Theme.DeviceDefault"
android:launchMode="singleTop"
android:process=":webview_apk"> {# Explicit process required for monochrome compatibility. #}
</activity>
<!-- End of WebView Developer UI Activties -->
<activity android:name="com.android.webview.chromium.LicenseActivity"
android:label="@string/license_activity_title"
android:process=":webview_apk"> {# Explicit process required for monochrome compatibility. #}
......@@ -38,11 +55,6 @@
<meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
android:value="true" />
</activity>
<!--suppress HardcodedText -->
<activity android:name="org.chromium.android_webview.devui.CrashesListActivity"
android:label="WebView Crashes"
android:process=":webview_apk"> {# Explicit process required for monochrome compatibility. #}
</activity>
<provider android:name="com.android.webview.chromium.LicenseContentProvider"
android:exported="true"
android:authorities="{{ manifest_package }}.LicenseContentProvider"
......
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2019 The Chromium Authors. All rights reserved. Use of this
source code is governed by a BSD-style license that can be found in the
LICENSE file.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@+id/main_info_list"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
......@@ -7,9 +7,11 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<!--suppress HardcodedText -->
<item
android:id="@+id/options_menu_refresh"
android:title="Refresh"
android:showAsAction="never" />
<group android:id="@+id/crashes_menu">
<!--suppress HardcodedText -->
<item
android:id="@+id/options_menu_refresh"
android:title="Refresh"
android:showAsAction="ifRoom" />
</group>
</menu>
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2019 The Chromium Authors. All rights reserved. Use of this
source code is governed by a BSD-style license that can be found in the
LICENSE file.
-->
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<group android:id="@+id/nav_menu_group">
<!--suppress HardcodedText -->
<item
android:id="@+id/nav_menu_crash_ui"
android:title="WebView Crashes"
android:showAsAction="never"/>
<!--suppress HardcodedText -->
<item
android:id="@+id/nav_menu_main_ui"
android:title="Home"
android:showAsAction="never"/>
</group>
</menu>
......@@ -21,6 +21,7 @@ import android.widget.TextView;
import org.chromium.android_webview.common.crash.CrashInfo;
import org.chromium.android_webview.common.crash.CrashInfo.UploadState;
import org.chromium.android_webview.devui.util.NavigationMenuHelper;
import org.chromium.android_webview.devui.util.WebViewCrashInfoCollector;
import java.util.Date;
......@@ -191,11 +192,15 @@ public class CrashesListActivity extends Activity {
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.crashes_options_menu, menu);
NavigationMenuHelper.inflate(this, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (NavigationMenuHelper.onOptionsItemSelected(this, item)) {
return true;
}
if (item.getItemId() == R.id.options_menu_refresh) {
updateCrashesList();
return true;
......
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.android_webview.devui;
import android.app.Activity;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Build;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import org.chromium.android_webview.devui.util.NavigationMenuHelper;
import org.chromium.ui.widget.Toast;
import java.util.Locale;
/**
* Dev UI main activity.
* It shows a summary about WebView package and the device.
* It helps to navigate to other WebView developer tools.
*/
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
PackageInfo webViewPackage = getPackageInfo();
InfoItem[] infoItems = new InfoItem[] {
new InfoItem("WebView package",
webViewPackage == null ? null : webViewPackage.packageName),
new InfoItem("WebView version",
String.format(Locale.US, "%s (%s)",
webViewPackage == null ? null : webViewPackage.versionName,
webViewPackage.versionCode)),
new InfoItem("Device info",
String.format(Locale.US, "%s - %s", Build.MODEL, Build.FINGERPRINT)),
};
ListView infoListView = findViewById(R.id.main_info_list);
ArrayAdapter<InfoItem> itemsArrayAdapter = new InfoListAdapter(infoItems);
infoListView.setAdapter(itemsArrayAdapter);
// Copy item's text to clipboard on tapping a list item.
infoListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
InfoItem item = infoItems[position];
ClipboardManager clipboard =
(ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText(item.title, item.subtitle);
clipboard.setPrimaryClip(clip);
// Show a toast that the text has been copied.
Toast.makeText(MainActivity.this, "Copied " + item.title, Toast.LENGTH_SHORT)
.show();
}
});
}
/**
* A model class for a key-value piece of information to be displayed as a title (key) and
* subtitle (value).
*/
private static class InfoItem {
public static final String UNKNOWN = "Unknown";
public final String title;
public final String subtitle;
public InfoItem(String title, String subtitle) {
this.title = title;
this.subtitle = subtitle == null ? UNKNOWN : subtitle;
}
}
/**
* An ArrayAdapter to show a list of {@code InfoItem} objects.
*
* It uses android stock {@code android.R.layout.simple_list_item_2} which has two {@code
* TextView}; {@code text1} acts as the item title and {@code text2} as the item subtitle.
*/
private class InfoListAdapter extends ArrayAdapter<InfoItem> {
private final InfoItem[] mItems;
public InfoListAdapter(InfoItem[] items) {
super(MainActivity.this, android.R.layout.simple_list_item_2, items);
mItems = items;
}
@Override
public View getView(int position, View view, ViewGroup parent) {
// If the the old view is already created then reuse it, else create a new one by layout
// inflation.
if (view == null) {
view = getLayoutInflater().inflate(android.R.layout.simple_list_item_2, null, true);
}
InfoItem item = mItems[position];
TextView title = view.findViewById(android.R.id.text1);
TextView subtitle = view.findViewById(android.R.id.text2);
title.setText(item.title);
subtitle.setText(item.subtitle);
return view;
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
NavigationMenuHelper.inflate(this, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (NavigationMenuHelper.onOptionsItemSelected(this, item)) {
return true;
}
return super.onOptionsItemSelected(item);
}
private PackageInfo getPackageInfo() {
try {
return getPackageManager().getPackageInfo(getPackageName(), 0);
} catch (NameNotFoundException e) {
return null;
}
}
}
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.android_webview.devui.util;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.MenuItem;
import org.chromium.android_webview.devui.CrashesListActivity;
import org.chromium.android_webview.devui.MainActivity;
import org.chromium.android_webview.devui.R;
/**
* Helper class for navigation menu between activities.
*
* TODO(crbug.com/1017532) should be replaced with a navigation drawer.
*/
public final class NavigationMenuHelper {
/**
* Inflate the navigation menu in the given {@code activity} options menu.
*
* This should be called inside {@code Activity#onCreateOptionsMenu} method.
*/
public static void inflate(Activity activity, Menu menu) {
activity.getMenuInflater().inflate(R.menu.navigation_menu, menu);
}
/**
* Handle {@code onOptionsItemSelected} event for navigation menu.
*
* This should be called inside {@code Activity#onOptionsItemSelected} method.
* @return {@code true} if the item selection event is consumed.
*/
public static boolean onOptionsItemSelected(Activity activity, MenuItem item) {
if (item.getItemId() == R.id.nav_menu_crash_ui) {
activity.startActivity(new Intent(activity, CrashesListActivity.class));
} else if (item.getItemId() == R.id.nav_menu_main_ui) {
activity.startActivity(new Intent(activity, MainActivity.class));
} else {
return false;
}
return true;
}
// Do not instantiate this class.
private NavigationMenuHelper() {}
}
......@@ -1008,8 +1008,17 @@
<activity
android:label="WebView
Crashes"
android:launchMode="singleTop"
android:name="org.chromium.android_webview.devui.CrashesListActivity"
android:process=":webview_apk"/>
android:process=":webview_apk"
android:theme="@android:style/Theme.DeviceDefault"/>
<activity
android:label="WebView
DevTools"
android:launchMode="singleTask"
android:name="org.chromium.android_webview.devui.MainActivity"
android:process=":webview_apk"
android:theme="@android:style/Theme.DeviceDefault"/>
<activity
android:enabled="false"
android:excludeFromRecents="true"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment