summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/system-current.txt15
-rw-r--r--core/java/android/util/FeatureFlagUtils.java2
-rw-r--r--core/java/com/android/internal/statusbar/IStatusBar.aidl19
-rw-r--r--core/java/com/android/internal/statusbar/IStatusBarService.aidl1
-rw-r--r--core/java/com/android/internal/statusbar/RegisterStatusBarResult.java65
-rw-r--r--core/tests/coretests/src/com/android/internal/statusbar/RegisterStatusBarResultTest.java23
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java41
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java17
-rw-r--r--services/core/java/com/android/server/media/MediaSessionService.java23
-rw-r--r--services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java5
-rw-r--r--services/core/java/com/android/server/statusbar/StatusBarManagerService.java167
-rw-r--r--services/core/java/com/android/server/wallpaper/GLHelper.java148
-rw-r--r--services/core/java/com/android/server/wallpaper/WallpaperManagerService.java114
-rw-r--r--services/core/java/com/android/server/wm/DisplayPolicy.java77
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java4
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java5
-rw-r--r--tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassBase.java6
-rw-r--r--tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassChild.java6
-rw-r--r--tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java8
-rw-r--r--tests/Codegen/src/com/android/codegentest/SampleDataClass.java6
-rw-r--r--tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java6
-rw-r--r--tests/Codegen/src/com/android/codegentest/SampleWithNestedDataClasses.java18
-rw-r--r--tests/Codegen/src/com/android/codegentest/StaleDataclassDetectorFalsePositivesTest.java6
-rw-r--r--tools/codegen/src/com/android/codegen/FieldInfo.kt4
-rw-r--r--tools/codegen/src/com/android/codegen/Generators.kt7
-rw-r--r--tools/codegen/src/com/android/codegen/SharedConstants.kt2
-rw-r--r--wifi/java/android/net/wifi/ISoftApCallback.aidl8
-rw-r--r--wifi/java/android/net/wifi/SoftApInfo.aidl20
-rw-r--r--wifi/java/android/net/wifi/SoftApInfo.java211
-rw-r--r--wifi/java/android/net/wifi/WifiManager.java19
-rw-r--r--wifi/tests/src/android/net/wifi/SoftApInfoTest.java71
-rw-r--r--wifi/tests/src/android/net/wifi/WifiManagerTest.java28
33 files changed, 818 insertions, 336 deletions
diff --git a/api/system-current.txt b/api/system-current.txt
index 213ea3125c69..9a24181d18f5 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -4755,6 +4755,21 @@ package android.net.wifi {
method @NonNull public android.net.wifi.SoftApConfiguration.Builder setWpa2Passphrase(@Nullable String);
}
+ public final class SoftApInfo implements android.os.Parcelable {
+ method public int describeContents();
+ method public int getBandwidth();
+ method public int getFrequency();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field public static final int CHANNEL_WIDTH_160MHZ = 6; // 0x6
+ field public static final int CHANNEL_WIDTH_20MHZ = 2; // 0x2
+ field public static final int CHANNEL_WIDTH_20MHZ_NOHT = 1; // 0x1
+ field public static final int CHANNEL_WIDTH_40MHZ = 3; // 0x3
+ field public static final int CHANNEL_WIDTH_80MHZ = 4; // 0x4
+ field public static final int CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 5; // 0x5
+ field public static final int CHANNEL_WIDTH_INVALID = 0; // 0x0
+ field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.SoftApInfo> CREATOR;
+ }
+
public final class WifiClient implements android.os.Parcelable {
method public int describeContents();
method @NonNull public android.net.MacAddress getMacAddress();
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index b1fd4e5e699e..af1a51f68d71 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -47,8 +47,6 @@ public class FeatureFlagUtils {
static {
DEFAULT_FLAGS = new HashMap<>();
DEFAULT_FLAGS.put("settings_audio_switcher", "true");
- DEFAULT_FLAGS.put("settings_mobile_network_v2", "true");
- DEFAULT_FLAGS.put("settings_network_and_internet_v2", "true");
DEFAULT_FLAGS.put("settings_systemui_theme", "true");
DEFAULT_FLAGS.put(DYNAMIC_SYSTEM, "false");
DEFAULT_FLAGS.put(SEAMLESS_TRANSFER, "false");
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl
index 317469e58245..73f549a31bac 100644
--- a/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -38,25 +38,6 @@ oneway interface IStatusBar
void showWirelessChargingAnimation(int batteryLevel);
- /**
- * Notifies System UI side of a visibility flag change on the specified display.
- *
- * @param displayId the id of the display to notify
- * @param vis the visibility flags except SYSTEM_UI_FLAG_LIGHT_STATUS_BAR which will be reported
- * separately in fullscreenStackVis and dockedStackVis
- * @param fullscreenStackVis the flags which only apply in the region of the fullscreen stack,
- * which is currently only SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
- * @param dockedStackVis the flags that only apply in the region of the docked stack, which is
- * currently only SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
- * @param mask which flags to change
- * @param fullscreenBounds the current bounds of the fullscreen stack, in screen coordinates
- * @param dockedBounds the current bounds of the docked stack, in screen coordinates
- * @param navbarColorManagedByIme {@code true} if navigation bar color is managed by IME.
- */
- void setSystemUiVisibility(int displayId, int vis, int fullscreenStackVis, int dockedStackVis,
- int mask, in Rect fullscreenBounds, in Rect dockedBounds,
- boolean navbarColorManagedByIme);
-
void topAppWindowChanged(int displayId, boolean isFullscreen, boolean isImmersive);
void setImeWindowStatus(int displayId, in IBinder token, int vis, int backDisposition,
boolean showImeSwitcher, boolean isMultiClientImeEnabled);
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index d703b86d6c8d..3f08710bb17f 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -77,7 +77,6 @@ interface IStatusBarService
void onNotificationSmartReplySent(in String key, in int replyIndex, in CharSequence reply,
in int notificationLocation, boolean modifiedBeforeSending);
void onNotificationSettingsViewed(String key);
- void setSystemUiVisibility(int displayId, int vis, int mask, String cause);
void onNotificationBubbleChanged(String key, boolean isBubble);
void grantInlineReplyUriPermission(String key, in Uri uri, in UserHandle user, String packageName);
void clearInlineReplyUriPermissions(String key);
diff --git a/core/java/com/android/internal/statusbar/RegisterStatusBarResult.java b/core/java/com/android/internal/statusbar/RegisterStatusBarResult.java
index 4c3f04b10892..9095f05543da 100644
--- a/core/java/com/android/internal/statusbar/RegisterStatusBarResult.java
+++ b/core/java/com/android/internal/statusbar/RegisterStatusBarResult.java
@@ -16,53 +16,50 @@
package com.android.internal.statusbar;
-import android.graphics.Rect;
+import android.annotation.NonNull;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.ArrayMap;
+import com.android.internal.view.AppearanceRegion;
+
/**
* An immutable data object to return a set of values from StatusBarManagerService to its clients.
*/
public final class RegisterStatusBarResult implements Parcelable {
public final ArrayMap<String, StatusBarIcon> mIcons;
- public final int mDisabledFlags1; // switch[0]
- public final int mSystemUiVisibility; // switch[1]
- public final int mImeWindowVis; // switch[3]
- public final int mImeBackDisposition; // switch[4]
- public final boolean mShowImeSwitcher; // switch[5]
- public final int mDisabledFlags2; // switch[6]
- public final int mFullscreenStackSysUiVisibility; // switch[7]
- public final int mDockedStackSysUiVisibility; // switch[8]
+ public final int mDisabledFlags1; // switch[0]
+ public final int mAppearance; // switch[1]
+ public final AppearanceRegion[] mAppearanceRegions; // switch[2]
+ public final int mImeWindowVis; // switch[3]
+ public final int mImeBackDisposition; // switch[4]
+ public final boolean mShowImeSwitcher; // switch[5]
+ public final int mDisabledFlags2; // switch[6]
public final IBinder mImeToken;
- public final Rect mFullscreenStackBounds;
- public final Rect mDockedStackBounds;
public final boolean mNavbarColorManagedByIme;
public final boolean mAppFullscreen;
public final boolean mAppImmersive;
+ public final int[] mTransientBarTypes;
public RegisterStatusBarResult(ArrayMap<String, StatusBarIcon> icons, int disabledFlags1,
- int systemUiVisibility, int imeWindowVis, int imeBackDisposition,
- boolean showImeSwitcher, int disabledFlags2, int fullscreenStackSysUiVisibility,
- int dockedStackSysUiVisibility, IBinder imeToken, Rect fullscreenStackBounds,
- Rect dockedStackBounds, boolean navbarColorManagedByIme, boolean appFullscreen,
- boolean appImmersive) {
+ int appearance, AppearanceRegion[] appearanceRegions, int imeWindowVis,
+ int imeBackDisposition, boolean showImeSwitcher, int disabledFlags2, IBinder imeToken,
+ boolean navbarColorManagedByIme, boolean appFullscreen, boolean appImmersive,
+ @NonNull int[] transientBarTypes) {
mIcons = new ArrayMap<>(icons);
mDisabledFlags1 = disabledFlags1;
- mSystemUiVisibility = systemUiVisibility;
+ mAppearance = appearance;
+ mAppearanceRegions = appearanceRegions;
mImeWindowVis = imeWindowVis;
mImeBackDisposition = imeBackDisposition;
mShowImeSwitcher = showImeSwitcher;
mDisabledFlags2 = disabledFlags2;
- mFullscreenStackSysUiVisibility = fullscreenStackSysUiVisibility;
- mDockedStackSysUiVisibility = dockedStackSysUiVisibility;
mImeToken = imeToken;
- mFullscreenStackBounds = fullscreenStackBounds;
- mDockedStackBounds = dockedStackBounds;
mNavbarColorManagedByIme = navbarColorManagedByIme;
mAppFullscreen = appFullscreen;
mAppImmersive = appImmersive;
+ mTransientBarTypes = transientBarTypes;
}
@Override
@@ -74,19 +71,17 @@ public final class RegisterStatusBarResult implements Parcelable {
public void writeToParcel(Parcel dest, int flags) {
dest.writeTypedArrayMap(mIcons, flags);
dest.writeInt(mDisabledFlags1);
- dest.writeInt(mSystemUiVisibility);
+ dest.writeInt(mAppearance);
+ dest.writeParcelableArray(mAppearanceRegions, 0);
dest.writeInt(mImeWindowVis);
dest.writeInt(mImeBackDisposition);
dest.writeBoolean(mShowImeSwitcher);
dest.writeInt(mDisabledFlags2);
- dest.writeInt(mFullscreenStackSysUiVisibility);
- dest.writeInt(mDockedStackSysUiVisibility);
dest.writeStrongBinder(mImeToken);
- dest.writeTypedObject(mFullscreenStackBounds, flags);
- dest.writeTypedObject(mDockedStackBounds, flags);
dest.writeBoolean(mNavbarColorManagedByIme);
dest.writeBoolean(mAppFullscreen);
dest.writeBoolean(mAppImmersive);
+ dest.writeIntArray(mTransientBarTypes);
}
/**
@@ -99,24 +94,22 @@ public final class RegisterStatusBarResult implements Parcelable {
final ArrayMap<String, StatusBarIcon> icons =
source.createTypedArrayMap(StatusBarIcon.CREATOR);
final int disabledFlags1 = source.readInt();
- final int systemUiVisibility = source.readInt();
+ final int appearance = source.readInt();
+ final AppearanceRegion[] appearanceRegions =
+ source.readParcelableArray(null, AppearanceRegion.class);
final int imeWindowVis = source.readInt();
final int imeBackDisposition = source.readInt();
final boolean showImeSwitcher = source.readBoolean();
final int disabledFlags2 = source.readInt();
- final int fullscreenStackSysUiVisibility = source.readInt();
- final int dockedStackSysUiVisibility = source.readInt();
final IBinder imeToken = source.readStrongBinder();
- final Rect fullscreenStackBounds = source.readTypedObject(Rect.CREATOR);
- final Rect dockedStackBounds = source.readTypedObject(Rect.CREATOR);
final boolean navbarColorManagedByIme = source.readBoolean();
final boolean appFullscreen = source.readBoolean();
final boolean appImmersive = source.readBoolean();
- return new RegisterStatusBarResult(icons, disabledFlags1, systemUiVisibility,
- imeWindowVis, imeBackDisposition, showImeSwitcher, disabledFlags2,
- fullscreenStackSysUiVisibility, dockedStackSysUiVisibility, imeToken,
- fullscreenStackBounds, dockedStackBounds, navbarColorManagedByIme,
- appFullscreen, appImmersive);
+ final int[] transientBarTypes = source.createIntArray();
+ return new RegisterStatusBarResult(icons, disabledFlags1, appearance,
+ appearanceRegions, imeWindowVis, imeBackDisposition, showImeSwitcher,
+ disabledFlags2, imeToken, navbarColorManagedByIme, appFullscreen,
+ appImmersive, transientBarTypes);
}
@Override
diff --git a/core/tests/coretests/src/com/android/internal/statusbar/RegisterStatusBarResultTest.java b/core/tests/coretests/src/com/android/internal/statusbar/RegisterStatusBarResultTest.java
index 0be5009f85f0..9f68ef31c166 100644
--- a/core/tests/coretests/src/com/android/internal/statusbar/RegisterStatusBarResultTest.java
+++ b/core/tests/coretests/src/com/android/internal/statusbar/RegisterStatusBarResultTest.java
@@ -18,7 +18,6 @@ package com.android.internal.statusbar;
import static com.google.common.truth.Truth.assertThat;
-import android.graphics.Rect;
import android.os.Binder;
import android.os.Parcel;
import android.os.UserHandle;
@@ -27,6 +26,8 @@ import android.util.ArrayMap;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
+import com.android.internal.view.AppearanceRegion;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -47,19 +48,17 @@ public class RegisterStatusBarResultTest {
final RegisterStatusBarResult original = new RegisterStatusBarResult(iconMap,
0x2 /* disabledFlags1 */,
- 0x4 /* systemUiVisibility */,
+ 0x4 /* appearance */,
+ new AppearanceRegion[0] /* appearanceRegions */,
0x8 /* imeWindowVis */,
0x10 /* imeBackDisposition */,
false /* showImeSwitcher */,
0x20 /* disabledFlags2 */,
- 0x40 /* fullscreenStackSysUiVisibility */,
- 0x80 /* dockedStackSysUiVisibility */,
new Binder() /* imeToken */,
- new Rect(0x100, 0x200, 0x400, 0x800) /* fullscreenStackBounds */,
- new Rect(0x1000, 0x2000, 0x4000, 0x8000) /* dockedStackBounds */,
true /* navbarColorManagedByIme */,
true /* appFullscreen */,
- true /* appImmersive */);
+ true /* appImmersive */,
+ new int[0] /* transientBarTypes */);
final RegisterStatusBarResult copy = clone(original);
@@ -69,21 +68,17 @@ public class RegisterStatusBarResultTest {
.isEqualTo(original.mIcons.get(dumyIconKey).user);
assertThat(copy.mDisabledFlags1).isEqualTo(original.mDisabledFlags1);
- assertThat(copy.mSystemUiVisibility).isEqualTo(original.mSystemUiVisibility);
+ assertThat(copy.mAppearance).isEqualTo(original.mAppearance);
+ assertThat(copy.mAppearanceRegions).isEqualTo(original.mAppearanceRegions);
assertThat(copy.mImeWindowVis).isEqualTo(original.mImeWindowVis);
assertThat(copy.mImeBackDisposition).isEqualTo(original.mImeBackDisposition);
assertThat(copy.mShowImeSwitcher).isEqualTo(original.mShowImeSwitcher);
assertThat(copy.mDisabledFlags2).isEqualTo(original.mDisabledFlags2);
- assertThat(copy.mFullscreenStackSysUiVisibility)
- .isEqualTo(original.mFullscreenStackSysUiVisibility);
- assertThat(copy.mDockedStackSysUiVisibility)
- .isEqualTo(original.mDockedStackSysUiVisibility);
assertThat(copy.mImeToken).isSameAs(original.mImeToken);
- assertThat(copy.mFullscreenStackBounds).isEqualTo(original.mFullscreenStackBounds);
- assertThat(copy.mDockedStackBounds).isEqualTo(original.mDockedStackBounds);
assertThat(copy.mNavbarColorManagedByIme).isEqualTo(original.mNavbarColorManagedByIme);
assertThat(copy.mAppFullscreen).isEqualTo(original.mAppFullscreen);
assertThat(copy.mAppImmersive).isEqualTo(original.mAppImmersive);
+ assertThat(copy.mTransientBarTypes).isEqualTo(original.mTransientBarTypes);
}
private RegisterStatusBarResult clone(RegisterStatusBarResult original) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index b723b752548b..621f101cd8af 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -22,8 +22,6 @@ import static android.inputmethodservice.InputMethodService.BACK_DISPOSITION_DEF
import static android.inputmethodservice.InputMethodService.IME_INVISIBLE;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
-import static android.view.InsetsState.TYPE_NAVIGATION_BAR;
-import static android.view.InsetsState.TYPE_TOP_BAR;
import static com.android.systemui.statusbar.phone.StatusBar.ONLY_CORE_APPS;
@@ -34,7 +32,6 @@ import android.app.StatusBarManager.WindowType;
import android.app.StatusBarManager.WindowVisibleState;
import android.content.ComponentName;
import android.content.Context;
-import android.graphics.Rect;
import android.hardware.biometrics.IBiometricServiceReceiverInternal;
import android.hardware.display.DisplayManager;
import android.inputmethodservice.InputMethodService.BackDispositionMode;
@@ -45,9 +42,7 @@ import android.os.Looper;
import android.os.Message;
import android.util.Pair;
import android.util.SparseArray;
-import android.view.InsetsFlags;
import android.view.InsetsState.InternalInsetType;
-import android.view.View;
import android.view.WindowInsetsController.Appearance;
import com.android.internal.os.SomeArgs;
@@ -462,42 +457,6 @@ public class CommandQueue extends IStatusBar.Stub implements CallbackController<
}
}
- // TODO(b/118118435): Remove this function after migration
- @Override
- public void setSystemUiVisibility(int displayId, int vis, int fullscreenStackVis,
- int dockedStackVis, int mask, Rect fullscreenStackBounds, Rect dockedStackBounds,
- boolean navbarColorManagedByIme) {
- synchronized (mLock) {
- final boolean hasDockedStack = !dockedStackBounds.isEmpty();
- final boolean transientStatus = (vis & View.STATUS_BAR_TRANSIENT) != 0;
- final boolean transientNavigation = (vis & View.NAVIGATION_BAR_TRANSIENT) != 0;
- if (transientStatus && transientNavigation) {
- showTransient(displayId, new int[]{TYPE_TOP_BAR, TYPE_NAVIGATION_BAR});
- } else if (transientStatus) {
- showTransient(displayId, new int[]{TYPE_TOP_BAR});
- abortTransient(displayId, new int[]{TYPE_NAVIGATION_BAR});
- } else if (transientNavigation) {
- showTransient(displayId, new int[]{TYPE_NAVIGATION_BAR});
- abortTransient(displayId, new int[]{TYPE_TOP_BAR});
- } else {
- abortTransient(displayId, new int[]{TYPE_TOP_BAR, TYPE_NAVIGATION_BAR});
- }
- SomeArgs args = SomeArgs.obtain();
- args.argi1 = displayId;
- args.argi2 = InsetsFlags.getAppearance(vis);
- args.argi3 = navbarColorManagedByIme ? 1 : 0;
- final int fullscreenAppearance = InsetsFlags.getAppearance(fullscreenStackVis);
- final int dockedAppearance = InsetsFlags.getAppearance(dockedStackVis);
- args.arg1 = hasDockedStack
- ? new AppearanceRegion[]{
- new AppearanceRegion(fullscreenAppearance, fullscreenStackBounds),
- new AppearanceRegion(dockedAppearance, dockedStackBounds)}
- : new AppearanceRegion[]{
- new AppearanceRegion(fullscreenAppearance, fullscreenStackBounds)};
- mHandler.obtainMessage(MSG_SYSTEM_BAR_APPEARANCE_CHANGED, args).sendToTarget();
- }
- }
-
@Override
public void topAppWindowChanged(int displayId, boolean isFullscreen, boolean isImmersive) {
synchronized (mLock) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java
index 2e776e39b54c..1532c4f977e0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java
@@ -247,7 +247,7 @@ public class LightBarController implements BatteryController.BatteryStateChangeC
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("LightBarController: ");
- pw.print(" mAppearance=0x"); pw.println(ViewDebug.flagsToString(
+ pw.print(" mAppearance="); pw.println(ViewDebug.flagsToString(
InsetsFlags.class, "appearance", mAppearance));
final int numStacks = mAppearanceRegions.length;
for (int i = 0; i < numStacks; i++) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index b0104d65a278..cff282472074 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -24,7 +24,6 @@ import static android.app.StatusBarManager.WindowType;
import static android.app.StatusBarManager.WindowVisibleState;
import static android.app.StatusBarManager.windowStateToString;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
-import static android.view.InsetsFlags.getAppearance;
import static android.view.InsetsState.TYPE_TOP_BAR;
import static android.view.InsetsState.containsType;
import static android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS;
@@ -856,19 +855,11 @@ public class StatusBar extends SystemUI implements DemoMode,
// Set up the initial notification state. This needs to happen before CommandQueue.disable()
setUpPresenter();
- if ((result.mSystemUiVisibility & View.STATUS_BAR_TRANSIENT) != 0) {
+ if (containsType(result.mTransientBarTypes, TYPE_TOP_BAR)) {
showTransientUnchecked();
}
- final int fullscreenAppearance = getAppearance(result.mFullscreenStackSysUiVisibility);
- final int dockedAppearance = getAppearance(result.mDockedStackSysUiVisibility);
- final AppearanceRegion[] appearanceRegions = result.mDockedStackBounds.isEmpty()
- ? new AppearanceRegion[]{
- new AppearanceRegion(fullscreenAppearance, result.mFullscreenStackBounds)}
- : new AppearanceRegion[]{
- new AppearanceRegion(fullscreenAppearance, result.mFullscreenStackBounds),
- new AppearanceRegion(dockedAppearance, result.mDockedStackBounds)};
- onSystemBarAppearanceChanged(mDisplayId, getAppearance(result.mSystemUiVisibility),
- appearanceRegions, result.mNavbarColorManagedByIme);
+ onSystemBarAppearanceChanged(mDisplayId, result.mAppearance, result.mAppearanceRegions,
+ result.mNavbarColorManagedByIme);
mAppFullscreen = result.mAppFullscreen;
mAppImmersive = result.mAppImmersive;
@@ -888,7 +879,7 @@ public class StatusBar extends SystemUI implements DemoMode,
"init: icons=%d disabled=0x%08x lights=0x%08x imeButton=0x%08x",
numIcons,
result.mDisabledFlags1,
- result.mSystemUiVisibility,
+ result.mAppearance,
result.mImeWindowVis));
}
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index 193e0afc529e..c25e206d9104 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -1316,7 +1316,6 @@ public class MediaSessionService extends SystemService implements Monitor {
* pressed.
*
* @param packageName The caller's package name, obtained by Context#getPackageName()
- * @param opPackageName The caller's op package name, obtained by Context#getOpPackageName()
* @param sessionToken token for the session that the controller is pointing to
* @param keyEvent media key event
* @see #dispatchVolumeKeyEvent
@@ -1330,15 +1329,15 @@ public class MediaSessionService extends SystemService implements Monitor {
try {
synchronized (mLock) {
MediaSessionRecord record = getMediaSessionRecordLocked(sessionToken);
- if (record == null) {
- Log.w(TAG, "Failed to find session to dispatch key event.");
- return false;
- }
- if (DEBUG) {
+ if (DEBUG_KEY_EVENT) {
Log.d(TAG, "dispatchMediaKeyEventToSessionAsSystemService, pkg="
+ packageName + ", pid=" + pid + ", uid=" + uid + ", sessionToken="
+ sessionToken + ", event=" + keyEvent + ", session=" + record);
}
+ if (record == null) {
+ Log.w(TAG, "Failed to find session to dispatch key event.");
+ return false;
+ }
return record.sendMediaButton(packageName, pid, uid, true /* asSystemService */,
keyEvent, 0, null);
}
@@ -1688,6 +1687,12 @@ public class MediaSessionService extends SystemService implements Monitor {
try {
synchronized (mLock) {
MediaSessionRecord record = getMediaSessionRecordLocked(sessionToken);
+ if (DEBUG_KEY_EVENT) {
+ Log.d(TAG, "dispatchVolumeKeyEventToSessionAsSystemService, pkg="
+ + packageName + ", opPkg=" + opPackageName + ", pid=" + pid
+ + ", uid=" + uid + ", sessionToken=" + sessionToken + ", event="
+ + keyEvent + ", session=" + record);
+ }
if (record == null) {
Log.w(TAG, "Failed to find session to dispatch key event, token="
+ sessionToken + ". Fallbacks to the default handling.");
@@ -1695,12 +1700,6 @@ public class MediaSessionService extends SystemService implements Monitor {
keyEvent, AudioManager.USE_DEFAULT_STREAM_TYPE, false);
return;
}
- if (DEBUG) {
- Log.d(TAG, "dispatchVolumeKeyEventToSessionAsSystemService, pkg="
- + packageName + ", opPkg=" + opPackageName + ", pid=" + pid
- + ", uid=" + uid + ", sessionToken=" + sessionToken + ", event="
- + keyEvent + ", session=" + record);
- }
switch (keyEvent.getAction()) {
case KeyEvent.ACTION_DOWN: {
int direction = 0;
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
index ec64ee6d52de..b6934c9ce604 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
@@ -16,7 +16,6 @@
package com.android.server.statusbar;
-import android.graphics.Rect;
import android.os.Bundle;
import android.view.InsetsState.InternalInsetType;
import android.view.WindowInsetsController.Appearance;
@@ -79,9 +78,7 @@ public interface StatusBarManagerInternal {
void startAssist(Bundle args);
void onCameraLaunchGestureDetected(int source);
void topAppWindowChanged(int displayId, boolean isFullscreen, boolean isImmersive);
- void setSystemUiVisibility(int displayId, int vis, int fullscreenStackVis, int dockedStackVis,
- int mask, Rect fullscreenBounds, Rect dockedBounds, boolean isNavbarColorManagedByIme,
- String cause);
+ void setDisableFlags(int displayId, int flags, String cause);
void toggleSplitScreen();
void appTransitionFinished(int displayId);
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index effeb80298b8..25c41f5cdd6b 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -25,7 +25,6 @@ import android.app.Notification;
import android.app.StatusBarManager;
import android.content.ComponentName;
import android.content.Context;
-import android.graphics.Rect;
import android.hardware.biometrics.IBiometricServiceReceiverInternal;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManager.DisplayListener;
@@ -43,10 +42,11 @@ import android.os.UserHandle;
import android.service.notification.NotificationStats;
import android.text.TextUtils;
import android.util.ArrayMap;
-import android.util.Log;
+import android.util.ArraySet;
import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
+import android.view.InsetsState.InternalInsetType;
import android.view.WindowInsetsController.Appearance;
import com.android.internal.R;
@@ -263,12 +263,8 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
}
@Override
- public void setSystemUiVisibility(int displayId, int vis, int fullscreenStackVis,
- int dockedStackVis, int mask, Rect fullscreenBounds, Rect dockedBounds,
- boolean isNavbarColorManagedByIme, String cause) {
- StatusBarManagerService.this.setSystemUiVisibility(displayId, vis, fullscreenStackVis,
- dockedStackVis, mask, fullscreenBounds, dockedBounds, isNavbarColorManagedByIme,
- cause);
+ public void setDisableFlags(int displayId, int flags, String cause) {
+ StatusBarManagerService.this.setDisableFlags(displayId, flags, cause);
}
@Override
@@ -473,7 +469,10 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
@Override
public void onSystemBarAppearanceChanged(int displayId, @Appearance int appearance,
AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme) {
- // TODO (b/118118435): save the information to UiState
+ final UiState state = getUiState(displayId);
+ if (!state.appearanceEquals(appearance, appearanceRegions, navbarColorManagedByIme)) {
+ state.setAppearance(appearance, appearanceRegions, navbarColorManagedByIme);
+ }
if (mBar != null) {
try {
mBar.onSystemBarAppearanceChanged(displayId, appearance, appearanceRegions,
@@ -483,7 +482,8 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
}
@Override
- public void showTransient(int displayId, int[] types) {
+ public void showTransient(int displayId, @InternalInsetType int[] types) {
+ getUiState(displayId).showTransient(types);
if (mBar != null) {
try {
mBar.showTransient(displayId, types);
@@ -492,7 +492,8 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
}
@Override
- public void abortTransient(int displayId, int[] types) {
+ public void abortTransient(int displayId, @InternalInsetType int[] types) {
+ getUiState(displayId).clearTransient(types);
if (mBar != null) {
try {
mBar.abortTransient(displayId, types);
@@ -896,54 +897,20 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
}
}
- @Override
- public void setSystemUiVisibility(int displayId, int vis, int mask, String cause) {
- final UiState state = getUiState(displayId);
- setSystemUiVisibility(displayId, vis, 0, 0, mask,
- state.mFullscreenStackBounds, state.mDockedStackBounds,
- state.mNavbarColorManagedByIme, cause);
- }
-
- private void setSystemUiVisibility(int displayId, int vis, int fullscreenStackVis,
- int dockedStackVis, int mask, Rect fullscreenBounds, Rect dockedBounds,
- boolean isNavbarColorManagedByIme, String cause) {
+ private void setDisableFlags(int displayId, int flags, String cause) {
// also allows calls from window manager which is in this process.
enforceStatusBarService();
- if (SPEW) Slog.d(TAG, "setSystemUiVisibility(0x" + Integer.toHexString(vis) + ")");
-
- synchronized (mLock) {
- updateUiVisibilityLocked(displayId, vis, fullscreenStackVis, dockedStackVis, mask,
- fullscreenBounds, dockedBounds, isNavbarColorManagedByIme);
- disableLocked(
- displayId,
- mCurrentUserId,
- vis & StatusBarManager.DISABLE_MASK,
- mSysUiVisToken,
- cause, 1);
+ final int unknownFlags = flags & ~StatusBarManager.DISABLE_MASK;
+ if (unknownFlags != 0) {
+ Slog.e(TAG, "Unknown disable flags: 0x" + Integer.toHexString(unknownFlags),
+ new RuntimeException());
}
- }
- private void updateUiVisibilityLocked(final int displayId, final int vis,
- final int fullscreenStackVis, final int dockedStackVis, final int mask,
- final Rect fullscreenBounds, final Rect dockedBounds,
- final boolean isNavbarColorManagedByIme) {
- final UiState state = getUiState(displayId);
- if (!state.systemUiStateEquals(vis, fullscreenStackVis, dockedStackVis,
- fullscreenBounds, dockedBounds, isNavbarColorManagedByIme)) {
- state.setSystemUiState(vis, fullscreenStackVis, dockedStackVis, fullscreenBounds,
- dockedBounds, isNavbarColorManagedByIme);
- mHandler.post(() -> {
- if (mBar != null) {
- try {
- mBar.setSystemUiVisibility(displayId, vis, fullscreenStackVis,
- dockedStackVis, mask, fullscreenBounds, dockedBounds,
- isNavbarColorManagedByIme);
- } catch (RemoteException ex) {
- Log.w(TAG, "Can not get StatusBar!");
- }
- }
- });
+ if (SPEW) Slog.d(TAG, "setDisableFlags(0x" + Integer.toHexString(flags) + ")");
+
+ synchronized (mLock) {
+ disableLocked(displayId, mCurrentUserId, flags, mSysUiVisToken, cause, 1);
}
}
@@ -965,11 +932,10 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
}
private class UiState {
- private int mSystemUiVisibility = 0;
- private int mFullscreenStackSysUiVisibility = 0;
- private int mDockedStackSysUiVisibility = 0;
- private final Rect mFullscreenStackBounds = new Rect();
- private final Rect mDockedStackBounds = new Rect();
+ private @Appearance int mAppearance = 0;
+ private AppearanceRegion[] mAppearanceRegions = new AppearanceRegion[0];
+ private ArraySet<Integer> mTransientBarTypes = new ArraySet<>();
+ private boolean mNavbarColorManagedByIme = false;
private boolean mFullscreen = false;
private boolean mImmersive = false;
private int mDisabled1 = 0;
@@ -978,53 +944,63 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
private int mImeBackDisposition = 0;
private boolean mShowImeSwitcher = false;
private IBinder mImeToken = null;
- private boolean mNavbarColorManagedByIme = false;
- private int getDisabled1() {
- return mDisabled1;
+ private void setAppearance(@Appearance int appearance,
+ AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme) {
+ mAppearance = appearance;
+ mAppearanceRegions = appearanceRegions;
+ mNavbarColorManagedByIme = navbarColorManagedByIme;
}
- private int getDisabled2() {
- return mDisabled2;
+ private boolean appearanceEquals(@Appearance int appearance,
+ AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme) {
+ if (mAppearance != appearance || mAppearanceRegions.length != appearanceRegions.length
+ || mNavbarColorManagedByIme != navbarColorManagedByIme) {
+ return false;
+ }
+ for (int i = appearanceRegions.length - 1; i >= 0; i--) {
+ if (!mAppearanceRegions[i].equals(appearanceRegions[i])) {
+ return false;
+ }
+ }
+ return true;
}
- private void setDisabled(int disabled1, int disabled2) {
- mDisabled1 = disabled1;
- mDisabled2 = disabled2;
+ private void showTransient(@InternalInsetType int[] types) {
+ for (int type : types) {
+ mTransientBarTypes.add(type);
+ }
+ }
+
+ private void clearTransient(@InternalInsetType int[] types) {
+ for (int type : types) {
+ mTransientBarTypes.remove(type);
+ }
}
private void setFullscreen(boolean isFullscreen) {
mFullscreen = isFullscreen;
}
- private void setImmersive(boolean immersive) {
- mImmersive = immersive;
+ private void setImmersive(boolean isImmersive) {
+ mImmersive = isImmersive;
}
- private boolean disableEquals(int disabled1, int disabled2) {
- return mDisabled1 == disabled1 && mDisabled2 == disabled2;
+ private int getDisabled1() {
+ return mDisabled1;
}
- private void setSystemUiState(final int vis, final int fullscreenStackVis,
- final int dockedStackVis, final Rect fullscreenBounds, final Rect dockedBounds,
- final boolean navbarColorManagedByIme) {
- mSystemUiVisibility = vis;
- mFullscreenStackSysUiVisibility = fullscreenStackVis;
- mDockedStackSysUiVisibility = dockedStackVis;
- mFullscreenStackBounds.set(fullscreenBounds);
- mDockedStackBounds.set(dockedBounds);
- mNavbarColorManagedByIme = navbarColorManagedByIme;
+ private int getDisabled2() {
+ return mDisabled2;
}
- private boolean systemUiStateEquals(final int vis, final int fullscreenStackVis,
- final int dockedStackVis, final Rect fullscreenBounds, final Rect dockedBounds,
- final boolean navbarColorManagedByIme) {
- return mSystemUiVisibility == vis
- && mFullscreenStackSysUiVisibility == fullscreenStackVis
- && mDockedStackSysUiVisibility == dockedStackVis
- && mFullscreenStackBounds.equals(fullscreenBounds)
- && mDockedStackBounds.equals(dockedBounds)
- && mNavbarColorManagedByIme == navbarColorManagedByIme;
+ private void setDisabled(int disabled1, int disabled2) {
+ mDisabled1 = disabled1;
+ mDisabled2 = disabled2;
+ }
+
+ private boolean disableEquals(int disabled1, int disabled2) {
+ return mDisabled1 == disabled1 && mDisabled2 == disabled2;
}
private void setImeWindowState(final int vis, final int backDisposition,
@@ -1084,13 +1060,16 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
// TODO(b/118592525): Currently, status bar only works on the default display.
// Make it aware of multi-display if needed.
final UiState state = mDisplayUiState.get(DEFAULT_DISPLAY);
+ final int[] transientBarTypes = new int[state.mTransientBarTypes.size()];
+ for (int i = 0; i < transientBarTypes.length; i++) {
+ transientBarTypes[i] = state.mTransientBarTypes.valueAt(i);
+ }
return new RegisterStatusBarResult(icons, gatherDisableActionsLocked(mCurrentUserId, 1),
- state.mSystemUiVisibility, state.mImeWindowVis,
+ state.mAppearance, state.mAppearanceRegions, state.mImeWindowVis,
state.mImeBackDisposition, state.mShowImeSwitcher,
- gatherDisableActionsLocked(mCurrentUserId, 2),
- state.mFullscreenStackSysUiVisibility, state.mDockedStackSysUiVisibility,
- state.mImeToken, state.mFullscreenStackBounds, state.mDockedStackBounds,
- state.mNavbarColorManagedByIme, state.mFullscreen, state.mImmersive);
+ gatherDisableActionsLocked(mCurrentUserId, 2), state.mImeToken,
+ state.mNavbarColorManagedByIme, state.mFullscreen, state.mImmersive,
+ transientBarTypes);
}
}
diff --git a/services/core/java/com/android/server/wallpaper/GLHelper.java b/services/core/java/com/android/server/wallpaper/GLHelper.java
new file mode 100644
index 000000000000..1d733f53f055
--- /dev/null
+++ b/services/core/java/com/android/server/wallpaper/GLHelper.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2019 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.server.wallpaper;
+
+import static android.opengl.EGL14.EGL_ALPHA_SIZE;
+import static android.opengl.EGL14.EGL_BLUE_SIZE;
+import static android.opengl.EGL14.EGL_CONFIG_CAVEAT;
+import static android.opengl.EGL14.EGL_CONTEXT_CLIENT_VERSION;
+import static android.opengl.EGL14.EGL_DEFAULT_DISPLAY;
+import static android.opengl.EGL14.EGL_DEPTH_SIZE;
+import static android.opengl.EGL14.EGL_GREEN_SIZE;
+import static android.opengl.EGL14.EGL_HEIGHT;
+import static android.opengl.EGL14.EGL_NONE;
+import static android.opengl.EGL14.EGL_NO_CONTEXT;
+import static android.opengl.EGL14.EGL_NO_DISPLAY;
+import static android.opengl.EGL14.EGL_NO_SURFACE;
+import static android.opengl.EGL14.EGL_OPENGL_ES2_BIT;
+import static android.opengl.EGL14.EGL_RED_SIZE;
+import static android.opengl.EGL14.EGL_RENDERABLE_TYPE;
+import static android.opengl.EGL14.EGL_STENCIL_SIZE;
+import static android.opengl.EGL14.EGL_WIDTH;
+import static android.opengl.EGL14.eglChooseConfig;
+import static android.opengl.EGL14.eglCreateContext;
+import static android.opengl.EGL14.eglCreatePbufferSurface;
+import static android.opengl.EGL14.eglDestroyContext;
+import static android.opengl.EGL14.eglDestroySurface;
+import static android.opengl.EGL14.eglGetDisplay;
+import static android.opengl.EGL14.eglGetError;
+import static android.opengl.EGL14.eglInitialize;
+import static android.opengl.EGL14.eglMakeCurrent;
+import static android.opengl.EGL14.eglTerminate;
+import static android.opengl.GLES20.GL_MAX_TEXTURE_SIZE;
+import static android.opengl.GLES20.glGetIntegerv;
+
+import android.opengl.EGLConfig;
+import android.opengl.EGLContext;
+import android.opengl.EGLDisplay;
+import android.opengl.EGLSurface;
+import android.opengl.GLUtils;
+import android.os.SystemProperties;
+import android.util.Log;
+
+class GLHelper {
+ private static final String TAG = GLHelper.class.getSimpleName();
+ private static final int sMaxTextureSize;
+
+ static {
+ int maxTextureSize = SystemProperties.getInt("sys.max_texture_size", 0);
+ sMaxTextureSize = maxTextureSize > 0 ? maxTextureSize : retrieveTextureSizeFromGL();
+ }
+
+ private static int retrieveTextureSizeFromGL() {
+ try {
+ String err;
+
+ // Before we can retrieve info from GL,
+ // we have to create EGLContext, EGLConfig and EGLDisplay first.
+ // We will fail at querying info from GL once one of above failed.
+ // When this happens, we will use defValue instead.
+ EGLDisplay eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ if (eglDisplay == null || eglDisplay == EGL_NO_DISPLAY) {
+ err = "eglGetDisplay failed: " + GLUtils.getEGLErrorString(eglGetError());
+ throw new RuntimeException(err);
+ }
+
+ if (!eglInitialize(eglDisplay, null, 0 /* majorOffset */, null, 1 /* minorOffset */)) {
+ err = "eglInitialize failed: " + GLUtils.getEGLErrorString(eglGetError());
+ throw new RuntimeException(err);
+ }
+
+ EGLConfig eglConfig = null;
+ int[] configsCount = new int[1];
+ EGLConfig[] configs = new EGLConfig[1];
+ int[] configSpec = new int[] {
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+ EGL_RED_SIZE, 8,
+ EGL_GREEN_SIZE, 8,
+ EGL_BLUE_SIZE, 8,
+ EGL_ALPHA_SIZE, 0,
+ EGL_DEPTH_SIZE, 0,
+ EGL_STENCIL_SIZE, 0,
+ EGL_CONFIG_CAVEAT, EGL_NONE,
+ EGL_NONE
+ };
+
+ if (!eglChooseConfig(eglDisplay, configSpec, 0 /* attrib_listOffset */,
+ configs, 0 /* configOffset */, 1 /* config_size */,
+ configsCount, 0 /* num_configOffset */)) {
+ err = "eglChooseConfig failed: " + GLUtils.getEGLErrorString(eglGetError());
+ throw new RuntimeException(err);
+ } else if (configsCount[0] > 0) {
+ eglConfig = configs[0];
+ }
+
+ if (eglConfig == null) {
+ throw new RuntimeException("eglConfig not initialized!");
+ }
+
+ int[] attr_list = new int[] {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
+ EGLContext eglContext = eglCreateContext(
+ eglDisplay, eglConfig, EGL_NO_CONTEXT, attr_list, 0 /* offset */);
+
+ if (eglContext == null || eglContext == EGL_NO_CONTEXT) {
+ err = "eglCreateContext failed: " + GLUtils.getEGLErrorString(eglGetError());
+ throw new RuntimeException(err);
+ }
+
+ // We create a push buffer temporarily for querying info from GL.
+ int[] attrs = {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE};
+ EGLSurface eglSurface =
+ eglCreatePbufferSurface(eglDisplay, eglConfig, attrs, 0 /* offset */);
+ eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
+
+ // Now, we are ready to query the info from GL.
+ int[] maxSize = new int[1];
+ glGetIntegerv(GL_MAX_TEXTURE_SIZE, maxSize, 0 /* offset */);
+
+ // We have got the info we want, release all egl resources.
+ eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ eglDestroySurface(eglDisplay, eglSurface);
+ eglDestroyContext(eglDisplay, eglContext);
+ eglTerminate(eglDisplay);
+ return maxSize[0];
+ } catch (RuntimeException e) {
+ Log.w(TAG, "Retrieve from GL failed", e);
+ return Integer.MAX_VALUE;
+ }
+ }
+
+ static int getMaxTextureSize() {
+ return sMaxTextureSize;
+ }
+}
+
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 3663f4696a27..3cc6428c792b 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -134,6 +134,9 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
private static final boolean DEBUG = false;
private static final boolean DEBUG_LIVE = true;
+ // This 100MB limitation is defined in RecordingCanvas.
+ private static final int MAX_BITMAP_SIZE = 100 * 1024 * 1024;
+
public static class Lifecycle extends SystemService {
private IWallpaperManagerService mService;
@@ -572,7 +575,9 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
// Only generate crop for default display.
final DisplayData wpData = getDisplayDataOrCreate(DEFAULT_DISPLAY);
- Rect cropHint = new Rect(wallpaper.cropHint);
+ final Rect cropHint = new Rect(wallpaper.cropHint);
+ final DisplayInfo displayInfo = new DisplayInfo();
+ mDisplayManager.getDisplay(DEFAULT_DISPLAY).getDisplayInfo(displayInfo);
if (DEBUG) {
Slog.v(TAG, "Generating crop for new wallpaper(s): 0x"
@@ -618,12 +623,12 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
}
// scale if the crop height winds up not matching the recommended metrics
- needScale = (wpData.mHeight != cropHint.height());
+ needScale = wpData.mHeight != cropHint.height()
+ || cropHint.height() > GLHelper.getMaxTextureSize()
+ || cropHint.width() > GLHelper.getMaxTextureSize();
//make sure screen aspect ratio is preserved if width is scaled under screen size
if (needScale) {
- final DisplayInfo displayInfo = new DisplayInfo();
- mDisplayManager.getDisplay(DEFAULT_DISPLAY).getDisplayInfo(displayInfo);
final float scaleByHeight = (float) wpData.mHeight / (float) cropHint.height();
final int newWidth = (int) (cropHint.width() * scaleByHeight);
if (newWidth < displayInfo.logicalWidth) {
@@ -644,14 +649,29 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
if (!needCrop && !needScale) {
// Simple case: the nominal crop fits what we want, so we take
// the whole thing and just copy the image file directly.
- if (DEBUG) {
- Slog.v(TAG, "Null crop of new wallpaper; copying");
+
+ // TODO: It is not accurate to estimate bitmap size without decoding it,
+ // may be we can try to remove this optimized way in the future,
+ // that means, we will always go into the 'else' block.
+
+ // This is just a quick estimation, may be smaller than it is.
+ long estimateSize = options.outWidth * options.outHeight * 4;
+
+ // A bitmap over than MAX_BITMAP_SIZE will make drawBitmap() fail.
+ // Please see: RecordingCanvas#throwIfCannotDraw.
+ if (estimateSize < MAX_BITMAP_SIZE) {
+ success = FileUtils.copyFile(wallpaper.wallpaperFile, wallpaper.cropFile);
}
- success = FileUtils.copyFile(wallpaper.wallpaperFile, wallpaper.cropFile);
+
if (!success) {
wallpaper.cropFile.delete();
// TODO: fall back to default wallpaper in this case
}
+
+ if (DEBUG) {
+ Slog.v(TAG, "Null crop of new wallpaper, estimate size="
+ + estimateSize + ", success=" + success);
+ }
} else {
// Fancy case: crop and scale. First, we decode and scale down if appropriate.
FileOutputStream f = null;
@@ -665,49 +685,78 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
// We calculate the largest power-of-two under the actual ratio rather than
// just let the decode take care of it because we also want to remap where the
// cropHint rectangle lies in the decoded [super]rect.
- final BitmapFactory.Options scaler;
final int actualScale = cropHint.height() / wpData.mHeight;
int scale = 1;
- while (2*scale < actualScale) {
+ while (2 * scale <= actualScale) {
scale *= 2;
}
- if (scale > 1) {
- scaler = new BitmapFactory.Options();
- scaler.inSampleSize = scale;
+ options.inSampleSize = scale;
+ options.inJustDecodeBounds = false;
+
+ final Rect estimateCrop = new Rect(cropHint);
+ estimateCrop.scale(1f / options.inSampleSize);
+ final float hRatio = (float) wpData.mHeight / estimateCrop.height();
+ final int destHeight = (int) (estimateCrop.height() * hRatio);
+ final int destWidth = (int) (estimateCrop.width() * hRatio);
+
+ // We estimated an invalid crop, try to adjust the cropHint to get a valid one.
+ if (destWidth > GLHelper.getMaxTextureSize()) {
+ int newHeight = (int) (wpData.mHeight / hRatio);
+ int newWidth = (int) (wpData.mWidth / hRatio);
+
if (DEBUG) {
- Slog.v(TAG, "Downsampling cropped rect with scale " + scale);
+ Slog.v(TAG, "Invalid crop dimensions, trying to adjust.");
}
- } else {
- scaler = null;
+
+ estimateCrop.set(cropHint);
+ estimateCrop.left += (cropHint.width() - newWidth) / 2;
+ estimateCrop.top += (cropHint.height() - newHeight) / 2;
+ estimateCrop.right = estimateCrop.left + newWidth;
+ estimateCrop.bottom = estimateCrop.top + newHeight;
+ cropHint.set(estimateCrop);
+ estimateCrop.scale(1f / options.inSampleSize);
+ }
+
+ // We've got the safe cropHint; now we want to scale it properly to
+ // the desired rectangle.
+ // That's a height-biased operation: make it fit the hinted height.
+ final int safeHeight = (int) (estimateCrop.height() * hRatio);
+ final int safeWidth = (int) (estimateCrop.width() * hRatio);
+
+ if (DEBUG) {
+ Slog.v(TAG, "Decode parameters:");
+ Slog.v(TAG, " cropHint=" + cropHint + ", estimateCrop=" + estimateCrop);
+ Slog.v(TAG, " down sampling=" + options.inSampleSize
+ + ", hRatio=" + hRatio);
+ Slog.v(TAG, " dest=" + destWidth + "x" + destHeight);
+ Slog.v(TAG, " safe=" + safeWidth + "x" + safeHeight);
+ Slog.v(TAG, " maxTextureSize=" + GLHelper.getMaxTextureSize());
}
- Bitmap cropped = decoder.decodeRegion(cropHint, scaler);
+
+ Bitmap cropped = decoder.decodeRegion(cropHint, options);
decoder.recycle();
if (cropped == null) {
Slog.e(TAG, "Could not decode new wallpaper");
} else {
- // We've got the extracted crop; now we want to scale it properly to
- // the desired rectangle. That's a height-biased operation: make it
- // fit the hinted height, and accept whatever width we end up with.
- cropHint.offsetTo(0, 0);
- cropHint.right /= scale; // adjust by downsampling factor
- cropHint.bottom /= scale;
- final float heightR =
- ((float) wpData.mHeight) / ((float) cropHint.height());
- if (DEBUG) {
- Slog.v(TAG, "scale " + heightR + ", extracting " + cropHint);
- }
- final int destWidth = (int)(cropHint.width() * heightR);
+ // We are safe to create final crop with safe dimensions now.
final Bitmap finalCrop = Bitmap.createScaledBitmap(cropped,
- destWidth, wpData.mHeight, true);
+ safeWidth, safeHeight, true);
if (DEBUG) {
Slog.v(TAG, "Final extract:");
Slog.v(TAG, " dims: w=" + wpData.mWidth
+ " h=" + wpData.mHeight);
- Slog.v(TAG, " out: w=" + finalCrop.getWidth()
+ Slog.v(TAG, " out: w=" + finalCrop.getWidth()
+ " h=" + finalCrop.getHeight());
}
+ // A bitmap over than MAX_BITMAP_SIZE will make drawBitmap() fail.
+ // Please see: RecordingCanvas#throwIfCannotDraw.
+ if (finalCrop.getByteCount() > MAX_BITMAP_SIZE) {
+ throw new RuntimeException(
+ "Too large bitmap, limit=" + MAX_BITMAP_SIZE);
+ }
+
f = new FileOutputStream(wallpaper.cropFile);
bos = new BufferedOutputStream(f, 32*1024);
finalCrop.compress(Bitmap.CompressFormat.JPEG, 100, bos);
@@ -1997,6 +2046,11 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
if (!isWallpaperSupported(callingPackage)) {
return;
}
+
+ // Make sure both width and height are not larger than max texture size.
+ width = Math.min(width, GLHelper.getMaxTextureSize());
+ height = Math.min(height, GLHelper.getMaxTextureSize());
+
synchronized (mLock) {
int userId = UserHandle.getCallingUserId();
WallpaperData wallpaper = getWallpaperSafeLocked(userId, FLAG_SYSTEM);
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 6e238b33d8dd..fcfd9ded9ad7 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -144,13 +144,16 @@ import android.view.InputChannel;
import android.view.InputDevice;
import android.view.InputEvent;
import android.view.InputEventReceiver;
+import android.view.InsetsFlags;
import android.view.InsetsState;
+import android.view.InsetsState.InternalInsetType;
import android.view.MotionEvent;
import android.view.PointerIcon;
import android.view.Surface;
import android.view.View;
import android.view.ViewRootImpl;
import android.view.WindowInsets;
+import android.view.WindowInsetsController.Appearance;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.view.WindowManagerGlobal;
@@ -332,8 +335,6 @@ public class DisplayPolicy {
private int mResettingSystemUiFlags = 0;
// Bits that we are currently always keeping cleared.
private int mForceClearedSystemUiFlags = 0;
- private int mLastFullscreenStackSysUiFlags;
- private int mLastDockedStackSysUiFlags;
private int mLastAppearance;
private int mLastFullscreenAppearance;
private int mLastDockedAppearance;
@@ -3172,11 +3173,6 @@ public class DisplayPolicy {
&= ~PolicyControl.adjustClearableFlags(win, View.SYSTEM_UI_CLEARABLE_FLAGS);
}
- final int appearance = win.mAttrs.insetsFlags.appearance;
- final int fullscreenVisibility = updateLightStatusBarLw(0 /* vis */,
- mTopFullscreenOpaqueWindowState, mTopFullscreenOpaqueOrDimmingWindowState);
- final int dockedVisibility = updateLightStatusBarLw(0 /* vis */,
- mTopDockedOpaqueWindowState, mTopDockedOpaqueOrDimmingWindowState);
final int fullscreenAppearance = updateLightStatusBarAppearanceLw(0 /* vis */,
mTopFullscreenOpaqueWindowState, mTopFullscreenOpaqueOrDimmingWindowState);
final int dockedAppearance = updateLightStatusBarAppearanceLw(0 /* vis */,
@@ -3190,9 +3186,9 @@ public class DisplayPolicy {
final Pair<Integer, Boolean> result =
updateSystemBarsLw(win, mLastSystemUiFlags, tmpVisibility);
final int visibility = result.first;
+ final int appearance = win.mAttrs.insetsFlags.appearance
+ | InsetsFlags.getAppearance(visibility);
final int diff = visibility ^ mLastSystemUiFlags;
- final int fullscreenDiff = fullscreenVisibility ^ mLastFullscreenStackSysUiFlags;
- final int dockedDiff = dockedVisibility ^ mLastDockedStackSysUiFlags;
final InsetsPolicy insetsPolicy = getInsetsPolicy();
final boolean isFullscreen = (visibility & (View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION)) != 0
@@ -3205,7 +3201,7 @@ public class DisplayPolicy {
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY)) != 0
|| behavior == BEHAVIOR_SHOW_BARS_BY_SWIPE
|| behavior == BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
- if (diff == 0 && fullscreenDiff == 0 && dockedDiff == 0
+ if (diff == 0
&& mLastAppearance == appearance
&& mLastFullscreenAppearance == fullscreenAppearance
&& mLastDockedAppearance == dockedAppearance
@@ -3216,9 +3212,12 @@ public class DisplayPolicy {
&& mLastDockedStackBounds.equals(mDockedStackBounds)) {
return 0;
}
+
+ // Obtains which types should show transient and which types should abort transient.
+ // If there is no transient state change, this pair will contain two empty arrays.
+ final Pair<int[], int[]> transientState = getTransientState(visibility, mLastSystemUiFlags);
+
mLastSystemUiFlags = visibility;
- mLastFullscreenStackSysUiFlags = fullscreenVisibility;
- mLastDockedStackSysUiFlags = dockedVisibility;
mLastAppearance = appearance;
mLastFullscreenAppearance = fullscreenAppearance;
mLastDockedAppearance = dockedAppearance;
@@ -3240,14 +3239,16 @@ public class DisplayPolicy {
StatusBarManagerInternal statusBar = getStatusBarManagerInternal();
if (statusBar != null) {
final int displayId = getDisplayId();
- // TODO(b/118118435): disabled flags only
- statusBar.setSystemUiVisibility(displayId, visibility, fullscreenVisibility,
- dockedVisibility, 0xffffffff, fullscreenStackBounds,
- dockedStackBounds, isNavbarColorManagedByIme, win.toString());
- if (ViewRootImpl.sNewInsetsMode == NEW_INSETS_MODE_FULL) {
- statusBar.onSystemBarAppearanceChanged(displayId, appearance,
- appearanceRegions, isNavbarColorManagedByIme);
+ statusBar.setDisableFlags(displayId, visibility & StatusBarManager.DISABLE_MASK,
+ win.toString());
+ if (transientState.first.length > 0) {
+ statusBar.showTransient(displayId, transientState.first);
}
+ if (transientState.second.length > 0) {
+ statusBar.abortTransient(displayId, transientState.second);
+ }
+ statusBar.onSystemBarAppearanceChanged(displayId, appearance,
+ appearanceRegions, isNavbarColorManagedByIme);
statusBar.topAppWindowChanged(displayId, isFullscreen, isImmersive);
// TODO(b/118118435): Remove this after removing system UI visibilities.
@@ -3258,23 +3259,28 @@ public class DisplayPolicy {
return diff;
}
- private int updateLightStatusBarLw(int vis, WindowState opaque, WindowState opaqueOrDimming) {
- final boolean onKeyguard = isStatusBarKeyguard() && !isKeyguardOccluded();
- final WindowState statusColorWin = onKeyguard ? mStatusBar : opaqueOrDimming;
- if (statusColorWin != null && (statusColorWin == opaque || onKeyguard)) {
- // If the top fullscreen-or-dimming window is also the top fullscreen, respect
- // its light flag.
- vis &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
- vis |= PolicyControl.getSystemUiVisibility(statusColorWin, null)
- & View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
- } else if (statusColorWin != null && statusColorWin.isDimming()) {
- // Otherwise if it's dimming, clear the light flag.
- vis &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
+ private static Pair<int[], int[]> getTransientState(int vis, int oldVis) {
+ final IntArray typesToShow = new IntArray(0);
+ final IntArray typesToAbort = new IntArray(0);
+ updateTransientState(vis, oldVis, View.STATUS_BAR_TRANSIENT, TYPE_TOP_BAR, typesToShow,
+ typesToAbort);
+ updateTransientState(vis, oldVis, View.NAVIGATION_BAR_TRANSIENT,
+ InsetsState.TYPE_NAVIGATION_BAR, typesToShow, typesToAbort);
+ return Pair.create(typesToShow.toArray(), typesToAbort.toArray());
+ }
+
+ private static void updateTransientState(int vis, int oldVis, int transientFlag,
+ @InternalInsetType int type, IntArray typesToShow, IntArray typesToAbort) {
+ final boolean wasTransient = (oldVis & transientFlag) != 0;
+ final boolean isTransient = (vis & transientFlag) != 0;
+ if (!wasTransient && isTransient) {
+ typesToShow.add(type);
+ } else if (wasTransient && !isTransient) {
+ typesToAbort.add(type);
}
- return vis;
}
- private int updateLightStatusBarAppearanceLw(int appearance, WindowState opaque,
+ private int updateLightStatusBarAppearanceLw(@Appearance int appearance, WindowState opaque,
WindowState opaqueOrDimming) {
final boolean onKeyguard = isStatusBarKeyguard() && !isKeyguardOccluded();
final WindowState statusColorWin = onKeyguard ? mStatusBar : opaqueOrDimming;
@@ -3282,7 +3288,10 @@ public class DisplayPolicy {
// If the top fullscreen-or-dimming window is also the top fullscreen, respect
// its light flag.
appearance &= ~APPEARANCE_LIGHT_TOP_BAR;
- appearance |= statusColorWin.mAttrs.insetsFlags.appearance & APPEARANCE_LIGHT_TOP_BAR;
+ final int legacyAppearance = InsetsFlags.getAppearance(
+ PolicyControl.getSystemUiVisibility(statusColorWin, null));
+ appearance |= (statusColorWin.mAttrs.insetsFlags.appearance | legacyAppearance)
+ & APPEARANCE_LIGHT_TOP_BAR;
} else if (statusColorWin != null && statusColorWin.isDimming()) {
// Otherwise if it's dimming, clear the light flag.
appearance &= ~APPEARANCE_LIGHT_TOP_BAR;
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 1d11acd61a68..344befad8fa9 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -638,7 +638,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
private boolean mIsDimming = false;
private @Nullable InsetsSourceProvider mControllableInsetProvider;
- private InsetsState mClientInsetsState = new InsetsState();
+ private InsetsState mClientInsetsState;
private static final float DEFAULT_DIM_AMOUNT_DEAD_WINDOW = 0.5f;
private KeyInterceptionInfo mKeyInterceptionInfo;
@@ -767,6 +767,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
mSeq = seq;
mPowerManagerWrapper = powerManagerWrapper;
mForceSeamlesslyRotate = token.mRoundedCornerOverlay;
+ mClientInsetsState =
+ getDisplayContent().getInsetsStateController().getInsetsForDispatch(this);
if (DEBUG) {
Slog.v(TAG, "Window " + this + " client=" + c.asBinder()
+ " token=" + token + " (" + mAttrs.token + ")" + " params=" + a);
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java
index 8c2ae5a7659a..55947ae9626f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java
@@ -178,11 +178,14 @@ public class InsetsPolicyTest extends WindowTestsBase {
@Test
public void testShowTransientBars_topCanBeTransient_appGetsTopFakeControl() {
+ // Adding app window before setting source visibility is to prevent the visibility from
+ // being cleared by InsetsSourceProvider.updateVisibility.
+ final WindowState app = addWindow(TYPE_APPLICATION, "app");
+
addWindow(TYPE_STATUS_BAR, "topBar")
.getControllableInsetProvider().getSource().setVisible(false);
addWindow(TYPE_NAVIGATION_BAR, "navBar")
.getControllableInsetProvider().getSource().setVisible(true);
- final WindowState app = addWindow(TYPE_APPLICATION, "app");
final InsetsPolicy policy = mDisplayContent.getInsetsPolicy();
policy.updateBarControlTarget(app);
diff --git a/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassBase.java b/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassBase.java
index 7d88161a2805..176c7a0ada7b 100644
--- a/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassBase.java
+++ b/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassBase.java
@@ -32,7 +32,7 @@ public class HierrarchicalDataClassBase implements Parcelable {
- // Code below generated by codegen v1.0.12.
+ // Code below generated by codegen v1.0.13.
//
// DO NOT MODIFY!
// CHECKSTYLE:OFF Generated code
@@ -98,8 +98,8 @@ public class HierrarchicalDataClassBase implements Parcelable {
};
@DataClass.Generated(
- time = 1572655992854L,
- codegenVersion = "1.0.12",
+ time = 1573006405823L,
+ codegenVersion = "1.0.13",
sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassBase.java",
inputSignatures = "private int mBaseData\nclass HierrarchicalDataClassBase extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genConstructor=false, genSetters=true)")
@Deprecated
diff --git a/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassChild.java b/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassChild.java
index c930ce535ab6..e348c77c0ac6 100644
--- a/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassChild.java
+++ b/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassChild.java
@@ -46,7 +46,7 @@ public class HierrarchicalDataClassChild extends HierrarchicalDataClassBase {
- // Code below generated by codegen v1.0.12.
+ // Code below generated by codegen v1.0.13.
//
// DO NOT MODIFY!
// CHECKSTYLE:OFF Generated code
@@ -120,8 +120,8 @@ public class HierrarchicalDataClassChild extends HierrarchicalDataClassBase {
};
@DataClass.Generated(
- time = 1572655993858L,
- codegenVersion = "1.0.12",
+ time = 1573006406833L,
+ codegenVersion = "1.0.13",
sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassChild.java",
inputSignatures = "private @android.annotation.NonNull java.lang.String mChildData\nclass HierrarchicalDataClassChild extends com.android.codegentest.HierrarchicalDataClassBase implements []\n@com.android.internal.util.DataClass(genParcelable=true, genConstructor=false, genSetters=true)")
@Deprecated
diff --git a/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java b/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java
index 368a5c3a81e8..112d3df02280 100644
--- a/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java
+++ b/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java
@@ -19,6 +19,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Parcel;
import android.os.Parcelable;
+import android.util.ArrayMap;
import android.util.SparseArray;
import android.util.SparseIntArray;
@@ -52,7 +53,8 @@ public class ParcelAllTheThingsDataClass implements Parcelable {
- // Code below generated by codegen v1.0.12.
+
+ // Code below generated by codegen v1.0.13.
//
// DO NOT MODIFY!
// CHECKSTYLE:OFF Generated code
@@ -410,8 +412,8 @@ public class ParcelAllTheThingsDataClass implements Parcelable {
}
@DataClass.Generated(
- time = 1572655991821L,
- codegenVersion = "1.0.12",
+ time = 1573006404728L,
+ codegenVersion = "1.0.13",
sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java",
inputSignatures = " @android.annotation.NonNull java.lang.String[] mStringArray\n @android.annotation.NonNull int[] mIntArray\n @android.annotation.NonNull java.util.List<java.lang.String> mStringList\n @android.annotation.NonNull java.util.Map<java.lang.String,com.android.codegentest.SampleWithCustomBuilder> mMap\n @android.annotation.NonNull java.util.Map<java.lang.String,java.lang.String> mStringMap\n @android.annotation.NonNull android.util.SparseArray<com.android.codegentest.SampleWithCustomBuilder> mSparseArray\n @android.annotation.NonNull android.util.SparseIntArray mSparseIntArray\n @java.lang.SuppressWarnings({\"WeakerAccess\"}) @android.annotation.Nullable java.lang.Boolean mNullableBoolean\nclass ParcelAllTheThingsDataClass extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genBuilder=true, genAidl=false, genToString=true)")
@Deprecated
diff --git a/tests/Codegen/src/com/android/codegentest/SampleDataClass.java b/tests/Codegen/src/com/android/codegentest/SampleDataClass.java
index 9d52287d631e..0fdcf5918c81 100644
--- a/tests/Codegen/src/com/android/codegentest/SampleDataClass.java
+++ b/tests/Codegen/src/com/android/codegentest/SampleDataClass.java
@@ -342,7 +342,7 @@ public final class SampleDataClass implements Parcelable {
- // Code below generated by codegen v1.0.12.
+ // Code below generated by codegen v1.0.13.
//
// DO NOT MODIFY!
// CHECKSTYLE:OFF Generated code
@@ -1872,8 +1872,8 @@ public final class SampleDataClass implements Parcelable {
}
@DataClass.Generated(
- time = 1572655989589L,
- codegenVersion = "1.0.12",
+ time = 1573006402566L,
+ codegenVersion = "1.0.13",
sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/SampleDataClass.java",
inputSignatures = "public static final java.lang.String STATE_NAME_UNDEFINED\npublic static final java.lang.String STATE_NAME_ON\npublic static final java.lang.String STATE_NAME_OFF\npublic static final int STATE_UNDEFINED\npublic static final int STATE_ON\npublic static final int STATE_OFF\npublic static final @com.android.codegentest.SampleDataClass.RequestFlags int FLAG_MANUAL_REQUEST\npublic static final @com.android.codegentest.SampleDataClass.RequestFlags int FLAG_COMPATIBILITY_MODE_REQUEST\npublic static final @com.android.codegentest.SampleDataClass.RequestFlags int FLAG_AUGMENTED_REQUEST\nprivate int mNum\nprivate int mNum2\nprivate int mNum4\nprivate @android.annotation.Nullable java.lang.String mName\nprivate @android.annotation.NonNull java.lang.String mName2\nprivate @android.annotation.NonNull java.lang.String mName4\nprivate @android.annotation.Nullable android.view.accessibility.AccessibilityNodeInfo mOtherParcelable\nprivate @com.android.internal.util.DataClass.ParcelWith(com.android.codegentest.MyDateParcelling.class) @android.annotation.NonNull java.util.Date mDate\nprivate @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForPattern.class) @android.annotation.NonNull java.util.regex.Pattern mPattern\nprivate @android.annotation.NonNull java.util.List<android.net.LinkAddress> mLinkAddresses2\nprivate @com.android.internal.util.DataClass.PluralOf(\"linkAddress\") @android.annotation.NonNull java.util.ArrayList<android.net.LinkAddress> mLinkAddresses\nprivate @android.annotation.Nullable android.net.LinkAddress[] mLinkAddresses4\nprivate @com.android.codegentest.SampleDataClass.StateName @android.annotation.NonNull java.lang.String mStateName\nprivate @com.android.codegentest.SampleDataClass.RequestFlags int mFlags\nprivate @com.android.codegentest.SampleDataClass.State int mState\npublic @android.annotation.NonNull java.lang.CharSequence charSeq\nprivate final @android.annotation.Nullable android.net.LinkAddress[] mLinkAddresses5\nprivate transient android.net.LinkAddress[] mLinkAddresses6\ntransient int[] mTmpStorage\nprivate @android.annotation.StringRes int mStringRes\nprivate @android.annotation.IntRange(from=0L, to=6L) int mDayOfWeek\nprivate @android.annotation.Size(2L) @android.annotation.NonNull @com.android.internal.util.DataClass.Each @android.annotation.FloatRange(from=0.0) float[] mCoords\nprivate static java.lang.String defaultName4()\nprivate int[] lazyInitTmpStorage()\npublic android.net.LinkAddress[] getLinkAddresses4()\nprivate boolean patternEquals(java.util.regex.Pattern)\nprivate int patternHashCode()\nprivate void onConstructed()\npublic void dump(java.io.PrintWriter)\nclass SampleDataClass extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genBuilder=true, genConstructor=true, genEqualsHashCode=true, genToString=true, genForEachField=true, genSetters=true)")
@Deprecated
diff --git a/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java b/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java
index cef32d1051df..cab477dafae9 100644
--- a/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java
+++ b/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java
@@ -85,7 +85,7 @@ public class SampleWithCustomBuilder implements Parcelable {
- // Code below generated by codegen v1.0.12.
+ // Code below generated by codegen v1.0.13.
//
// DO NOT MODIFY!
// CHECKSTYLE:OFF Generated code
@@ -253,8 +253,8 @@ public class SampleWithCustomBuilder implements Parcelable {
}
@DataClass.Generated(
- time = 1572655990725L,
- codegenVersion = "1.0.12",
+ time = 1573006403628L,
+ codegenVersion = "1.0.13",
sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java",
inputSignatures = " long delayAmount\n @android.annotation.NonNull java.util.concurrent.TimeUnit delayUnit\n long creationTimestamp\nprivate static java.util.concurrent.TimeUnit unparcelDelayUnit(android.os.Parcel)\nprivate void parcelDelayUnit(android.os.Parcel,int)\nclass SampleWithCustomBuilder extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genBuilder=true, genAidl=false, genToString=true)\nabstract com.android.codegentest.SampleWithCustomBuilder.Builder setDelayAmount(long)\npublic abstract com.android.codegentest.SampleWithCustomBuilder.Builder setDelayUnit(java.util.concurrent.TimeUnit)\npublic com.android.codegentest.SampleWithCustomBuilder.Builder setDelay(long,java.util.concurrent.TimeUnit)\nclass BaseBuilder extends java.lang.Object implements []")
@Deprecated
diff --git a/tests/Codegen/src/com/android/codegentest/SampleWithNestedDataClasses.java b/tests/Codegen/src/com/android/codegentest/SampleWithNestedDataClasses.java
index 27055f6a4df8..6190085a4d82 100644
--- a/tests/Codegen/src/com/android/codegentest/SampleWithNestedDataClasses.java
+++ b/tests/Codegen/src/com/android/codegentest/SampleWithNestedDataClasses.java
@@ -36,7 +36,7 @@ public class SampleWithNestedDataClasses {
- // Code below generated by codegen v1.0.12.
+ // Code below generated by codegen v1.0.13.
//
// DO NOT MODIFY!
// CHECKSTYLE:OFF Generated code
@@ -135,8 +135,8 @@ public class SampleWithNestedDataClasses {
};
@DataClass.Generated(
- time = 1572655995915L,
- codegenVersion = "1.0.12",
+ time = 1573006408903L,
+ codegenVersion = "1.0.13",
sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/SampleWithNestedDataClasses.java",
inputSignatures = " @android.annotation.NonNull java.lang.String mBar\nclass NestedDataClass extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true)")
@Deprecated
@@ -160,7 +160,7 @@ public class SampleWithNestedDataClasses {
- // Code below generated by codegen v1.0.12.
+ // Code below generated by codegen v1.0.13.
//
// DO NOT MODIFY!
// CHECKSTYLE:OFF Generated code
@@ -259,8 +259,8 @@ public class SampleWithNestedDataClasses {
};
@DataClass.Generated(
- time = 1572655995924L,
- codegenVersion = "1.0.12",
+ time = 1573006408912L,
+ codegenVersion = "1.0.13",
sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/SampleWithNestedDataClasses.java",
inputSignatures = " @android.annotation.NonNull long mBaz2\nclass NestedDataClass3 extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true)")
@Deprecated
@@ -274,7 +274,7 @@ public class SampleWithNestedDataClasses {
- // Code below generated by codegen v1.0.12.
+ // Code below generated by codegen v1.0.13.
//
// DO NOT MODIFY!
// CHECKSTYLE:OFF Generated code
@@ -373,8 +373,8 @@ public class SampleWithNestedDataClasses {
};
@DataClass.Generated(
- time = 1572655995930L,
- codegenVersion = "1.0.12",
+ time = 1573006408917L,
+ codegenVersion = "1.0.13",
sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/SampleWithNestedDataClasses.java",
inputSignatures = " @android.annotation.NonNull java.lang.String mBaz\nclass NestedDataClass2 extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true)")
@Deprecated
diff --git a/tests/Codegen/src/com/android/codegentest/StaleDataclassDetectorFalsePositivesTest.java b/tests/Codegen/src/com/android/codegentest/StaleDataclassDetectorFalsePositivesTest.java
index 4bfec895fdcb..5a960d7dd002 100644
--- a/tests/Codegen/src/com/android/codegentest/StaleDataclassDetectorFalsePositivesTest.java
+++ b/tests/Codegen/src/com/android/codegentest/StaleDataclassDetectorFalsePositivesTest.java
@@ -51,7 +51,7 @@ public class StaleDataclassDetectorFalsePositivesTest {
- // Code below generated by codegen v1.0.12.
+ // Code below generated by codegen v1.0.13.
//
// DO NOT MODIFY!
// CHECKSTYLE:OFF Generated code
@@ -65,8 +65,8 @@ public class StaleDataclassDetectorFalsePositivesTest {
@DataClass.Generated(
- time = 1572655994865L,
- codegenVersion = "1.0.12",
+ time = 1573006407900L,
+ codegenVersion = "1.0.13",
sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/StaleDataclassDetectorFalsePositivesTest.java",
inputSignatures = "public @android.annotation.NonNull java.lang.String someMethod(int)\nclass StaleDataclassDetectorFalsePositivesTest extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genBuilder=false)")
@Deprecated
diff --git a/tools/codegen/src/com/android/codegen/FieldInfo.kt b/tools/codegen/src/com/android/codegen/FieldInfo.kt
index ed35a1dfc599..ebfbbd8163b5 100644
--- a/tools/codegen/src/com/android/codegen/FieldInfo.kt
+++ b/tools/codegen/src/com/android/codegen/FieldInfo.kt
@@ -93,6 +93,8 @@ data class FieldInfo(
// Generic args
val isArray = Type.endsWith("[]")
val isList = FieldClass == "List" || FieldClass == "ArrayList"
+ val isMap = FieldClass == "Map" || FieldClass == "ArrayMap"
+ || FieldClass == "HashMap" || FieldClass == "LinkedHashMap"
val fieldBit = bitAtExpr(index)
var isLast = false
val isFinal = fieldAst.isFinal
@@ -197,7 +199,7 @@ data class FieldInfo(
listOf("String", "CharSequence", "Exception", "Size", "SizeF", "Bundle",
"FileDescriptor", "SparseBooleanArray", "SparseIntArray", "SparseArray") ->
FieldClass
- FieldClass == "Map" && fieldTypeGenegicArgs[0] == "String" -> "Map"
+ isMap && fieldTypeGenegicArgs[0] == "String" -> "Map"
isArray -> when {
FieldInnerType!! in (PRIMITIVE_TYPES + "String") -> FieldInnerType + "Array"
isBinder(FieldInnerType) -> "BinderArray"
diff --git a/tools/codegen/src/com/android/codegen/Generators.kt b/tools/codegen/src/com/android/codegen/Generators.kt
index c25d0c74f251..dc1f4c50abc4 100644
--- a/tools/codegen/src/com/android/codegen/Generators.kt
+++ b/tools/codegen/src/com/android/codegen/Generators.kt
@@ -343,7 +343,7 @@ private fun ClassPrinter.generateBuilderSetters(visibility: String) {
}
}
- if (FieldClass.endsWith("Map") && FieldInnerType != null) {
+ if (isMap && FieldInnerType != null) {
generateBuilderMethod(
name = adderName,
defVisibility = visibility,
@@ -351,7 +351,7 @@ private fun ClassPrinter.generateBuilderSetters(visibility: String) {
paramNames = listOf("key", "value"),
genJavadoc = { +javadocSeeSetter }) {
!singularNameCustomizationHint
- +"if ($name == null) $setterName(new $LinkedHashMap());"
+ +"if ($name == null) $setterName(new ${if (FieldClass == "Map") LinkedHashMap else FieldClass}());"
+"$name.put(key, value);"
+"return$maybeCast this;"
}
@@ -507,7 +507,8 @@ fun ClassPrinter.generateParcelable() {
// Create container if any
val containerInitExpr = when {
- FieldClass.endsWith("Map") -> "new $LinkedHashMap<>()"
+ FieldClass == "Map" -> "new $LinkedHashMap<>()"
+ isMap -> "new $FieldClass()"
FieldClass == "List" || FieldClass == "ArrayList" ->
"new ${classRef("java.util.ArrayList")}<>()"
else -> ""
diff --git a/tools/codegen/src/com/android/codegen/SharedConstants.kt b/tools/codegen/src/com/android/codegen/SharedConstants.kt
index 339057f24833..85c832fcf34f 100644
--- a/tools/codegen/src/com/android/codegen/SharedConstants.kt
+++ b/tools/codegen/src/com/android/codegen/SharedConstants.kt
@@ -1,7 +1,7 @@
package com.android.codegen
const val CODEGEN_NAME = "codegen"
-const val CODEGEN_VERSION = "1.0.12"
+const val CODEGEN_VERSION = "1.0.13"
const val CANONICAL_BUILDER_CLASS = "Builder"
const val BASE_BUILDER_CLASS = "BaseBuilder"
diff --git a/wifi/java/android/net/wifi/ISoftApCallback.aidl b/wifi/java/android/net/wifi/ISoftApCallback.aidl
index 8a252dd1e447..452a655edc7b 100644
--- a/wifi/java/android/net/wifi/ISoftApCallback.aidl
+++ b/wifi/java/android/net/wifi/ISoftApCallback.aidl
@@ -15,6 +15,7 @@
*/
package android.net.wifi;
+import android.net.wifi.SoftApInfo;
import android.net.wifi.WifiClient;
@@ -43,4 +44,11 @@ oneway interface ISoftApCallback
* @param clients the currently connected clients
*/
void onConnectedClientsChanged(in List<WifiClient> clients);
+
+ /**
+ * Service to manager callback providing information of softap.
+ *
+ * @param softApInfo is the softap information. {@link SoftApInfo}
+ */
+ void onInfoChanged(in SoftApInfo softApInfo);
}
diff --git a/wifi/java/android/net/wifi/SoftApInfo.aidl b/wifi/java/android/net/wifi/SoftApInfo.aidl
new file mode 100644
index 000000000000..d4551cfac044
--- /dev/null
+++ b/wifi/java/android/net/wifi/SoftApInfo.aidl
@@ -0,0 +1,20 @@
+/**
+ * Copyright (c) 2019, 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 android.net.wifi;
+
+parcelable SoftApInfo;
+
diff --git a/wifi/java/android/net/wifi/SoftApInfo.java b/wifi/java/android/net/wifi/SoftApInfo.java
new file mode 100644
index 000000000000..375a9774f570
--- /dev/null
+++ b/wifi/java/android/net/wifi/SoftApInfo.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2019 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 android.net.wifi;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+
+/**
+ * A class representing information about SoftAp.
+ * {@see WifiManager}
+ *
+ * @hide
+ */
+@SystemApi
+public final class SoftApInfo implements Parcelable {
+
+ /**
+ * AP Channel bandwidth is invalid.
+ *
+ * @see #getBandwidth()
+ */
+ public static final int CHANNEL_WIDTH_INVALID = 0;
+
+ /**
+ * AP Channel bandwidth is 20 MHZ but no HT.
+ *
+ * @see #getBandwidth()
+ */
+ public static final int CHANNEL_WIDTH_20MHZ_NOHT = 1;
+
+ /**
+ * AP Channel bandwidth is 20 MHZ.
+ *
+ * @see #getBandwidth()
+ */
+ public static final int CHANNEL_WIDTH_20MHZ = 2;
+
+ /**
+ * AP Channel bandwidth is 40 MHZ.
+ *
+ * @see #getBandwidth()
+ */
+ public static final int CHANNEL_WIDTH_40MHZ = 3;
+
+ /**
+ * AP Channel bandwidth is 80 MHZ.
+ *
+ * @see #getBandwidth()
+ */
+ public static final int CHANNEL_WIDTH_80MHZ = 4;
+
+ /**
+ * AP Channel bandwidth is 160 MHZ, but 80MHZ + 80MHZ.
+ *
+ * @see #getBandwidth()
+ */
+ public static final int CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 5;
+
+ /**
+ * AP Channel bandwidth is 160 MHZ.
+ *
+ * @see #getBandwidth()
+ */
+ public static final int CHANNEL_WIDTH_160MHZ = 6;
+
+ /**
+ * @hide
+ */
+ @IntDef(prefix = { "CHANNEL_WIDTH_" }, value = {
+ CHANNEL_WIDTH_INVALID,
+ CHANNEL_WIDTH_20MHZ_NOHT,
+ CHANNEL_WIDTH_20MHZ,
+ CHANNEL_WIDTH_40MHZ,
+ CHANNEL_WIDTH_80MHZ,
+ CHANNEL_WIDTH_80MHZ_PLUS_MHZ,
+ CHANNEL_WIDTH_160MHZ,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Bandwidth {}
+
+
+ /** The frequency which AP resides on. */
+ private int mFrequency = 0;
+
+ @Bandwidth
+ private int mBandwidth = CHANNEL_WIDTH_INVALID;
+
+ /**
+ * Get the frequency which AP resides on.
+ */
+ public int getFrequency() {
+ return mFrequency;
+ }
+
+ /**
+ * Set the frequency which AP resides on.
+ * @hide
+ */
+ public void setFrequency(int freq) {
+ mFrequency = freq;
+ }
+
+ /**
+ * Get AP Channel bandwidth.
+ *
+ * @return One of {@link #CHANNEL_WIDTH_20MHZ}, {@link #CHANNEL_WIDTH_40MHZ},
+ * {@link #CHANNEL_WIDTH_80MHZ}, {@link #CHANNEL_WIDTH_160MHZ},
+ * {@link #CHANNEL_WIDTH_80MHZ_PLUS_MHZ} or {@link #CHANNEL_WIDTH_UNKNOWN}.
+ */
+ @Bandwidth
+ public int getBandwidth() {
+ return mBandwidth;
+ }
+
+ /**
+ * Set AP Channel bandwidth.
+ * @hide
+ */
+ public void setBandwidth(@Bandwidth int bandwidth) {
+ mBandwidth = bandwidth;
+ }
+
+ /**
+ * @hide
+ */
+ public SoftApInfo(@Nullable SoftApInfo source) {
+ if (source != null) {
+ mFrequency = source.mFrequency;
+ mBandwidth = source.mBandwidth;
+ }
+ }
+
+ /**
+ * @hide
+ */
+ public SoftApInfo() {
+ }
+
+ @Override
+ /** Implement the Parcelable interface. */
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ /** Implement the Parcelable interface */
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeInt(mFrequency);
+ dest.writeInt(mBandwidth);
+ }
+
+ @NonNull
+ /** Implement the Parcelable interface */
+ public static final Creator<SoftApInfo> CREATOR = new Creator<SoftApInfo>() {
+ public SoftApInfo createFromParcel(Parcel in) {
+ SoftApInfo info = new SoftApInfo();
+ info.mFrequency = in.readInt();
+ info.mBandwidth = in.readInt();
+ return info;
+ }
+
+ public SoftApInfo[] newArray(int size) {
+ return new SoftApInfo[size];
+ }
+ };
+
+ @NonNull
+ @Override
+ public String toString() {
+ return "SoftApInfo{"
+ + "bandwidth= " + mBandwidth
+ + ",frequency= " + mFrequency
+ + '}';
+ }
+
+ @Override
+ public boolean equals(@NonNull Object o) {
+ if (this == o) return true;
+ if (!(o instanceof SoftApInfo)) return false;
+ SoftApInfo softApInfo = (SoftApInfo) o;
+ return mFrequency == softApInfo.mFrequency
+ && mBandwidth == softApInfo.mBandwidth;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mFrequency, mBandwidth);
+ }
+}
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 07831c71b0d3..8108fef5d3ee 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -3315,6 +3315,15 @@ public class WifiManager {
* @param clients the currently connected clients
*/
void onConnectedClientsChanged(@NonNull List<WifiClient> clients);
+
+ /**
+ * Called when information of softap changes.
+ *
+ * @param softApInfo is the softap information. {@link SoftApInfo}
+ */
+ default void onInfoChanged(@NonNull SoftApInfo softApInfo) {
+ // Do nothing: can be updated to add SoftApInfo details (e.g. channel) to the UI.
+ }
}
/**
@@ -3354,6 +3363,16 @@ public class WifiManager {
mCallback.onConnectedClientsChanged(clients);
});
}
+
+ @Override
+ public void onInfoChanged(SoftApInfo softApInfo) {
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "SoftApCallbackProxy: onInfoChange: softApInfo=" + softApInfo);
+ }
+ mHandler.post(() -> {
+ mCallback.onInfoChanged(softApInfo);
+ });
+ }
}
/**
diff --git a/wifi/tests/src/android/net/wifi/SoftApInfoTest.java b/wifi/tests/src/android/net/wifi/SoftApInfoTest.java
new file mode 100644
index 000000000000..929f3ab88fd8
--- /dev/null
+++ b/wifi/tests/src/android/net/wifi/SoftApInfoTest.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2019 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 android.net.wifi;
+
+import android.os.Parcel;
+
+import static org.junit.Assert.assertEquals;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+
+/**
+ * Unit tests for {@link android.net.wifi.SoftApInfo}.
+ */
+@SmallTest
+public class SoftApInfoTest {
+
+ /**
+ * Verifies copy constructor.
+ */
+ @Test
+ public void testCopyOperator() throws Exception {
+ SoftApInfo info = new SoftApInfo();
+ info.setFrequency(2412);
+ info.setBandwidth(SoftApInfo.CHANNEL_WIDTH_20MHZ);
+
+ SoftApInfo copiedInfo = new SoftApInfo(info);
+
+ assertEquals(info, copiedInfo);
+ assertEquals(info.hashCode(), copiedInfo.hashCode());
+ }
+
+ /**
+ * Verifies parcel serialization/deserialization.
+ */
+ @Test
+ public void testParcelOperation() throws Exception {
+ SoftApInfo info = new SoftApInfo();
+ info.setFrequency(2412);
+ info.setBandwidth(SoftApInfo.CHANNEL_WIDTH_20MHZ);
+
+ Parcel parcelW = Parcel.obtain();
+ info.writeToParcel(parcelW, 0);
+ byte[] bytes = parcelW.marshall();
+ parcelW.recycle();
+
+ Parcel parcelR = Parcel.obtain();
+ parcelR.unmarshall(bytes, 0, bytes.length);
+ parcelR.setDataPosition(0);
+ SoftApInfo fromParcel = SoftApInfo.CREATOR.createFromParcel(parcelR);
+
+ assertEquals(info, fromParcel);
+ assertEquals(info.hashCode(), fromParcel.hashCode());
+ }
+
+}
diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
index d2516a33fead..14e994cf0f08 100644
--- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
@@ -97,6 +97,8 @@ public class WifiManagerTest {
private static final String TEST_PACKAGE_NAME = "TestPackage";
private static final String TEST_COUNTRY_CODE = "US";
private static final String[] TEST_MAC_ADDRESSES = {"da:a1:19:0:0:0"};
+ private static final int TEST_AP_FREQUENCY = 2412;
+ private static final int TEST_AP_BANDWIDTH = SoftApInfo.CHANNEL_WIDTH_20MHZ;
@Mock Context mContext;
@Mock android.net.wifi.IWifiManager mWifiService;
@@ -122,7 +124,6 @@ public class WifiManagerTest {
mApplicationInfo.targetSdkVersion = Build.VERSION_CODES.Q;
when(mContext.getApplicationInfo()).thenReturn(mApplicationInfo);
when(mContext.getOpPackageName()).thenReturn(TEST_PACKAGE_NAME);
-
mWifiManager = new WifiManager(mContext, mWifiService, mLooper.getLooper());
verify(mWifiService).getVerboseLoggingLevel();
}
@@ -776,11 +777,34 @@ public class WifiManagerTest {
verify(mSoftApCallback).onConnectedClientsChanged(testClients);
}
+
+ /*
+ * Verify client-provided callback is being called through callback proxy
+ */
+ @Test
+ public void softApCallbackProxyCallsOnSoftApInfoChanged() throws Exception {
+ SoftApInfo testSoftApInfo = new SoftApInfo();
+ testSoftApInfo.setFrequency(TEST_AP_FREQUENCY);
+ testSoftApInfo.setBandwidth(TEST_AP_BANDWIDTH);
+ ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor =
+ ArgumentCaptor.forClass(ISoftApCallback.Stub.class);
+ mWifiManager.registerSoftApCallback(mSoftApCallback, mHandler);
+ verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(),
+ anyInt());
+
+ callbackCaptor.getValue().onInfoChanged(testSoftApInfo);
+ mLooper.dispatchAll();
+ verify(mSoftApCallback).onInfoChanged(testSoftApInfo);
+ }
+
/*
* Verify client-provided callback is being called through callback proxy on multiple events
*/
@Test
public void softApCallbackProxyCallsOnMultipleUpdates() throws Exception {
+ SoftApInfo testSoftApInfo = new SoftApInfo();
+ testSoftApInfo.setFrequency(TEST_AP_FREQUENCY);
+ testSoftApInfo.setBandwidth(TEST_AP_BANDWIDTH);
ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor =
ArgumentCaptor.forClass(ISoftApCallback.Stub.class);
mWifiManager.registerSoftApCallback(mSoftApCallback, mHandler);
@@ -790,11 +814,13 @@ public class WifiManagerTest {
final List<WifiClient> testClients = new ArrayList();
callbackCaptor.getValue().onStateChanged(WIFI_AP_STATE_ENABLING, 0);
callbackCaptor.getValue().onConnectedClientsChanged(testClients);
+ callbackCaptor.getValue().onInfoChanged(testSoftApInfo);
callbackCaptor.getValue().onStateChanged(WIFI_AP_STATE_FAILED, SAP_START_FAILURE_GENERAL);
mLooper.dispatchAll();
verify(mSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLING, 0);
verify(mSoftApCallback).onConnectedClientsChanged(testClients);
+ verify(mSoftApCallback).onInfoChanged(testSoftApInfo);
verify(mSoftApCallback).onStateChanged(WIFI_AP_STATE_FAILED, SAP_START_FAILURE_GENERAL);
}