Merge "Import translations. DO NOT MERGE"
diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp
index 87dec5d..3c9dd68 100644
--- a/cmds/statsd/src/StatsLogProcessor.cpp
+++ b/cmds/statsd/src/StatsLogProcessor.cpp
@@ -316,7 +316,7 @@
StatsdStats::kMaxMetricsBytesPerConfig) { // Too late. We need to start clearing data.
// TODO(b/70571383): By 12/15/2017 add API to drop data directly
ProtoOutputStream proto;
- metricsManager.onDumpReport(time(nullptr) * NS_PER_SEC, &proto);
+ metricsManager.onDumpReport(timestampNs, &proto);
StatsdStats::getInstance().noteDataDropped(key);
VLOG("StatsD had to toss out metrics for %s", key.ToString().c_str());
} else if (totalBytes > .9 * StatsdStats::kMaxMetricsBytesPerConfig) {
@@ -340,7 +340,7 @@
for (auto& pair : mMetricsManagers) {
const ConfigKey& key = pair.first;
vector<uint8_t> data;
- onDumpReportLocked(key, time(nullptr) * NS_PER_SEC, &data);
+ onDumpReportLocked(key, getElapsedRealtimeNs(), &data);
// TODO: Add a guardrail to prevent accumulation of file on disk.
string file_name = StringPrintf("%s/%ld_%d_%lld", STATS_DATA_DIR,
(long)getWallClockSec(), key.GetUid(), (long long)key.GetId());
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
index 26db3af..c27b130 100644
--- a/cmds/statsd/src/StatsService.cpp
+++ b/cmds/statsd/src/StatsService.cpp
@@ -493,7 +493,7 @@
}
if (good) {
vector<uint8_t> data;
- mProcessor->onDumpReport(ConfigKey(uid, StrToInt64(name)), time(nullptr) * NS_PER_SEC,
+ mProcessor->onDumpReport(ConfigKey(uid, StrToInt64(name)), getElapsedRealtimeNs(),
&data);
// TODO: print the returned StatsLogReport to file instead of printing to logcat.
if (proto) {
@@ -786,7 +786,7 @@
VLOG("StatsService::getData with Pid %i, Uid %i", ipc->getCallingPid(), ipc->getCallingUid());
if (checkCallingPermission(String16(kPermissionDump))) {
ConfigKey configKey(ipc->getCallingUid(), key);
- mProcessor->onDumpReport(configKey, time(nullptr) * NS_PER_SEC, output);
+ mProcessor->onDumpReport(configKey, getElapsedRealtimeNs(), output);
return Status::ok();
} else {
return Status::fromExceptionCode(binder::Status::EX_SECURITY);
diff --git a/core/java/android/bluetooth/BluetoothUuid.java b/core/java/android/bluetooth/BluetoothUuid.java
index 0a0d214..605dbd2 100644
--- a/core/java/android/bluetooth/BluetoothUuid.java
+++ b/core/java/android/bluetooth/BluetoothUuid.java
@@ -79,9 +79,8 @@
ParcelUuid.fromString("00001132-0000-1000-8000-00805F9B34FB");
public static final ParcelUuid SAP =
ParcelUuid.fromString("0000112D-0000-1000-8000-00805F9B34FB");
- /* TODO: b/69623109 update this value. It will change to 16bit UUID!! */
public static final ParcelUuid HearingAid =
- ParcelUuid.fromString("7312C48F-22CC-497F-85FD-A0616A3B9E05");
+ ParcelUuid.fromString("0000FDF0-0000-1000-8000-00805f9b34fb");
public static final ParcelUuid BASE_UUID =
ParcelUuid.fromString("00000000-0000-1000-8000-00805F9B34FB");
diff --git a/core/java/android/security/keystore/recovery/BadCertificateFormatException.java b/core/java/android/security/keystore/recovery/BadCertificateFormatException.java
index e0781a5..4275c29 100644
--- a/core/java/android/security/keystore/recovery/BadCertificateFormatException.java
+++ b/core/java/android/security/keystore/recovery/BadCertificateFormatException.java
@@ -17,10 +17,8 @@
package android.security.keystore.recovery;
/**
- * Error thrown when the recovery agent supplies an invalid X509 certificate.
- *
+ * @deprecated Not used.
* @hide
- * Deprecated
*/
public class BadCertificateFormatException extends RecoveryControllerException {
public BadCertificateFormatException(String msg) {
diff --git a/core/java/android/security/keystore/recovery/InternalRecoveryServiceException.java b/core/java/android/security/keystore/recovery/InternalRecoveryServiceException.java
index 218d26e..e62bfb1 100644
--- a/core/java/android/security/keystore/recovery/InternalRecoveryServiceException.java
+++ b/core/java/android/security/keystore/recovery/InternalRecoveryServiceException.java
@@ -19,6 +19,7 @@
import android.annotation.SystemApi;
import java.security.GeneralSecurityException;
+
/**
* An error thrown when something went wrong internally in the recovery service.
*
diff --git a/core/java/android/security/keystore/recovery/RecoveryController.java b/core/java/android/security/keystore/recovery/RecoveryController.java
index 0d262c9..0683e02 100644
--- a/core/java/android/security/keystore/recovery/RecoveryController.java
+++ b/core/java/android/security/keystore/recovery/RecoveryController.java
@@ -46,11 +46,11 @@
* <p>The RecoveryController must be paired with a recovery agent. The recovery agent is responsible
* for transporting the keychain to remote trusted hardware. This hardware must prevent brute force
* attempts against the user's lock screen by limiting the number of allowed guesses (to, e.g., 10).
- * After that number of incorrect guesses, the trusted hardware no longer allows access to the
+ * After that number of incorrect guesses, the trusted hardware no longer allows access to the
* key chain.
*
- * <p>For now only the recovery agent itself is able to create keys, so it is expected that the
- * recovery agent is itself the system app.
+ * <p>Only the recovery agent itself is able to create keys, so it is expected that the recovery
+ * agent is itself the system app.
*
* <p>A recovery agent requires the privileged permission
* {@code android.Manifest.permission#RECOVER_KEYSTORE}.
diff --git a/core/java/android/security/keystore/recovery/RecoveryControllerException.java b/core/java/android/security/keystore/recovery/RecoveryControllerException.java
index 2733aca..1af61ce 100644
--- a/core/java/android/security/keystore/recovery/RecoveryControllerException.java
+++ b/core/java/android/security/keystore/recovery/RecoveryControllerException.java
@@ -19,10 +19,8 @@
import java.security.GeneralSecurityException;
/**
- * Base exception for errors thrown by {@link RecoveryController}.
- *
+ * @deprecated Not used.
* @hide
- * Deprecated
*/
public abstract class RecoveryControllerException extends GeneralSecurityException {
RecoveryControllerException() { }
diff --git a/core/java/android/security/keystore/recovery/RecoverySession.java b/core/java/android/security/keystore/recovery/RecoverySession.java
index 069af91..e42c766 100644
--- a/core/java/android/security/keystore/recovery/RecoverySession.java
+++ b/core/java/android/security/keystore/recovery/RecoverySession.java
@@ -50,7 +50,7 @@
}
/**
- * A new session, started by {@code recoveryManager}.
+ * A new session, started by the {@link RecoveryController}.
*/
@RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE)
static RecoverySession newInstance(RecoveryController recoveryController) {
@@ -72,26 +72,6 @@
}
/**
- * Starts a recovery session and returns a blob with proof of recovery secret possession.
- * The method generates a symmetric key for a session, which trusted remote device can use to
- * return recovery key.
- *
- * @param verifierPublicKey Encoded {@code java.security.cert.X509Certificate} with Public key
- * used to create the recovery blob on the source device.
- * Keystore will verify the certificate using root of trust.
- * @param vaultParams Must match the parameters in the corresponding field in the recovery blob.
- * Used to limit number of guesses.
- * @param vaultChallenge Data passed from server for this recovery session and used to prevent
- * replay attacks
- * @param secrets Secrets provided by user, the method only uses type and secret fields.
- * @return The recovery claim. Claim provides a b binary blob with recovery claim. It is
- * encrypted with verifierPublicKey and contains a proof of user secrets, session symmetric
- * key and parameters necessary to identify the counter with the number of failed recovery
- * attempts.
- * @throws CertificateException if the {@code verifierPublicKey} is in an incorrect
- * format.
- * @throws InternalRecoveryServiceException if an unexpected error occurred in the recovery
- * service.
* @deprecated Use {@link #start(CertPath, byte[], byte[], List)} instead.
* @removed
*/
@@ -132,7 +112,7 @@
* @param vaultParams Must match the parameters in the corresponding field in the recovery blob.
* Used to limit number of guesses.
* @param vaultChallenge Data passed from server for this recovery session and used to prevent
- * replay attacks
+ * replay attacks.
* @param secrets Secrets provided by user, the method only uses type and secret fields.
* @return The recovery claim. Claim provides a b binary blob with recovery claim. It is
* encrypted with verifierPublicKey and contains a proof of user secrets, session symmetric
diff --git a/core/jni/android/opengl/util.cpp b/core/jni/android/opengl/util.cpp
index 888db32..b163597 100644
--- a/core/jni/android/opengl/util.cpp
+++ b/core/jni/android/opengl/util.cpp
@@ -622,29 +622,25 @@
// ---------------------------------------------------------------------------
-static int checkInternalFormat(SkColorType colorType, int format, int type)
+static int checkInternalFormat(SkColorType colorType, int internalformat,
+ int type)
{
switch(colorType) {
case kN32_SkColorType:
+ return (type == GL_UNSIGNED_BYTE &&
+ internalformat == GL_RGBA) ? 0 : -1;
case kAlpha_8_SkColorType:
- if (type == GL_UNSIGNED_BYTE)
- return 0;
+ return (type == GL_UNSIGNED_BYTE &&
+ internalformat == GL_ALPHA) ? 0 : -1;
case kARGB_4444_SkColorType:
+ return (type == GL_UNSIGNED_SHORT_4_4_4_4 &&
+ internalformat == GL_RGBA) ? 0 : -1;
case kRGB_565_SkColorType:
- switch (type) {
- case GL_UNSIGNED_SHORT_4_4_4_4:
- case GL_UNSIGNED_SHORT_5_6_5:
- case GL_UNSIGNED_SHORT_5_5_5_1:
- return 0;
- case GL_UNSIGNED_BYTE:
- if (format == GL_LUMINANCE_ALPHA)
- return 0;
- }
- break;
+ return (type == GL_UNSIGNED_SHORT_5_6_5 &&
+ internalformat == GL_RGB) ? 0 : -1;
case kRGBA_F16_SkColorType:
- if (type == GL_HALF_FLOAT && format == GL_RGBA16F)
- return 0;
- break;
+ return (type == GL_HALF_FLOAT &&
+ internalformat == GL_RGBA16F) ? 0 : -1;
default:
break;
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/utils/IconCache.java b/packages/SettingsLib/src/com/android/settingslib/utils/IconCache.java
new file mode 100644
index 0000000..3d55c4f
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/utils/IconCache.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2018 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.settingslib.utils;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
+import android.support.annotation.VisibleForTesting;
+import android.support.v4.util.ArrayMap;
+
+
+/**
+ * Icon cache to avoid multiple loads on the same icon.
+ */
+public class IconCache {
+ private final Context mContext;
+ @VisibleForTesting
+ final ArrayMap<Icon, Drawable> mMap = new ArrayMap<>();
+
+ public IconCache(Context context) {
+ mContext = context;
+ }
+
+ public Drawable getIcon(Icon icon) {
+ if (icon == null) {
+ return null;
+ }
+ Drawable drawable = mMap.get(icon);
+ if (drawable == null) {
+ drawable = icon.loadDrawable(mContext);
+ updateIcon(icon, drawable);
+ }
+ return drawable;
+ }
+
+ public void updateIcon(Icon icon, Drawable drawable) {
+ mMap.put(icon, drawable);
+ }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
index df1a7a8..2482095 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
@@ -527,10 +527,7 @@
WifiConfiguration connectionConfig = null;
if (mLastInfo != null) {
- // TODO(sghuman): Refactor to match config network id when updating configs below, and
- // then update network info and wifi info only on match
- connectionConfig = getWifiConfigurationForNetworkId(
- mLastInfo.getNetworkId(), configs);
+ connectionConfig = getWifiConfigurationForNetworkId(mLastInfo.getNetworkId(), configs);
}
// Rather than dropping and reacquiring the lock multiple times in this method, we lock
@@ -564,6 +561,17 @@
accessPoints.add(accessPoint);
}
+ // If there were no scan results, create an AP for the currently connected network (if
+ // it exists).
+ // TODO(sghuman): Investigate if this works for an ephemeral (auto-connected) network
+ // when there are no scan results, as it may not have a valid WifiConfiguration
+ if (accessPoints.isEmpty() && connectionConfig != null) {
+ AccessPoint activeAp = new AccessPoint(mContext, connectionConfig);
+ activeAp.update(connectionConfig, mLastInfo, mLastNetworkInfo);
+ accessPoints.add(activeAp);
+ scoresToRequest.add(NetworkKey.createFromWifiInfo(mLastInfo));
+ }
+
requestScoresForNetworkKeys(scoresToRequest);
for (AccessPoint ap : accessPoints) {
ap.update(mScoreCache, mNetworkScoringUiEnabled, mMaxSpeedLabelScoreCacheAge);
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
index 8fd4700..ca965f3 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
@@ -696,6 +696,36 @@
}
@Test
+ public void onStartShouldDisplayConnectedAccessPointWhenThereAreNoScanResults()
+ throws Exception {
+ Network mockNetwork = mock(Network.class);
+ when(mockWifiManager.getCurrentNetwork()).thenReturn(mockNetwork);
+
+ when(mockWifiManager.getConnectionInfo()).thenReturn(CONNECTED_AP_1_INFO);
+
+ NetworkInfo networkInfo = new NetworkInfo(
+ ConnectivityManager.TYPE_WIFI, 0, "Type Wifi", "subtype");
+ networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, "connected", "test");
+ when(mockConnectivityManager.getNetworkInfo(any(Network.class))).thenReturn(networkInfo);
+
+ // Don't return any scan results
+ when(mockWifiManager.getScanResults()).thenReturn(new ArrayList<>());
+
+ WifiTracker tracker = createMockedWifiTracker();
+ startTracking(tracker);
+
+ verify(mockWifiManager).getConnectionInfo();
+ verify(mockWifiManager, times(1)).getConfiguredNetworks();
+ verify(mockConnectivityManager).getNetworkInfo(any(Network.class));
+
+ // mStaleAccessPoints is true
+ verify(mockWifiListenerExecutor, never()).onAccessPointsChanged();
+
+ assertThat(tracker.getAccessPoints().size()).isEqualTo(1);
+ assertThat(tracker.getAccessPoints().get(0).isActive()).isTrue();
+ }
+
+ @Test
public void stopTrackingShouldRemoveAllPendingWork() throws Exception {
WifiTracker tracker = createMockedWifiTracker();
startTracking(tracker);
@@ -778,7 +808,7 @@
mAccessPointsChangedLatch = new CountDownLatch(1);
tracker.mReceiver.onReceive(mContext, new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION));
- assertThat(mAccessPointsChangedLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
+ assertThat(mAccessPointsChangedLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS)).isTrue();
assertThat(tracker.getAccessPoints()).isEmpty();
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/IconCacheTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/IconCacheTest.java
new file mode 100644
index 0000000..026ad47
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/IconCacheTest.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2018 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.settingslib.utils;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static junit.framework.Assert.assertTrue;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(RobolectricTestRunner.class)
+public class IconCacheTest {
+ private Icon mIcon;
+ private Context mContext;
+ private IconCache mIconCache;
+
+ @Before
+ public void setUp() {
+ mContext = spy(RuntimeEnvironment.application);
+ mIcon = mock(Icon.class);
+ Drawable drawable = mock(Drawable.class);
+ doReturn(drawable).when(mIcon).loadDrawable(mContext);
+ mIconCache = new IconCache(mContext);
+ }
+
+ @Test
+ public void testGetIcon_iconisNull() {
+ assertThat(mIconCache.getIcon(null)).isNull();
+ }
+
+ @Test
+ public void testGetIcon_iconAlreadyLoaded() {
+ mIconCache.getIcon(mIcon);
+ verify(mIcon, times(1)).loadDrawable(mContext);
+ mIconCache.getIcon(mIcon);
+ verify(mIcon, times(1)).loadDrawable(mContext);
+ }
+
+ @Test
+ public void testGetIcon_iconLoadedFirstTime() {
+ mIconCache.getIcon(mIcon);
+ assertTrue(mIconCache.mMap.containsKey(mIcon));
+ }
+}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index be1aa46..0d9a37a 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2125,6 +2125,10 @@
win.setLastReportedMergedConfiguration(mergedConfiguration);
+ // Update the last inset values here because the values are sent back to the client.
+ // The last inset values represent the last client state.
+ win.updateLastInsetValues();
+
outFrame.set(win.mCompatFrame);
outOverscanInsets.set(win.mOverscanInsets);
outContentInsets.set(win.mContentInsets);
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index a7fc470..ef0780a 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -1359,9 +1359,7 @@
UsbManager.USB_FUNCTION_NONE).equals(
getSystemProperty(USB_STATE_PROPERTY, UsbManager.USB_FUNCTION_NONE));
}
- // Mask out adb, since it is stored in mAdbEnabled
- mCurrentFunctions = UsbManager.usbFunctionsFromString(mCurrentFunctionsStr)
- & ~UsbManager.FUNCTION_ADB;
+ mCurrentFunctions = UsbManager.FUNCTION_NONE;
mCurrentUsbFunctionsReceived = true;
String state = FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim();
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java
index 0401737..db48984 100644
--- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java
@@ -57,7 +57,9 @@
Button mCompleteButton;
Button mAbortButton;
+ Bundle mAssistData;
AssistStructure mAssistStructure;
+ AssistContent mAssistContent;
static final int STATE_IDLE = 0;
static final int STATE_LAUNCHING = 1;
@@ -169,19 +171,15 @@
public void onHandleAssist(Bundle assistBundle) {
}
- @Override
- public void onHandleAssist(Bundle data, AssistStructure structure, AssistContent content) {
- mAssistStructure = structure;
- if (mAssistVisualizer != null) {
- if (mAssistStructure != null) {
- mAssistVisualizer.setAssistStructure(mAssistStructure);
- } else {
- mAssistVisualizer.clearAssistData();
- }
- }
+ private void logAssistContentAndData(AssistContent content, Bundle data) {
if (content != null) {
Log.i(TAG, "Assist intent: " + content.getIntent());
+ Log.i(TAG, "Assist intent from app: " + content.isAppProvidedIntent());
Log.i(TAG, "Assist clipdata: " + content.getClipData());
+ Log.i(TAG, "Assist structured data: " + content.getStructuredData());
+ Log.i(TAG, "Assist web uri: " + content.getWebUri());
+ Log.i(TAG, "Assist web uri from app: " + content.isAppProvidedWebUri());
+ Log.i(TAG, "Assist extras: " + content.getExtras());
}
if (data != null) {
Uri referrer = data.getParcelable(Intent.EXTRA_REFERRER);
@@ -192,6 +190,21 @@
}
@Override
+ public void onHandleAssist(Bundle data, AssistStructure structure, AssistContent content) {
+ mAssistData = data;
+ mAssistStructure = structure;
+ mAssistContent = content;
+ if (mAssistVisualizer != null) {
+ if (mAssistStructure != null) {
+ mAssistVisualizer.setAssistStructure(mAssistStructure);
+ } else {
+ mAssistVisualizer.clearAssistData();
+ }
+ }
+ logAssistContentAndData(content, data);
+ }
+
+ @Override
public void onHandleAssistSecondary(final Bundle data, final AssistStructure structure,
final AssistContent content, int index, int count) {
Log.i(TAG, "Got secondary activity assist data " + index + " of " + count);
@@ -246,6 +259,7 @@
public void onClick(View v) {
if (v == mTreeButton) {
if (mAssistVisualizer != null) {
+ logAssistContentAndData(mAssistContent, mAssistData);
mAssistVisualizer.logTree();
}
} else if (v == mTextButton) {