Skip to content

Commit

Permalink
Merge pull request #1226 from microsoft/develop
Browse files Browse the repository at this point in the history
Version 2.3.0
  • Loading branch information
zhangcc01 authored Aug 14, 2019
2 parents feb3047 + e33f482 commit bc91ca8
Show file tree
Hide file tree
Showing 15 changed files with 528 additions and 11 deletions.
27 changes: 27 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,26 @@
# App Center SDK for Android Change Log

## Version 2.3.0

### App Center Crashes

* **[Feature]** Catch "low memory warning" and provide the API to check if it has happened in last session: `Crashes.hasReceivedMemoryWarningInLastSession()`.

### App Center Push

* **[Fix]** Fix confusing information log about the availability of the Firebase SDK.

### App Center Auth

* **[Feature]** App Center Auth logging now includes MSAL logs.
* **[Fix]** Redirect URIs are now hidden in logs.

### App Center Push

* **[Fix]** Fix sending the push installation log after delayed start.

___

## Version 2.2.0

### App Center
Expand All @@ -22,6 +43,8 @@
* **[Fix]** Fix declaring `gson` as a build time dependency instead of runtime.
* **[Fix]** Allow null for `ReadOptions` and `WriteOptions` parameters.

___

## Version 2.1.0

### App Center
Expand Down Expand Up @@ -60,6 +83,8 @@

* **[Fix]** Update Firebase dependency and AppCenter push logic to avoid a runtime issue with the latest Firebase messaging version 18.0.0.

___

## Version 2.0.0

Version 2 of the App Center SDK includes two new modules: Auth and Data.
Expand All @@ -85,6 +110,8 @@ The App Center Data service provides functionality enabling developers to persis
* **[Feature]** After calling `Auth.signIn`, the push installation is associated to the signed in user with an `accountId` and can be pushed by using the `accountId` audience. This is a different field than the `userId` set by `AppCenter.setUserId`. The push installation is also updated on calling `Auth.signOut` to stop the association.
* **[Fix]** Fix updating push installation when setting or unsetting the user identifier by calling `AppCenter.setUserId`.

___

## Version 1.11.4

### AppCenter
Expand Down
20 changes: 20 additions & 0 deletions apps/sasquatch/src/main/cpp/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <string>
#include <stdio.h>
#include <string.h>
#include <vector>
#include "android/log.h"
#include "google-breakpad/src/client/linux/handler/exception_handler.h"
#include "google-breakpad/src/client/linux/handler/minidump_descriptor.h"
Expand Down Expand Up @@ -88,6 +89,25 @@ Java_com_microsoft_appcenter_sasquatch_activities_CrashActivity_nativeDereferenc
}
#pragma clang diagnostic pop

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-parameter"
#pragma ide diagnostic ignored "OCDFAInspection"
#pragma clang diagnostic ignored "-Wmissing-noreturn"
#pragma ide diagnostic ignored "cppcoreguidelines-avoid-magic-numbers"

static std::vector<void*> data;

void
Java_com_microsoft_appcenter_sasquatch_activities_CrashActivity_nativeAllocateLargeBuffer(
JNIEnv *env,
jobject obj) {
size_t size = 128 * 1024 * 1024;
void *buffer = malloc(size);
memset(buffer, 42, size);
data.push_back(buffer);
}
#pragma clang diagnostic pop

#pragma clang diagnostic push
#pragma ide diagnostic ignored "InfiniteRecursion"
void Java_com_microsoft_appcenter_sasquatch_activities_CrashActivity_nativeStackOverflowCrash(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@
package com.microsoft.appcenter.sasquatch.activities;

import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
Expand All @@ -22,11 +26,14 @@
import com.microsoft.appcenter.crashes.model.TestCrashException;
import com.microsoft.appcenter.sasquatch.R;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;

import static com.microsoft.appcenter.sasquatch.activities.CrashSubActivity.INTENT_EXTRA_CRASH_TYPE;
import static com.microsoft.appcenter.sasquatch.activities.MainActivity.LOG_TAG;

public class CrashActivity extends AppCompatActivity {

Expand Down Expand Up @@ -158,9 +165,27 @@ public void run() {
public void run() {
nativeAbortCall();
}
}),
new Crash(R.string.title_low_memory_warning, R.string.description_low_memory_warning, new Runnable() {

@Override
public void run() {
final AtomicInteger i = new AtomicInteger(0);
final Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
nativeAllocateLargeBuffer();
Log.d(LOG_TAG, "Memory allocated: " + i.addAndGet(128) + "MB");
handler.post(this);
}
});
}
})
);

private native void nativeAllocateLargeBuffer();

private native void nativeDereferenceNullPointer();

private native void nativeStackOverflowCrash();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@

import android.app.Activity;
import android.content.Intent;
import android.support.annotation.Nullable;
import android.view.View;
import android.widget.AdapterView;

import com.microsoft.appcenter.crashes.Crashes;
import com.microsoft.appcenter.sasquatch.R;
import com.microsoft.appcenter.sasquatch.activities.AuthenticationProviderActivity;
import com.microsoft.appcenter.sasquatch.activities.CrashActivity;
Expand All @@ -20,8 +22,10 @@
import com.microsoft.appcenter.sasquatch.activities.EventActivity;
import com.microsoft.appcenter.sasquatch.activities.ManagedErrorActivity;
import com.microsoft.appcenter.sasquatch.activities.PageActivity;
import com.microsoft.appcenter.utils.async.AppCenterFuture;

import java.lang.ref.WeakReference;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

Expand All @@ -42,13 +46,26 @@ public static void initialize(Activity parentActivity) {
sTestFeatureModels.add(new TestFeatureTitle(R.string.crashes_title));
sTestFeatureModels.add(new TestFeature(R.string.title_crashes, R.string.description_crashes, CrashActivity.class));
sTestFeatureModels.add(new TestFeature(R.string.title_error, R.string.description_error, ManagedErrorActivity.class));
sTestFeatureModels.add(new TestFeature(R.string.title_had_memory_warning, hadMemoryWarning() ? R.string.description_had_memory_warning : R.string.description_did_not_have_memory_warning));
sTestFeatureModels.add(new TestFeatureTitle(R.string.miscellaneous_title));
sTestFeatureModels.add(new TestFeature(R.string.title_custom_properties, R.string.description_custom_properties, CustomPropertiesActivity.class));
sTestFeatureModels.add(new TestFeature(R.string.title_device_info, R.string.description_device_info, DeviceInfoActivity.class));
sTestFeatureModels.add(new TestFeatureTitle(R.string.title_data));
sTestFeatureModels.add(new TestFeature(R.string.title_data, R.string.description_data, DataActivity.class));
}

@SuppressWarnings("unchecked")
private static boolean hadMemoryWarning() {

/* TODO: Replace with return Crashes.hadMemoryWarningInLastSession().get(); when updating the demo during release process. */
try {
Method hadMemoryWarning = Crashes.class.getMethod("hasReceivedMemoryWarningInLastSession");
return ((AppCenterFuture<Boolean>) hadMemoryWarning.invoke(null)).get();
} catch (Exception e) {
return false;
}
}

public static List<TestFeatureModel> getAvailableControls() {
return sTestFeatureModels;
}
Expand All @@ -61,7 +78,9 @@ public void onItemClick(AdapterView<?> parent, View view, int position, long id)
Object item = parent.getItemAtPosition(position);
if (item instanceof TestFeature) {
TestFeature model = (TestFeature) item;
model.mOnClickListener.onClick(view);
if (model.mOnClickListener != null) {
model.mOnClickListener.onClick(view);
}
}
}
};
Expand Down Expand Up @@ -103,11 +122,15 @@ public static class TestFeature extends TestFeatureModel {

private final View.OnClickListener mOnClickListener;

TestFeature(int title, int description) {
this(title, description, (View.OnClickListener)null);
}

TestFeature(int title, int description, Class<? extends Activity> clazz) {
this(title, description, getDefaultOnClickListener(clazz));
}

public TestFeature(int title, int description, View.OnClickListener listener) {
public TestFeature(int title, int description, @Nullable View.OnClickListener listener) {
super(title);
this.mDescription = description > 0 ? sParentActivity.get().getResources().getString(description) : "";
this.mOnClickListener = listener;
Expand Down
2 changes: 2 additions & 0 deletions apps/sasquatch/src/main/res/values/crashes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
<string name="description_native_stack_overflow_crash" tools:ignore="MissingTranslation">Caused by infinite recursion</string>
<string name="title_native_abort_crash" tools:ignore="MissingTranslation">NDK call abort()</string>
<string name="description_native_abort_crash" tools:ignore="MissingTranslation">Simply call abort() to terminate</string>
<string name="title_low_memory_warning" tools:ignore="MissingTranslation">Low memory warning</string>
<string name="description_low_memory_warning" tools:ignore="MissingTranslation">Generate low memory warning/crash</string>
<string name="crash_confirmation_dialog_title" tools:ignore="MissingTranslation">Unexpected crash found</string>
<string name="crash_confirmation_dialog_message" tools:ignore="MissingTranslation">Would you like to send an anonymous report so we can fix the problem?</string>
<string name="crash_confirmation_dialog_not_send_button" tools:ignore="MissingTranslation">Don\'t Send</string>
Expand Down
3 changes: 3 additions & 0 deletions apps/sasquatch/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
<string name="error_device_info" tools:ignore="MissingTranslation">Could not retrieve device information</string>
<string name="title_error" tools:ignore="MissingTranslation">Errors</string>
<string name="description_error" tools:ignore="MissingTranslation">Send an exception</string>
<string name="title_had_memory_warning" tools:ignore="MissingTranslation">Low memory warning</string>
<string name="description_had_memory_warning" tools:ignore="MissingTranslation">The application had a memory warning</string>
<string name="description_did_not_have_memory_warning" tools:ignore="MissingTranslation">The application didn\'t have a memory warning</string>
<string name="title_event" tools:ignore="MissingTranslation">Events</string>
<string name="description_event" tools:ignore="MissingTranslation">Send a custom event</string>
<string name="title_event_properties" tools:ignore="MissingTranslation">Event properties</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
import com.microsoft.identity.client.AuthenticationCallback;
import com.microsoft.identity.client.IAccount;
import com.microsoft.identity.client.IAuthenticationResult;
import com.microsoft.identity.client.ILoggerCallback;
import com.microsoft.identity.client.Logger;
import com.microsoft.identity.client.PublicClientApplication;
import com.microsoft.identity.client.exception.MsalException;
import com.microsoft.identity.client.exception.MsalUiRequiredException;
Expand Down Expand Up @@ -74,6 +76,32 @@
*/
public class Auth extends AbstractAppCenterService implements NetworkStateHelper.Listener {

/**
* Delimiter between two tags.
*/
@VisibleForTesting
static final String TAG_DELIMITER = ":";

@VisibleForTesting
static final ILoggerCallback AUTHENTICATION_EXTERNAL_LOGGER = new ILoggerCallback() {

@Override
public void log(String tag, Logger.LogLevel logLevel, String message, boolean containsPII) {
if (!containsPII) {
String prefixedTag = LOG_TAG + TAG_DELIMITER + tag;
if (Logger.LogLevel.VERBOSE == logLevel) {
AppCenterLog.verbose(prefixedTag, message);
} else if (Logger.LogLevel.INFO == logLevel) {
AppCenterLog.info(prefixedTag, message);
} else if (Logger.LogLevel.WARNING == logLevel) {
AppCenterLog.warn(prefixedTag, message);
} else if (Logger.LogLevel.ERROR == logLevel) {
AppCenterLog.error(prefixedTag, message);
}
}
}
};

/**
* Shared instance.
*/
Expand Down Expand Up @@ -214,6 +242,16 @@ public synchronized void onStarted(@NonNull Context context, @NonNull Channel ch
mContext = context;
mAppSecret = appSecret;

/* Setup MSAL Logging. */
Logger.getInstance().setLogLevel(Logger.LogLevel.VERBOSE);
try {
Logger.getInstance().setExternalLogger(AUTHENTICATION_EXTERNAL_LOGGER);
} catch (Exception e) {

/* Should only happen in tests when resetting the external logger. */
AppCenterLog.warn(LOG_TAG, "Enabling MSAL logging failed.", e);
}

/* The auth token from the previous launch is required. */
AuthTokenContext.getInstance().doNotResetAuthAfterStart();
super.onStarted(context, channel, appSecret, transmissionTargetToken, startedFromApp);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import com.microsoft.identity.client.IAccount;
import com.microsoft.identity.client.IAccountIdentifier;
import com.microsoft.identity.client.IAuthenticationResult;
import com.microsoft.identity.client.Logger;
import com.microsoft.identity.client.PublicClientApplication;
import com.microsoft.identity.client.exception.MsalClientException;
import com.microsoft.identity.client.exception.MsalException;
Expand All @@ -57,7 +58,11 @@
import java.util.UUID;
import java.util.concurrent.CancellationException;

import static android.util.Log.VERBOSE;
import static com.microsoft.appcenter.auth.Auth.AUTHENTICATION_EXTERNAL_LOGGER;
import static com.microsoft.appcenter.auth.Auth.TAG_DELIMITER;
import static com.microsoft.appcenter.auth.Constants.HEADER_IF_NONE_MATCH;
import static com.microsoft.appcenter.auth.Constants.LOG_TAG;
import static com.microsoft.appcenter.auth.Constants.PREFERENCE_E_TAG_KEY;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
Expand All @@ -72,6 +77,7 @@
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.anyMapOf;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.contains;
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.isNull;
import static org.mockito.Matchers.notNull;
Expand Down Expand Up @@ -149,6 +155,56 @@ private static void mockHttpCallSuccess(JSONObject jsonConfig, ServiceCallback s
serviceCallback.onCallSucceeded(jsonConfig.toString(), headers);
}

@Test
public void forwardMsalLogging() {
AppCenterLog.setLogLevel(VERBOSE);
String tag = "msalTag";
String expectedTag = LOG_TAG + TAG_DELIMITER + tag;
String message = "Message from MSAL";
AUTHENTICATION_EXTERNAL_LOGGER.log(tag, Logger.LogLevel.VERBOSE, message, false);
verifyStatic();
AppCenterLog.verbose(eq(expectedTag), contains(message));
AUTHENTICATION_EXTERNAL_LOGGER.log(tag, Logger.LogLevel.INFO, message, false);
verifyStatic();
AppCenterLog.info(eq(expectedTag), contains(message));
AUTHENTICATION_EXTERNAL_LOGGER.log(tag, Logger.LogLevel.WARNING, message, false);
verifyStatic();
AppCenterLog.warn(eq(expectedTag), contains(message));
AUTHENTICATION_EXTERNAL_LOGGER.log(tag, Logger.LogLevel.ERROR, message, false);
verifyStatic();
AppCenterLog.error(eq(expectedTag), contains(message));
}

@Test
public void dontForwardMsalLoggingForUnknownLoglevel() {
AppCenterLog.setLogLevel(VERBOSE);
String tag = "msalTag";
String expectedTag = LOG_TAG + TAG_DELIMITER + tag;
String message = "Message from MSAL";
AUTHENTICATION_EXTERNAL_LOGGER.log(tag, null, message, false);
verifyStatic(never());
AppCenterLog.verbose(eq(expectedTag), contains(message));
verifyStatic(never());
AppCenterLog.debug(eq(expectedTag), contains(message));
verifyStatic(never());
AppCenterLog.info(eq(expectedTag), contains(message));
verifyStatic(never());
AppCenterLog.warn(eq(expectedTag), contains(message));
verifyStatic(never());
AppCenterLog.error(eq(expectedTag), contains(message));
verifyStatic(never());
AppCenterLog.logAssert(eq(expectedTag), contains(message));
}

@Test
public void dontForwardPiiFromMsalLogging() {
AppCenterLog.setLogLevel(VERBOSE);
start(Auth.getInstance());
AUTHENTICATION_EXTERNAL_LOGGER.log("msalTag", Logger.LogLevel.VERBOSE, "Message from MSAL", true);
verifyStatic(never());
AppCenterLog.verbose(anyString(), anyString());
}

@Test
public void singleton() {
assertSame(Auth.getInstance(), Auth.getInstance());
Expand Down
Loading

0 comments on commit bc91ca8

Please sign in to comment.