- Merging Dev-Kairos/Engine/... to Main/Engine/...

- Brings over the necessary engine changes for embedding UE4 mobile as a dylib/so in native mobile app
- Various changes for facial animation, screen recording, others
- ARKit and ARCore plugins were removed, as deemed "not ready"
#rb many people

#ROBOMERGE-OWNER: ben.marsh
#ROBOMERGE-AUTHOR: josh.adams
#ROBOMERGE-SOURCE: CL 5201138 via CL 5203024 via CL 5226277
#ROBOMERGE-BOT: BUILD (Main -> Dev-Build)

[CL 5243833 by josh adams in Dev-Build branch]
This commit is contained in:
josh adams
2019-02-28 17:02:41 -05:00
parent 1549dc931e
commit b3cc809913
385 changed files with 40324 additions and 2907 deletions

View File

@@ -174,6 +174,8 @@ import com.epicgames.ue4.GooglePlayLicensing;
// Console commands listener, only for debug builds
import com.epicgames.ue4.ConsoleCmdReceiver;
import com.epicgames.ue4.MultiChannelMediaEncoder;
import android.os.Build;
// TODO: use the resources from the UE4 lib project once we've got the packager up and running
@@ -213,7 +215,7 @@ import android.content.BroadcastReceiver;
// Java libraries at the startup of the program and store references
// to them in this class.
public class GameActivity extends NativeActivity implements SurfaceHolder.Callback2,
public class GameActivity extends $${gameActivitySuperClass}$$ implements SurfaceHolder.Callback2,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
SensorEventListener,
@@ -456,8 +458,6 @@ public class GameActivity extends NativeActivity implements SurfaceHolder.Callba
private String localNotificationLaunchActivationEvent = "";
private int localNotificationLaunchFireDate = 0;
public int DeviceRotation = -1;
enum EAlertDialogType
{
None,
@@ -518,14 +518,6 @@ public class GameActivity extends NativeActivity implements SurfaceHolder.Callba
Configuration config = getResources().getConfiguration();
int rotation = windowManager.getDefaultDisplay().getRotation();
switch (rotation)
{
case Surface.ROTATION_0: DeviceRotation = 0; break;
case Surface.ROTATION_90: DeviceRotation = 90; break;
case Surface.ROTATION_180: DeviceRotation = 180; break;
case Surface.ROTATION_270: DeviceRotation = 270; break;
}
if ( ((rotation == android.view.Surface.ROTATION_0 || rotation == android.view.Surface.ROTATION_180) &&
config.orientation == Configuration.ORIENTATION_LANDSCAPE)
|| ((rotation == android.view.Surface.ROTATION_90 || rotation == android.view.Surface.ROTATION_270) &&
@@ -539,6 +531,23 @@ public class GameActivity extends NativeActivity implements SurfaceHolder.Callba
}
}
public int getCurrentDeviceRotationDegree()
{
// onConfigurationChanged won't be called if orientation changes from landscape/portrait to reverse landscape/portrait
// use this function instead of caching DeviceRotation
int orientation = AndroidThunkJava_GetDeviceOrientation();
switch (orientation)
{
case Surface.ROTATION_0: return 0;
case Surface.ROTATION_90: return 90;
case Surface.ROTATION_180: return 180;
case Surface.ROTATION_270: return 270;
}
return 0;
}
private int getResourceId(String VariableName, String ResourceName, String PackageName)
{
try {
@@ -703,7 +712,7 @@ public class GameActivity extends NativeActivity implements SurfaceHolder.Callba
}
}
private byte[] getByteArrayFromFile(String filename)
public static byte[] getByteArrayFromFile(String filename)
{
try
{
@@ -1935,6 +1944,16 @@ public class GameActivity extends NativeActivity implements SurfaceHolder.Callba
//$${gameActivityLoggerCallbackAdditions}$$
}
protected View GetMainView()
{
return mainView;
}
protected FrameLayout GetContainerFrameLayout()
{
return containerFrameLayout;
}
@Override
public void onCreate(Bundle savedInstanceState)
{
@@ -1951,9 +1970,9 @@ public class GameActivity extends NativeActivity implements SurfaceHolder.Callba
_extrasBundle = getIntent().getExtras();
if (_extrasBundle != null)
{
ShouldHideUI = _extrasBundle.getString("ShouldHideUI") != null;
UseDisplayCutout = _extrasBundle.getString("UseDisplayCutout") != null;
if (_extrasBundle.getString("UseSplashScreen") != null)
ShouldHideUI = _extrasBundle.getBoolean("ShouldHideUI", false);
UseDisplayCutout = _extrasBundle.getBoolean("UseDisplayCutout", false);
if (_extrasBundle.getBoolean("UseSplashScreen", false))
{
SplashScreenLaunch = true;
try {
@@ -3264,14 +3283,6 @@ public class GameActivity extends NativeActivity implements SurfaceHolder.Callba
{
super.onConfigurationChanged(newConfig);
switch (getWindowManager().getDefaultDisplay().getRotation())
{
case Surface.ROTATION_0: DeviceRotation = 0; break;
case Surface.ROTATION_90: DeviceRotation = 90; break;
case Surface.ROTATION_180: DeviceRotation = 180; break;
case Surface.ROTATION_270: DeviceRotation = 270; break;
}
// forward the orientation
boolean bPortrait = newConfig.orientation == Configuration.ORIENTATION_PORTRAIT;
nativeOnConfigurationChanged(bPortrait);
@@ -4343,9 +4354,9 @@ public class GameActivity extends NativeActivity implements SurfaceHolder.Callba
}
}
private int LocalNotificationGetID()
public static int LocalNotificationGetID(Context context)
{
SharedPreferences preferences = getApplicationContext().getSharedPreferences("LocalNotificationPreferences", MODE_PRIVATE);
SharedPreferences preferences = context.getSharedPreferences("LocalNotificationPreferences", MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
String notificationIDs = preferences.getString("notificationIDs", "");
@@ -4446,7 +4457,7 @@ public class GameActivity extends NativeActivity implements SurfaceHolder.Callba
public void AndroidThunkJava_LocalNotificationScheduleAtTime(String targetDateTime, boolean localTime, String title, String body, String action, String activationEvent)
{
int notificationID = LocalNotificationGetID();
int notificationID = LocalNotificationGetID(this);
// Create callback for PendingIntent
Intent notificationIntent = new Intent(this, LocalNotificationReceiver.class);
@@ -5301,6 +5312,11 @@ public class GameActivity extends NativeActivity implements SurfaceHolder.Callba
}
protected List<View> GetExtraIgnoreViews()
{
return null;
}
//check if the new virtual keyboard input has received a MOUSE_DOWN event
// or the keyboard animation is playing
public boolean AndroidThunkJava_VirtualInputIgnoreClick(int x, int y)
@@ -5316,6 +5332,24 @@ public class GameActivity extends NativeActivity implements SurfaceHolder.Callba
return true;
}
}
else
{
List<View> ExtraIgnoreViews = GetExtraIgnoreViews();
if (ExtraIgnoreViews != null)
{
for (int i = 0; i < ExtraIgnoreViews.size(); i++)
{
Rect r = new Rect();
ExtraIgnoreViews.get(i).getGlobalVisibleRect(r);
if (r.contains(x, y))
{
//Log.debug("Webview: AndroidThunkJava_VirtualInputIgnoreClick true");
return true;
}
}
}
}
//Log.debug("VK: AndroidThunkJava_VirtualInputIgnoreClick false");
return false;
}
@@ -5447,7 +5481,7 @@ public class GameActivity extends NativeActivity implements SurfaceHolder.Callba
return true;
}
public void AndroidThunkJava_RestartApplication()
public void AndroidThunkJava_RestartApplication(String RestartExtra)
{
Context context = getApplicationContext();
@@ -5457,6 +5491,7 @@ public class GameActivity extends NativeActivity implements SurfaceHolder.Callba
// make an "restart intent", to be used to re-launch an application's task in its base state
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.putExtra("RestartExtra", RestartExtra);
context.startActivity(intent);
// kill the current application instance. Undefined behaviour after this!
@@ -5479,6 +5514,11 @@ public class GameActivity extends NativeActivity implements SurfaceHolder.Callba
return "";
}
public int AndroidThunkJava_GetDeviceOrientation()
{
return getWindowManager().getDefaultDisplay().getRotation();
}
@SuppressWarnings("deprecation")
public boolean AndroidThunkJava_CookieManager_SetCookie(String Url, String Value)
{

View File

@@ -1,29 +1,34 @@
// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
package com.epicgames.ue4;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.NotificationChannel;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.NotificationCompat;
public class LocalNotificationReceiver extends BroadcastReceiver
{
private static boolean bChannelExists = false;
private static final String NOTIFICATION_CHANNEL_ID = "ue4-push-notification-channel-id";
private static final CharSequence NOTICATION_CHANNEL_NAME = "ue4-push-notification-channel";
public void onReceive(Context context, Intent intent)
{
int notificationID = intent.getIntExtra("local-notification-ID" , 0);
String title = intent.getStringExtra("local-notification-title");
String details = intent.getStringExtra("local-notification-body");
String action = intent.getStringExtra("local-notification-action");
String activationEvent = intent.getStringExtra("local-notification-activationEvent");
package com.epicgames.ue4;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.NotificationChannel;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.NotificationCompat;
public class LocalNotificationReceiver extends BroadcastReceiver
{
private static final String NOTIFICATION_CHANNEL_ID = "ue4-push-notification-channel-id";
private static final CharSequence NOTICATION_CHANNEL_NAME = "ue4-push-notification-channel";
public static final String KEY_LOCAL_NOTIFICATION_ID = "local-notification-ID";
public static final String KEY_LOCAL_NOTIFICATION_TITLE = "local-notification-title";
public static final String KEY_LOCAL_NOTIFICATION_BODY = "local-notification-body";
public static final String KEY_LOCAL_NOTIFICATION_ACTION = "local-notification-action";
public static final String KEY_LOCAL_NOTIFICATION_ACTION_EVENT = "local-notification-activationEvent";
public void onReceive(Context context, Intent intent)
{
int notificationID = intent.getIntExtra(KEY_LOCAL_NOTIFICATION_ID , 0);
String title = intent.getStringExtra(KEY_LOCAL_NOTIFICATION_TITLE);
String details = intent.getStringExtra(KEY_LOCAL_NOTIFICATION_BODY);
String action = intent.getStringExtra(KEY_LOCAL_NOTIFICATION_ACTION);
String activationEvent = intent.getStringExtra(KEY_LOCAL_NOTIFICATION_ACTION_EVENT);
if(title == null || details == null || action == null || activationEvent == null)
{
@@ -40,14 +45,11 @@
notificationIntent.putExtra("localNotificationAppLaunched" , true);
notificationIntent.putExtra("localNotificationLaunchActivationEvent", activationEvent);
int notificationIconID = context.getResources().getIdentifier("ic_notification", "drawable", context.getPackageName());
if (notificationIconID == 0)
{
notificationIconID = context.getResources().getIdentifier("icon", "drawable", context.getPackageName());
}
int notificationIconID = getNotificationIconID(context);
PendingIntent pendingNotificationIntent = PendingIntent.getActivity(context, notificationID, notificationIntent, 0);
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
@SuppressWarnings("deprecation")
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID)
.setSmallIcon(notificationIconID)
.setContentIntent(pendingNotificationIntent)
@@ -62,13 +64,16 @@
if (android.os.Build.VERSION.SDK_INT >= 26)
{
if (!bChannelExists)
if(notificationManager != null)
{
NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, NOTICATION_CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT);
channel.enableVibration(true);
channel.enableLights(true);
notificationManager.createNotificationChannel(channel);
bChannelExists = true;
NotificationChannel channel = notificationManager.getNotificationChannel(NOTIFICATION_CHANNEL_ID);
if (channel == null)
{
channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, NOTICATION_CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT);
channel.enableVibration(true);
channel.enableLights(true);
notificationManager.createNotificationChannel(channel);
}
}
}
Notification notification = builder.build();
@@ -77,8 +82,20 @@
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.defaults |= Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE;
// show the notification
notificationManager.notify(notificationID, notification);
}
}
if(notificationManager != null)
{
// show the notification
notificationManager.notify(notificationID, notification);
}
}
public static int getNotificationIconID(Context context)
{
int notificationIconID = context.getResources().getIdentifier("ic_notification", "drawable", context.getPackageName());
if (notificationIconID == 0)
{
notificationIconID = context.getResources().getIdentifier("icon", "drawable", context.getPackageName());
}
return notificationIconID;
}
}

View File

@@ -13,13 +13,16 @@ public class Logger
private String mTag;
private static boolean bAllowLogging = true;
@SuppressWarnings({"FieldCanBeLocal", "unused"})
private static boolean bAllowExceptionLogging = true;
@SuppressWarnings("unused")
public static void RegisterCallback(ILoggerCallback callback)
{
mCallback = callback;
}
@SuppressWarnings("WeakerAccess")
public static void SuppressLogs ()
{
bAllowLogging = bAllowExceptionLogging = false;
@@ -29,7 +32,19 @@ public class Logger
{
mTag = Tag;
}
public void verbose(String Message)
{
if (bAllowLogging)
{
Log.v(mTag, Message);
}
if (mCallback != null)
{
mCallback.LoggerCallback("V/", mTag, Message);
}
}
public void debug(String Message)
{
if (bAllowLogging)
@@ -65,4 +80,16 @@ public class Logger
mCallback.LoggerCallback("E/", mTag, Message);
}
}
public void error(String Message, Throwable Throwable)
{
if (bAllowLogging)
{
Log.e(mTag, Message, Throwable);
}
if (mCallback != null)
{
mCallback.LoggerCallback("E/", mTag, Message);
}
}
}

View File

@@ -0,0 +1,25 @@
package com.epicgames.ue4;
public class NativeCalls
{
@SuppressWarnings("JniMissingFunction")
public static native void HandleCustomTouchEvent(int deviceId, int pointerId, int action, int source, float x, float y);
@SuppressWarnings("JniMissingFunction")
public static native void CallNativeToEmbedded(String ID, int Priority, String Subsystem, String Command, String[] Params, String RoutingFunction);
@SuppressWarnings("JniMissingFunction")
public static native void SetNamedObject(String Name, Object Obj);
@SuppressWarnings("JniMissingFunction")
public static native void KeepAwake(String Requester, boolean bIsForRendering);
@SuppressWarnings("JniMissingFunction")
public static native void AllowSleep(String Requester);
@SuppressWarnings("JniMissingFunction")
public static native void WebViewVisible(boolean bShown);
@SuppressWarnings("JniMissingFunction")
public static native void ForwardNotification(String payload);
}

View File

@@ -2,6 +2,7 @@
package com.epicgames.ue4;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
@@ -13,6 +14,9 @@ import android.view.WindowManager;
public class SplashActivity extends Activity
{
public static Logger Log = new Logger("UE4-SplashActivity");
@SuppressLint("ObsoleteSdkInt")
@Override
protected void onCreate(Bundle savedInstanceState)
{
@@ -33,11 +37,9 @@ public class SplashActivity extends Activity
UseDisplayCutout = bundle.getBoolean("com.epicgames.ue4.GameActivity.bUseDisplayCutout");
}
}
catch (NameNotFoundException e)
{
}
catch (NullPointerException e)
catch (NameNotFoundException | NullPointerException e)
{
Log.error("Error when accessing application metadata", e);
}
if (ShouldHideUI)
@@ -78,10 +80,10 @@ public class SplashActivity extends Activity
Intent intent = new Intent(this, GameActivity.class);
intent.putExtras(getIntent());
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
intent.putExtra("UseSplashScreen", "true");
intent.putExtra("UseSplashScreen", true);
if (ShouldHideUI)
{
intent.putExtra("ShouldHideUI", "true");
intent.putExtra("ShouldHideUI", true);
}
if (UseDisplayCutout)
{

View File

@@ -7,6 +7,7 @@ import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.ConsoleMessage;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.webkit.WebChromeClient;
@@ -1681,6 +1682,14 @@ class WebViewControl
resultMsg.sendToTarget();
return true;
}
@Override
public boolean onConsoleMessage(ConsoleMessage cm) {
GameActivity.Log.warn(cm.message() + " -- From line "
+ cm.lineNumber() + " of "
+ cm.sourceId() );
return true;
}
}
public long GetNativePtr()
{

View File

@@ -227,7 +227,8 @@ public class Helpers {
static public boolean doesFileExistInternal(Context c, File fileForNewFile, long fileSize,
boolean deleteFileOnMismatch) {
if (fileForNewFile.exists()) {
if (fileForNewFile.length() == fileSize) {
// ignore actual file size if requested filesize is 0 (special case allow any)
if ((fileSize==0) || (fileForNewFile.length() == fileSize)) {
return true;
}
if (deleteFileOnMismatch) {