Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Android.bp
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ filegroup {
":deviceproductinfoconstants_aidl",

":adbrootservice_aidl",
":lmofreeform_aidl",

// For the generated R.java and Manifest.java
":framework-res{.aapt.srcjar}",
Expand Down
15 changes: 15 additions & 0 deletions core/java/android/hardware/display/DisplayManagerInternal.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,21 @@
import android.hardware.SensorManager;
import android.hardware.input.HostUsiVersion;
import android.os.Handler;
import android.os.IBinder;
import android.os.PowerManager;
import android.util.IntArray;
import android.util.SparseArray;
import android.view.Display;
import android.view.DisplayInfo;
import android.view.Surface;
import android.view.SurfaceControl;
import android.view.SurfaceControl.RefreshRateRange;
import android.view.SurfaceControl.Transaction;
import android.window.DisplayWindowPolicyController;
import android.window.ScreenCaptureInternal;

import com.libremobileos.freeform.ILMOFreeformDisplayCallback;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.List;
Expand Down Expand Up @@ -501,6 +505,17 @@ public abstract RefreshRateRange getRefreshRateForDisplayAndSensor(
*/
public abstract IntArray getDisplayIds();

// LMOFreeform
public abstract void createFreeformLocked(String name, ILMOFreeformDisplayCallback callback,
int width, int height, int densityDpi, boolean secure, boolean ownContentOnly,
boolean shouldShowSystemDecorations, Surface surface, float refreshRate,
long presentationDeadlineNanos);

public abstract void resizeFreeform(IBinder appToken, int width, int height,
int densityDpi);

public abstract void releaseFreeform(IBinder appToken);

/**
* Get group id for given display id
*/
Expand Down
114 changes: 114 additions & 0 deletions core/java/android/view/animation/AnimationUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,17 @@
import android.content.res.Resources.Theme;
import android.content.res.XmlResourceParser;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.ravenwood.annotation.RavenwoodIgnore;
import android.ravenwood.annotation.RavenwoodKeepPartialClass;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TimeUtils;
import android.util.Xml;
import android.view.InflateException;

import com.android.internal.R;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

Expand Down Expand Up @@ -224,6 +228,20 @@ public static long getExpectedPresentationTimeMillis() {
public static Animation loadAnimation(Context context, @AnimRes int id)
throws NotFoundException {

if (SystemProperties.getBoolean("persist.sys.activity_anim_perf_override", false)) {
ActivityAnimations.maybeInit(context);
switch (id) {
case R.anim.activity_open_enter:
return ActivityAnimations.getOpenEnter();
case R.anim.activity_open_exit:
return ActivityAnimations.getOpenExit();
case R.anim.activity_close_enter:
return ActivityAnimations.getCloseEnter();
case R.anim.activity_close_exit:
return ActivityAnimations.getCloseExit();
}
}

XmlResourceParser parser = null;
try {
parser = context.getResources().getAnimation(id);
Expand Down Expand Up @@ -504,4 +522,100 @@ private static Interpolator createInterpolatorFromXml(
}
return interpolator;
}

/** @hide */
public final class ActivityAnimations {

private static Animation sOpenEnter;
private static Animation sOpenExit;
private static Animation sCloseEnter;
private static Animation sCloseExit;

private static Interpolator sFastOutExtraSlowInInterpolator;

private static final float DISTANCE = 0.1f;

private ActivityAnimations() {}

/** @hide */
public static void maybeInit(Context context) {
if (sFastOutExtraSlowInInterpolator == null) {
sFastOutExtraSlowInInterpolator = AnimationUtils.loadInterpolator(
context, R.interpolator.fast_out_extra_slow_in);
}
}

private static class ActivityAnimFactory {
private float fromX = 0f, toX = 0f;
private long duration = 200L;

public ActivityAnimFactory fromX(float ratio) {
this.fromX = ratio;
return this;
}

public ActivityAnimFactory toX(float ratio) {
this.toX = ratio;
return this;
}

public Animation build() {
AnimationSet animationSet = new AnimationSet(false);
TranslateAnimation slide = new TranslateAnimation(
Animation.RELATIVE_TO_SELF, fromX,
Animation.RELATIVE_TO_SELF, toX,
Animation.RELATIVE_TO_SELF, 0f,
Animation.RELATIVE_TO_SELF, 0f
);
slide.setDuration(duration);
slide.setInterpolator(sFastOutExtraSlowInInterpolator);
animationSet.addAnimation(slide);
return animationSet;
}
}

/** @hide */
public static Animation getOpenEnter() {
if (sOpenEnter == null) {
sOpenEnter = new ActivityAnimFactory()
.fromX(1.0f)
.toX(0.0f)
.build();
}
return sOpenEnter;
}

/** @hide */
public static Animation getOpenExit() {
if (sOpenExit == null) {
sOpenExit = new ActivityAnimFactory()
.fromX(0.0f)
.toX(-DISTANCE)
.build();
}
return sOpenExit;
}

/** @hide */
public static Animation getCloseEnter() {
if (sCloseEnter == null) {
sCloseEnter = new ActivityAnimFactory()
.fromX(-DISTANCE)
.toX(0.0f)
.build();
}
return sCloseEnter;
}

/** @hide */
public static Animation getCloseExit() {
if (sCloseExit == null) {
sCloseExit = new ActivityAnimFactory()
.fromX(0.0f)
.toX(1.0f)
.build();
}
return sCloseExit;
}
}
}
4 changes: 4 additions & 0 deletions core/res/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -941,6 +941,10 @@
android:knownCerts="@array/config_setContactsDefaultAccountKnownSigners"
android:featureFlag="android.provider.new_default_account_api_enabled"/>

<!-- @hide -->
<permission android:name="com.libremobileos.permission.START_FREEFORM"
android:protectionLevel="signature|privileged" />

<!-- ====================================================================== -->
<!-- Permissions for accessing user's calendar -->
<!-- ====================================================================== -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.Insets;
import android.graphics.Point;
Expand All @@ -54,6 +55,7 @@
import android.window.DesktopModeFlags;
import android.window.WindowContainerTransaction;

import com.android.internal.policy.ScreenDecorationsUtils;
import com.android.internal.annotations.VisibleForTesting;
import com.android.wm.shell.R;
import com.android.wm.shell.ShellTaskOrganizer;
Expand Down Expand Up @@ -220,7 +222,7 @@ static void updateRelayoutParams(
boolean shouldSetTaskVisibilityPositionAndCrop,
boolean isStatusBarVisible,
boolean isKeyguardVisibleAndOccluded,
InsetsState displayInsetsState,
DisplayController displayController,
boolean hasGlobalFocus,
@NonNull Region globalExclusionRegion,
boolean shouldSetBackground,
Expand All @@ -246,6 +248,8 @@ static void updateRelayoutParams(
|| (isStatusBarVisible && !isKeyguardVisibleAndOccluded);
relayoutParams.mDisplayExclusionRegion.set(globalExclusionRegion);
relayoutParams.mInSyncWithTransition = inSyncWithTransition;
relayoutParams.mCornerRadius =
getCornerRadius(context, displayController.getDisplay(taskInfo.displayId));

if (TaskInfoKt.isTransparentCaptionBarAppearance(taskInfo)) {
// If the app is requesting to customize the caption bar, allow input to fall
Expand All @@ -265,7 +269,8 @@ static void updateRelayoutParams(
);

relayoutParams.mCaptionTopPadding = getTopPadding(relayoutParams,
taskInfo.getConfiguration().windowConfiguration.getBounds(), displayInsetsState);
taskInfo.getConfiguration().windowConfiguration.getBounds(),
displayController.getInsetsState(taskInfo.displayId));
// Set opaque background for all freeform tasks to prevent freeform tasks below
// from being visible if freeform task window above is translucent.
// Otherwise if fluid resize is enabled, add a background to freeform tasks.
Expand All @@ -290,7 +295,7 @@ void relayout(RunningTaskInfo taskInfo,
updateRelayoutParams(mRelayoutParams, mContext, taskInfo, applyStartTransactionOnDraw,
shouldSetTaskVisibilityPositionAndCrop, mIsStatusBarVisible,
mIsKeyguardVisibleAndOccluded,
mDisplayController.getInsetsState(taskInfo.displayId), hasGlobalFocus,
mDisplayController, hasGlobalFocus,
globalExclusionRegion, mDesktopConfig.shouldSetBackground(taskInfo),
inSyncWithTransition);

Expand Down Expand Up @@ -350,6 +355,19 @@ void relayout(RunningTaskInfo taskInfo,
});
}

private static int getCornerRadius(Context context, Display display) {
// Show rounded corners only on the internal display as we can't get rounded corners for
// external displays.
if (display.getType() != Display.TYPE_INTERNAL) {
return 0;
}
final TypedArray ta = context.obtainStyledAttributes(
new int[]{android.R.attr.dialogCornerRadius});
final int cornerRadius = ta.getDimensionPixelSize(0, 0);
ta.recycle();
return cornerRadius;
}

/**
* Sets up listeners when a new root view is created.
*/
Expand Down
2 changes: 2 additions & 0 deletions services/Android.bp
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ filegroup {
":services.coverage-sources",
":services.credentials-sources",
":services.devicepolicy-sources",
":services.freeform-sources",
":services.midi-sources",
":services.musicsearch-sources",
":services.net-sources",
Expand Down Expand Up @@ -339,6 +340,7 @@ java_library {
"services.credentials",
"services.devicepolicy",
"services.flags",
"services.freeform",
"services.midi",
"services.musicsearch",
"services.net",
Expand Down
1 change: 1 addition & 0 deletions services/core/Android.bp
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ java_library_static {
":display-layout-config",
":display-topology",
":device-state-config",
":lmofreeform-display-adapter-java",
"java/com/android/server/EventLogTags.logtags",
"java/com/android/server/am/EventLogTags.logtags",
"java/com/android/server/wm/EventLogTags.logtags",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,8 @@
import com.android.server.wm.SurfaceAnimationThread;
import com.android.server.wm.WindowManagerInternal;

import com.libremobileos.freeform.ILMOFreeformDisplayCallback;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
Expand Down Expand Up @@ -563,6 +565,8 @@ public synchronized void requestDisplayState(int displayId, int state, float bri
// only be used for the devices in projected mode.
private boolean mIncludeDefaultDisplayInTopology;

private LMOFreeformDisplayAdapter mFreeformDisplayAdapter;

private final BroadcastReceiver mIdleModeReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Expand Down Expand Up @@ -2386,6 +2390,7 @@ private void registerAdditionalDisplayAdapters() {
if (shouldRegisterNonEssentialDisplayAdaptersLocked()) {
registerOverlayDisplayAdapterLocked();
registerWifiDisplayAdapterLocked();
registerFreeformDisplayAdapterLocked();
}
}
}
Expand All @@ -2406,6 +2411,13 @@ private void registerWifiDisplayAdapterLocked() {
}
}

private void registerFreeformDisplayAdapterLocked() {
mFreeformDisplayAdapter = new LMOFreeformDisplayAdapter(
mSyncRoot, mContext, mHandler, mDisplayDeviceRepo, mLogicalDisplayMapper,
mUiHandler, mFlags);
registerDisplayAdapterLocked(mFreeformDisplayAdapter);
}

private boolean shouldRegisterNonEssentialDisplayAdaptersLocked() {
// In safe mode, we disable non-essential display adapters to give the user
// an opportunity to fix broken settings or other problems that might affect
Expand Down Expand Up @@ -6431,6 +6443,23 @@ public void reloadTopologies(final int userId) {
scheduleTopologiesReload(mCurrentUserId, /*isUserSwitching=*/ false);
}
}

public void createFreeformLocked(String name, ILMOFreeformDisplayCallback callback,
int width, int height, int densityDpi, boolean secure, boolean ownContentOnly,
boolean shouldShowSystemDecorations, Surface surface, float refreshRate,
long presentationDeadlineNanos) {
mFreeformDisplayAdapter.createFreeformLocked(name, callback, width, height, densityDpi,
secure, ownContentOnly, shouldShowSystemDecorations, surface, refreshRate,
presentationDeadlineNanos);
}

public void resizeFreeform(IBinder appToken, int width, int height, int densityDpi) {
mFreeformDisplayAdapter.resizeFreeform(appToken, width, height, densityDpi);
}

public void releaseFreeform(IBinder appToken) {
mFreeformDisplayAdapter.releaseFreeform(appToken);
}
}

class DesiredDisplayModeSpecsObserver
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3070,6 +3070,12 @@ int startActivityFromRecents(int callingPid, int callingUid, int taskId,
mService.continueWindowLayout();
}
}
if (activityOptions != null) {
final int windowingMode = activityOptions.getLaunchWindowingMode();
if (windowingMode == WINDOWING_MODE_FREEFORM) {
task.setBounds(activityOptions.getLaunchBounds());
}
}
taskCallingUid = task.mCallingUid;
callingPackage = task.mCallingPackage;
callingFeatureId = task.mCallingFeatureId;
Expand Down
Loading