Merge "Set recording duration and file size limits" into rvc-dev
diff --git a/api/current.txt b/api/current.txt
index a2f2c06..1bd3aa7 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -31106,6 +31106,7 @@
public class ScanResult implements android.os.Parcelable {
ctor public ScanResult(@NonNull android.net.wifi.ScanResult);
+ ctor public ScanResult();
method public int describeContents();
method @NonNull public java.util.List<android.net.wifi.ScanResult.InformationElement> getInformationElements();
method public int getWifiStandard();
@@ -31377,6 +31378,15 @@
field public static final int LINK_SPEED_UNKNOWN = -1; // 0xffffffff
}
+ public static final class WifiInfo.Builder {
+ ctor public WifiInfo.Builder();
+ method @NonNull public android.net.wifi.WifiInfo build();
+ method @NonNull public android.net.wifi.WifiInfo.Builder setBssid(@NonNull String);
+ method @NonNull public android.net.wifi.WifiInfo.Builder setNetworkId(int);
+ method @NonNull public android.net.wifi.WifiInfo.Builder setRssi(int);
+ method @NonNull public android.net.wifi.WifiInfo.Builder setSsid(@NonNull byte[]);
+ }
+
public class WifiManager {
method @Deprecated public int addNetwork(android.net.wifi.WifiConfiguration);
method @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE) public int addNetworkSuggestions(@NonNull java.util.List<android.net.wifi.WifiNetworkSuggestion>);
@@ -31560,6 +31570,20 @@
public final class WifiNetworkSuggestion implements android.os.Parcelable {
method public int describeContents();
+ method @Nullable public android.net.MacAddress getBssid();
+ method @Nullable public android.net.wifi.WifiEnterpriseConfig getEnterpriseConfig();
+ method @Nullable public String getPassphrase();
+ method @Nullable public android.net.wifi.hotspot2.PasspointConfiguration getPasspointConfig();
+ method @IntRange(from=0) public int getPriority();
+ method @Nullable public String getSsid();
+ method public boolean isAppInteractionRequired();
+ method public boolean isCredentialSharedWithUser();
+ method public boolean isEnhancedOpen();
+ method public boolean isHiddenSsid();
+ method public boolean isInitialAutojoinEnabled();
+ method public boolean isMetered();
+ method public boolean isUntrusted();
+ method public boolean isUserInteractionRequired();
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.WifiNetworkSuggestion> CREATOR;
}
diff --git a/api/system-current.txt b/api/system-current.txt
index 3b95f32..63bb7d1 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -4944,8 +4944,24 @@
package android.media.tv.tuner.dvr {
- public class Dvr implements java.lang.AutoCloseable {
- ctor protected Dvr(int);
+ public class DvrPlayback implements java.lang.AutoCloseable {
+ method public int attachFilter(@NonNull android.media.tv.tuner.filter.Filter);
+ method public void close();
+ method public int configure(@NonNull android.media.tv.tuner.dvr.DvrSettings);
+ method public int detachFilter(@NonNull android.media.tv.tuner.filter.Filter);
+ method public int flush();
+ method public long read(long);
+ method public long read(@NonNull byte[], long, long);
+ method public void setFileDescriptor(@NonNull android.os.ParcelFileDescriptor);
+ method public int start();
+ method public int stop();
+ field public static final int PLAYBACK_STATUS_ALMOST_EMPTY = 2; // 0x2
+ field public static final int PLAYBACK_STATUS_ALMOST_FULL = 4; // 0x4
+ field public static final int PLAYBACK_STATUS_EMPTY = 1; // 0x1
+ field public static final int PLAYBACK_STATUS_FULL = 8; // 0x8
+ }
+
+ public class DvrRecorder implements java.lang.AutoCloseable {
method public int attachFilter(@NonNull android.media.tv.tuner.filter.Filter);
method public void close();
method public int configure(@NonNull android.media.tv.tuner.dvr.DvrSettings);
@@ -4954,20 +4970,6 @@
method public void setFileDescriptor(@NonNull android.os.ParcelFileDescriptor);
method public int start();
method public int stop();
- field public static final int TYPE_PLAYBACK = 1; // 0x1
- field public static final int TYPE_RECORD = 0; // 0x0
- }
-
- public class DvrPlayback extends android.media.tv.tuner.dvr.Dvr {
- method public long read(long);
- method public long read(@NonNull byte[], long, long);
- field public static final int PLAYBACK_STATUS_ALMOST_EMPTY = 2; // 0x2
- field public static final int PLAYBACK_STATUS_ALMOST_FULL = 4; // 0x4
- field public static final int PLAYBACK_STATUS_EMPTY = 1; // 0x1
- field public static final int PLAYBACK_STATUS_FULL = 8; // 0x8
- }
-
- public class DvrRecorder extends android.media.tv.tuner.dvr.Dvr {
method public long write(long);
method public long write(@NonNull byte[], long, long);
}
@@ -7169,7 +7171,6 @@
}
public class ScanResult implements android.os.Parcelable {
- ctor public ScanResult();
field public static final int CIPHER_CCMP = 3; // 0x3
field public static final int CIPHER_GCMP_256 = 4; // 0x4
field public static final int CIPHER_NONE = 0; // 0x0
@@ -7314,8 +7315,8 @@
method @Deprecated public int getDisableReasonCounter(int);
method @Deprecated public long getDisableTime();
method @Deprecated public static int getMaxNetworkSelectionDisableReason();
- method @Deprecated @Nullable public static String getNetworkDisableReasonString(int);
method @Deprecated public int getNetworkSelectionDisableReason();
+ method @Deprecated @Nullable public static String getNetworkSelectionDisableReasonString(int);
method @Deprecated public int getNetworkSelectionStatus();
method @Deprecated @NonNull public String getNetworkStatusString();
method @Deprecated public boolean hasEverConnected();
@@ -7377,15 +7378,6 @@
field public static final int INVALID_RSSI = -127; // 0xffffff81
}
- public static final class WifiInfo.Builder {
- ctor public WifiInfo.Builder();
- method @NonNull public android.net.wifi.WifiInfo build();
- method @NonNull public android.net.wifi.WifiInfo.Builder setBssid(@NonNull String);
- method @NonNull public android.net.wifi.WifiInfo.Builder setNetworkId(int);
- method @NonNull public android.net.wifi.WifiInfo.Builder setRssi(int);
- method @NonNull public android.net.wifi.WifiInfo.Builder setSsid(@NonNull byte[]);
- }
-
public class WifiManager {
method @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) public void addOnWifiUsabilityStatsListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.OnWifiUsabilityStatsListener);
method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void allowAutojoin(int, boolean);
@@ -7528,7 +7520,7 @@
}
public static interface WifiManager.ScoreChangeCallback {
- method public void onScoreChange(int, @NonNull android.net.NetworkScore);
+ method public void onScoreChange(int, int);
method public void onTriggerUpdateOfWifiUsabilityStats(int);
}
@@ -7554,6 +7546,52 @@
method public void stop(int);
}
+ public final class WifiMigration {
+ method @Nullable public static android.net.wifi.WifiMigration.ConfigStoreMigrationData loadFromConfigStore();
+ method @NonNull public static android.net.wifi.WifiMigration.SettingsMigrationData loadFromSettings(@NonNull android.content.Context);
+ method public static void removeConfigStore();
+ }
+
+ public static final class WifiMigration.ConfigStoreMigrationData implements android.os.Parcelable {
+ method public int describeContents();
+ method @Nullable public java.util.List<android.net.wifi.WifiConfiguration> getUserSavedNetworkConfigurations();
+ method @Nullable public android.net.wifi.SoftApConfiguration getUserSoftApConfiguration();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.WifiMigration.ConfigStoreMigrationData> CREATOR;
+ }
+
+ public static final class WifiMigration.ConfigStoreMigrationData.Builder {
+ ctor public WifiMigration.ConfigStoreMigrationData.Builder();
+ method @NonNull public android.net.wifi.WifiMigration.ConfigStoreMigrationData build();
+ method @NonNull public android.net.wifi.WifiMigration.ConfigStoreMigrationData.Builder setUserSavedNetworkConfigurations(@NonNull java.util.List<android.net.wifi.WifiConfiguration>);
+ method @NonNull public android.net.wifi.WifiMigration.ConfigStoreMigrationData.Builder setUserSoftApConfiguration(@NonNull android.net.wifi.SoftApConfiguration);
+ }
+
+ public static final class WifiMigration.SettingsMigrationData implements android.os.Parcelable {
+ method public int describeContents();
+ method @Nullable public String getP2pDeviceName();
+ method public boolean isP2pFactoryResetPending();
+ method public boolean isScanAlwaysAvailable();
+ method public boolean isScanThrottleEnabled();
+ method public boolean isSoftApTimeoutEnabled();
+ method public boolean isVerboseLoggingEnabled();
+ method public boolean isWakeUpEnabled();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.WifiMigration.SettingsMigrationData> CREATOR;
+ }
+
+ public static final class WifiMigration.SettingsMigrationData.Builder {
+ ctor public WifiMigration.SettingsMigrationData.Builder();
+ method @NonNull public android.net.wifi.WifiMigration.SettingsMigrationData build();
+ method @NonNull public android.net.wifi.WifiMigration.SettingsMigrationData.Builder setP2pDeviceName(@Nullable String);
+ method @NonNull public android.net.wifi.WifiMigration.SettingsMigrationData.Builder setP2pFactoryResetPending(boolean);
+ method @NonNull public android.net.wifi.WifiMigration.SettingsMigrationData.Builder setScanAlwaysAvailable(boolean);
+ method @NonNull public android.net.wifi.WifiMigration.SettingsMigrationData.Builder setScanThrottleEnabled(boolean);
+ method @NonNull public android.net.wifi.WifiMigration.SettingsMigrationData.Builder setSoftApTimeoutEnabled(boolean);
+ method @NonNull public android.net.wifi.WifiMigration.SettingsMigrationData.Builder setVerboseLoggingEnabled(boolean);
+ method @NonNull public android.net.wifi.WifiMigration.SettingsMigrationData.Builder setWakeUpEnabled(boolean);
+ }
+
public class WifiNetworkConnectionStatistics implements android.os.Parcelable {
ctor public WifiNetworkConnectionStatistics(int, int);
ctor public WifiNetworkConnectionStatistics();
@@ -7570,7 +7608,6 @@
}
public final class WifiNetworkSuggestion implements android.os.Parcelable {
- method @Nullable public android.net.wifi.hotspot2.PasspointConfiguration getPasspointConfiguration();
method @NonNull public android.net.wifi.WifiConfiguration getWifiConfiguration();
}
@@ -7578,51 +7615,6 @@
method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_CARRIER_PROVISIONING) public android.net.wifi.WifiNetworkSuggestion.Builder setCarrierId(int);
}
- public final class WifiOemMigrationHook {
- method @Nullable public static android.net.wifi.WifiOemMigrationHook.ConfigStoreMigrationData loadFromConfigStore();
- method @NonNull public static android.net.wifi.WifiOemMigrationHook.SettingsMigrationData loadFromSettings(@NonNull android.content.Context);
- }
-
- public static final class WifiOemMigrationHook.ConfigStoreMigrationData implements android.os.Parcelable {
- method public int describeContents();
- method @Nullable public java.util.List<android.net.wifi.WifiConfiguration> getUserSavedNetworkConfigurations();
- method @Nullable public android.net.wifi.SoftApConfiguration getUserSoftApConfiguration();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.WifiOemMigrationHook.ConfigStoreMigrationData> CREATOR;
- }
-
- public static final class WifiOemMigrationHook.ConfigStoreMigrationData.Builder {
- ctor public WifiOemMigrationHook.ConfigStoreMigrationData.Builder();
- method @NonNull public android.net.wifi.WifiOemMigrationHook.ConfigStoreMigrationData build();
- method @NonNull public android.net.wifi.WifiOemMigrationHook.ConfigStoreMigrationData.Builder setUserSavedNetworkConfigurations(@NonNull java.util.List<android.net.wifi.WifiConfiguration>);
- method @NonNull public android.net.wifi.WifiOemMigrationHook.ConfigStoreMigrationData.Builder setUserSoftApConfiguration(@NonNull android.net.wifi.SoftApConfiguration);
- }
-
- public static final class WifiOemMigrationHook.SettingsMigrationData implements android.os.Parcelable {
- method public int describeContents();
- method @Nullable public String getP2pDeviceName();
- method public boolean isP2pFactoryResetPending();
- method public boolean isScanAlwaysAvailable();
- method public boolean isScanThrottleEnabled();
- method public boolean isSoftApTimeoutEnabled();
- method public boolean isVerboseLoggingEnabled();
- method public boolean isWakeUpEnabled();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.WifiOemMigrationHook.SettingsMigrationData> CREATOR;
- }
-
- public static final class WifiOemMigrationHook.SettingsMigrationData.Builder {
- ctor public WifiOemMigrationHook.SettingsMigrationData.Builder();
- method @NonNull public android.net.wifi.WifiOemMigrationHook.SettingsMigrationData build();
- method @NonNull public android.net.wifi.WifiOemMigrationHook.SettingsMigrationData.Builder setP2pDeviceName(@Nullable String);
- method @NonNull public android.net.wifi.WifiOemMigrationHook.SettingsMigrationData.Builder setP2pFactoryResetPending(boolean);
- method @NonNull public android.net.wifi.WifiOemMigrationHook.SettingsMigrationData.Builder setScanAlwaysAvailable(boolean);
- method @NonNull public android.net.wifi.WifiOemMigrationHook.SettingsMigrationData.Builder setScanThrottleEnabled(boolean);
- method @NonNull public android.net.wifi.WifiOemMigrationHook.SettingsMigrationData.Builder setSoftApTimeoutEnabled(boolean);
- method @NonNull public android.net.wifi.WifiOemMigrationHook.SettingsMigrationData.Builder setVerboseLoggingEnabled(boolean);
- method @NonNull public android.net.wifi.WifiOemMigrationHook.SettingsMigrationData.Builder setWakeUpEnabled(boolean);
- }
-
public class WifiScanner {
method @Deprecated public void configureWifiChange(int, int, int, int, int, android.net.wifi.WifiScanner.BssidInfo[]);
method @Deprecated public void configureWifiChange(android.net.wifi.WifiScanner.WifiChangeSettings);
@@ -11795,7 +11787,6 @@
method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setAllowedCarriers(int, java.util.List<android.service.carrier.CarrierIdentifier>);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setAllowedNetworkTypes(long);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setAlwaysAllowMmsData(boolean);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setAlwaysReportSignalStrength(boolean);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setCallForwarding(@NonNull android.telephony.CallForwardingInfo);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setCallWaitingStatus(boolean);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setCarrierDataEnabled(boolean);
@@ -11810,7 +11801,6 @@
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setMultiSimCarrierRestriction(boolean);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setNetworkSelectionModeManual(@NonNull String, int, boolean);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setOpportunisticNetworkState(boolean);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setPolicyDataEnabled(boolean);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setPreferredNetworkTypeBitmask(long);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setRadio(boolean);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setRadioEnabled(boolean);
diff --git a/cmds/idmap2/idmap2/CreateMultiple.cpp b/cmds/idmap2/idmap2/CreateMultiple.cpp
index 0b0541f..d4e888f 100644
--- a/cmds/idmap2/idmap2/CreateMultiple.cpp
+++ b/cmds/idmap2/idmap2/CreateMultiple.cpp
@@ -31,6 +31,7 @@
#include "idmap2/Idmap.h"
#include "idmap2/Policies.h"
#include "idmap2/SysTrace.h"
+#include "Commands.h"
using android::ApkAssets;
using android::base::StringPrintf;
@@ -105,32 +106,34 @@
continue;
}
- const std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path);
- if (!overlay_apk) {
- LOG(WARNING) << "failed to load apk " << overlay_apk_path.c_str();
- continue;
- }
+ if (!Verify(std::vector<std::string>({"--idmap-path", idmap_path}))) {
+ const std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path);
+ if (!overlay_apk) {
+ LOG(WARNING) << "failed to load apk " << overlay_apk_path.c_str();
+ continue;
+ }
- const auto idmap =
- Idmap::FromApkAssets(*target_apk, *overlay_apk, fulfilled_policies, !ignore_overlayable);
- if (!idmap) {
- LOG(WARNING) << "failed to create idmap";
- continue;
- }
+ const auto idmap =
+ Idmap::FromApkAssets(*target_apk, *overlay_apk, fulfilled_policies, !ignore_overlayable);
+ if (!idmap) {
+ LOG(WARNING) << "failed to create idmap";
+ continue;
+ }
- umask(kIdmapFilePermissionMask);
- std::ofstream fout(idmap_path);
- if (fout.fail()) {
- LOG(WARNING) << "failed to open idmap path " << idmap_path.c_str();
- continue;
- }
+ umask(kIdmapFilePermissionMask);
+ std::ofstream fout(idmap_path);
+ if (fout.fail()) {
+ LOG(WARNING) << "failed to open idmap path " << idmap_path.c_str();
+ continue;
+ }
- BinaryStreamVisitor visitor(fout);
- (*idmap)->accept(&visitor);
- fout.close();
- if (fout.fail()) {
- LOG(WARNING) << "failed to write to idmap path %s" << idmap_path.c_str();
- continue;
+ BinaryStreamVisitor visitor(fout);
+ (*idmap)->accept(&visitor);
+ fout.close();
+ if (fout.fail()) {
+ LOG(WARNING) << "failed to write to idmap path %s" << idmap_path.c_str();
+ continue;
+ }
}
idmap_paths.emplace_back(idmap_path);
diff --git a/core/java/android/app/ActivityTaskManager.java b/core/java/android/app/ActivityTaskManager.java
index d48b35b..fb315ad 100644
--- a/core/java/android/app/ActivityTaskManager.java
+++ b/core/java/android/app/ActivityTaskManager.java
@@ -215,8 +215,7 @@
public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode, boolean toTop,
boolean animate, Rect initialBounds, boolean showRecents) throws SecurityException {
try {
- return getService().setTaskWindowingModeSplitScreenPrimary(taskId, createMode, toTop,
- animate, initialBounds, showRecents);
+ return getService().setTaskWindowingModeSplitScreenPrimary(taskId, toTop);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 463c8c9..6f0611e 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -528,29 +528,6 @@
boolean unlockUser(int userid, in byte[] token, in byte[] secret,
in IProgressListener listener);
void killPackageDependents(in String packageName, int userId);
- /**
- * Resizes the docked stack, and all other stacks as the result of the dock stack bounds change.
- *
- * @param dockedBounds The bounds for the docked stack.
- * @param tempDockedTaskBounds The temporary bounds for the tasks in the docked stack, which
- * might be different from the stack bounds to allow more
- * flexibility while resizing, or {@code null} if they should be the
- * same as the stack bounds.
- * @param tempDockedTaskInsetBounds The temporary bounds for the tasks to calculate the insets.
- * When resizing, we usually "freeze" the layout of a task. To
- * achieve that, we also need to "freeze" the insets, which
- * gets achieved by changing task bounds but not bounds used
- * to calculate the insets in this transient state
- * @param tempOtherTaskBounds The temporary bounds for the tasks in all other stacks, or
- * {@code null} if they should be the same as the stack bounds.
- * @param tempOtherTaskInsetBounds Like {@code tempDockedTaskInsetBounds}, but for the other
- * stacks.
- * @throws RemoteException
- */
- @UnsupportedAppUsage
- void resizeDockedStack(in Rect dockedBounds, in Rect tempDockedTaskBounds,
- in Rect tempDockedTaskInsetBounds,
- in Rect tempOtherTaskBounds, in Rect tempOtherTaskInsetBounds);
@UnsupportedAppUsage
void removeStack(int stackId);
void makePackageIdle(String packageName, int userId);
diff --git a/core/java/android/app/IActivityTaskManager.aidl b/core/java/android/app/IActivityTaskManager.aidl
index 266a06a..7c89263 100644
--- a/core/java/android/app/IActivityTaskManager.aidl
+++ b/core/java/android/app/IActivityTaskManager.aidl
@@ -244,8 +244,7 @@
*/
boolean setTaskWindowingMode(int taskId, int windowingMode, boolean toTop);
void moveTaskToStack(int taskId, int stackId, boolean toTop);
- boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode, boolean toTop,
- boolean animate, in Rect initialBounds, boolean showRecents);
+ boolean setTaskWindowingModeSplitScreenPrimary(int taskId, boolean toTop);
/**
* Removes stacks in the input windowing modes from the system if they are of activity type
* ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
diff --git a/core/java/android/debug/AdbManagerInternal.java b/core/java/android/debug/AdbManagerInternal.java
index 0bd9f19..d730129 100644
--- a/core/java/android/debug/AdbManagerInternal.java
+++ b/core/java/android/debug/AdbManagerInternal.java
@@ -53,4 +53,14 @@
* Returns the file that contains all of the ADB keys and their last used time.
*/
public abstract File getAdbTempKeysFile();
+
+ /**
+ * Starts adbd for a transport.
+ */
+ public abstract void startAdbdForTransport(byte transportType);
+
+ /**
+ * Stops adbd for a transport.
+ */
+ public abstract void stopAdbdForTransport(byte transportType);
}
diff --git a/core/java/android/service/autofill/InlineSuggestionRenderService.java b/core/java/android/service/autofill/InlineSuggestionRenderService.java
index 17e0456..fcdefac 100644
--- a/core/java/android/service/autofill/InlineSuggestionRenderService.java
+++ b/core/java/android/service/autofill/InlineSuggestionRenderService.java
@@ -23,16 +23,13 @@
import android.annotation.TestApi;
import android.app.Service;
import android.app.slice.Slice;
-import android.content.Context;
import android.content.Intent;
import android.graphics.PixelFormat;
-import android.hardware.display.DisplayManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException;
-import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.SurfaceControl;
@@ -76,35 +73,41 @@
return;
}
- final DisplayManager displayManager = getSystemService(DisplayManager.class);
- final Display targetDisplay = displayManager.getDisplay(displayId);
- if (targetDisplay == null) {
- sendResult(callback, /*surface*/ null);
- return;
- }
- final Context displayContext = createDisplayContext(targetDisplay);
-
- final SurfaceControlViewHost host = new SurfaceControlViewHost(displayContext,
- displayContext.getDisplay(), hostInputToken);
- final SurfaceControl surface = host.getSurfacePackage().getSurfaceControl();
-
- final View suggestionView = onRenderSuggestion(presentation, width, height);
-
- final InlineSuggestionRoot suggestionRoot = new InlineSuggestionRoot(this, callback);
- suggestionRoot.addView(suggestionView);
- suggestionRoot.setOnClickListener((v) -> {
- try {
- callback.onAutofill();
- } catch (RemoteException e) {
- Log.w(TAG, "RemoteException calling onAutofill()");
+ // When we create the UI it should be for the IME display
+ updateDisplay(displayId);
+ try {
+ final View suggestionView = onRenderSuggestion(presentation, width, height);
+ if (suggestionView == null) {
+ try {
+ callback.onError();
+ } catch (RemoteException e) {
+ Log.w(TAG, "Null suggestion view returned by renderer");
+ }
+ return;
}
- });
- WindowManager.LayoutParams lp =
- new WindowManager.LayoutParams(width, height,
- WindowManager.LayoutParams.TYPE_APPLICATION, 0, PixelFormat.TRANSPARENT);
- host.addView(suggestionRoot, lp);
- sendResult(callback, surface);
+ final InlineSuggestionRoot suggestionRoot = new InlineSuggestionRoot(this, callback);
+ suggestionRoot.addView(suggestionView);
+ WindowManager.LayoutParams lp =
+ new WindowManager.LayoutParams(width, height,
+ WindowManager.LayoutParams.TYPE_APPLICATION, 0,
+ PixelFormat.TRANSPARENT);
+
+ final SurfaceControlViewHost host = new SurfaceControlViewHost(this, getDisplay(),
+ hostInputToken);
+ host.addView(suggestionRoot, lp);
+ suggestionRoot.setOnClickListener((v) -> {
+ try {
+ callback.onAutofill();
+ } catch (RemoteException e) {
+ Log.w(TAG, "RemoteException calling onAutofill()");
+ }
+ });
+
+ sendResult(callback, host.getSurfacePackage().getSurfaceControl());
+ } finally {
+ updateDisplay(Display.DEFAULT_DISPLAY);
+ }
}
private void sendResult(@NonNull IInlineSuggestionUiCallback callback,
diff --git a/core/java/android/service/controls/Control.java b/core/java/android/service/controls/Control.java
index 2d1d0ed..0cffe71 100644
--- a/core/java/android/service/controls/Control.java
+++ b/core/java/android/service/controls/Control.java
@@ -394,6 +394,11 @@
return this;
}
+ /**
+ * @param deviceType the device type for the {@link Control}. Setting an invalid value not
+ * in {@link DeviceTypes} will set it to {@link DeviceTypes#TYPE_UNKNOWN}.
+ * @return {@code this}
+ */
@NonNull
public StatelessBuilder setDeviceType(@DeviceTypes.DeviceType int deviceType) {
if (!DeviceTypes.validDeviceType(deviceType)) {
@@ -416,6 +421,10 @@
return this;
}
+ /**
+ * @param subtitle the user facing subtitle for the {@link Control}
+ * @return {@code this}
+ */
@NonNull
public StatelessBuilder setSubtitle(@NonNull CharSequence subtitle) {
Preconditions.checkNotNull(subtitle);
@@ -423,12 +432,22 @@
return this;
}
+ /**
+ * @param structure the user facing name of the structure for the {@link Control}.
+ * {@code null} indicates that it's not associated with any structure.
+ * @return {@code this}
+ */
@NonNull
public StatelessBuilder setStructure(@Nullable CharSequence structure) {
mStructure = structure;
return this;
}
+ /**
+ * @param zone the user facing name of the zone for the {@link Control}. {@code null}
+ * indicates that it's not associated with any zone.
+ * @return {@code this}
+ */
@NonNull
public StatelessBuilder setZone(@Nullable CharSequence zone) {
mZone = zone;
@@ -446,12 +465,20 @@
return this;
}
+ /**
+ * @param customIcon an {@link Icon} to override the one determined by the device type.
+ * @return {@code this}
+ */
@NonNull
public StatelessBuilder setCustomIcon(@Nullable Icon customIcon) {
mCustomIcon = customIcon;
return this;
}
+ /**
+ * @param customColor a list of colors to override the ones determined by the device type.
+ * @return {@code this}
+ */
@NonNull
public StatelessBuilder setCustomColor(@Nullable ColorStateList customColor) {
mCustomColor = customColor;
@@ -459,7 +486,7 @@
}
/**
- * Build a {@link Control}
+ * Build a stateless {@link Control}
* @return a valid {@link Control}
*/
@NonNull
@@ -482,7 +509,7 @@
/**
* Builder class for {@link Control}.
*
- * This class facilitates the creation of {@link Control}.
+ * This class facilitates the creation of {@link Control} with an associated state.
* It provides the following defaults for non-optional parameters:
* <ul>
* <li> Device type: {@link DeviceTypes#TYPE_UNKNOWN}
@@ -551,6 +578,11 @@
return this;
}
+ /**
+ * @param deviceType the device type for the {@link Control}. Setting an invalid value not
+ * in {@link DeviceTypes} will set it to {@link DeviceTypes#TYPE_UNKNOWN}.
+ * @return {@code this}
+ */
@NonNull
public StatefulBuilder setDeviceType(@DeviceTypes.DeviceType int deviceType) {
if (!DeviceTypes.validDeviceType(deviceType)) {
@@ -573,6 +605,10 @@
return this;
}
+ /**
+ * @param subtitle the user facing subtitle for the {@link Control}
+ * @return {@code this}
+ */
@NonNull
public StatefulBuilder setSubtitle(@NonNull CharSequence subtitle) {
Preconditions.checkNotNull(subtitle);
@@ -580,12 +616,22 @@
return this;
}
+ /**
+ * @param structure the user facing name of the structure for the {@link Control}.
+ * {@code null} indicates that it's not associated with any structure.
+ * @return {@code this}
+ */
@NonNull
public StatefulBuilder setStructure(@Nullable CharSequence structure) {
mStructure = structure;
return this;
}
+ /**
+ * @param zone the user facing name of the zone for the {@link Control}. {@code null}
+ * indicates that it's not associated with any zone.
+ * @return {@code this}
+ */
@NonNull
public StatefulBuilder setZone(@Nullable CharSequence zone) {
mZone = zone;
@@ -603,18 +649,31 @@
return this;
}
+ /**
+ * @param customIcon an {@link Icon} to override the one determined by the device type.
+ * @return {@code this}
+ */
@NonNull
public StatefulBuilder setCustomIcon(@Nullable Icon customIcon) {
mCustomIcon = customIcon;
return this;
}
+ /**
+ * @param customColor a list of colors to override the ones determined by the device type.
+ * @return {@code this}
+ */
@NonNull
public StatefulBuilder setCustomColor(@Nullable ColorStateList customColor) {
mCustomColor = customColor;
return this;
}
+ /**
+ * @param status the status of the {@link Control}. Setting an invalid value not in
+ * {@link Control} will set it to {@link Control#STATUS_UNKNOWN}.
+ * @return {@code this}
+ */
@NonNull
public StatefulBuilder setStatus(@Status int status) {
if (status < 0 || status >= NUM_STATUS) {
@@ -626,6 +685,10 @@
return this;
}
+ /**
+ * @param controlTemplate a template for the {@link Control}
+ * @return {@code this}
+ */
@NonNull
public StatefulBuilder setControlTemplate(@NonNull ControlTemplate controlTemplate) {
Preconditions.checkNotNull(controlTemplate);
@@ -633,6 +696,10 @@
return this;
}
+ /**
+ * @param statusText a user facing text representing the status of the {@link Control}.
+ * @return {@code this}
+ */
@NonNull
public StatefulBuilder setStatusText(@NonNull CharSequence statusText) {
Preconditions.checkNotNull(statusText);
@@ -640,6 +707,10 @@
return this;
}
+ /**
+ * Build a stateless {@link Control}
+ * @return a valid {@link Control}
+ */
@NonNull
public Control build() {
return new Control(mControlId,
diff --git a/core/java/android/service/controls/DeviceTypes.java b/core/java/android/service/controls/DeviceTypes.java
index 8dbb9cf..6594d2c 100644
--- a/core/java/android/service/controls/DeviceTypes.java
+++ b/core/java/android/service/controls/DeviceTypes.java
@@ -21,6 +21,9 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+/**
+ * Device types for {@link Control}.
+ */
public class DeviceTypes {
// Update this when adding new concrete types. Does not count TYPE_UNKNOWN
diff --git a/core/java/android/service/controls/actions/BooleanAction.java b/core/java/android/service/controls/actions/BooleanAction.java
index 0259335..b794ead 100644
--- a/core/java/android/service/controls/actions/BooleanAction.java
+++ b/core/java/android/service/controls/actions/BooleanAction.java
@@ -19,10 +19,15 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Bundle;
+import android.service.controls.Control;
+import android.service.controls.templates.ToggleRangeTemplate;
import android.service.controls.templates.ToggleTemplate;
/**
- * Action sent by a {@link ToggleTemplate}
+ * Action sent by user toggling a {@link Control} between checked/unchecked.
+ *
+ * This action is available when the {@link Control} was constructed with either a
+ * {@link ToggleTemplate} or a {@link ToggleRangeTemplate}.
*/
public final class BooleanAction extends ControlAction {
@@ -40,8 +45,8 @@
}
/**
- * @param templateId the identifier of the {@link ToggleTemplate} that originated this action.
- * @param newState new value for the state displayed by the {@link ToggleTemplate}.
+ * @param templateId the identifier of the template that originated this action.
+ * @param newState new value for the state displayed by the template.
* @param challengeValue a value sent by the user along with the action to authenticate. {@code}
* null is sent when no authentication is needed or has not been
* requested.
@@ -64,8 +69,7 @@
/**
* The new state set for the button in the corresponding {@link ToggleTemplate}.
*
- * @return {@code true} if the button was toggled from an {@code off} state to an {@code on}
- * state.
+ * @return {@code true} if the button was toggled from unchecked to checked.
*/
public boolean getNewState() {
return mNewState;
diff --git a/core/java/android/service/controls/actions/CommandAction.java b/core/java/android/service/controls/actions/CommandAction.java
index 84d6080..a560fa4 100644
--- a/core/java/android/service/controls/actions/CommandAction.java
+++ b/core/java/android/service/controls/actions/CommandAction.java
@@ -19,15 +19,32 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Bundle;
+import android.service.controls.Control;
+import android.service.controls.templates.StatelessTemplate;
+/**
+ * A simple {@link ControlAction} indicating that the user has interacted with a {@link Control}
+ * created using a {@link StatelessTemplate}.
+ */
public final class CommandAction extends ControlAction {
private static final @ActionType int TYPE = TYPE_COMMAND;
+ /**
+ * @param templateId the identifier of the {@link StatelessTemplate} that originated this
+ * action.
+ * @param challengeValue a value sent by the user along with the action to authenticate. {@code}
+ * null is sent when no authentication is needed or has not been
+ * requested.
+ */
public CommandAction(@NonNull String templateId, @Nullable String challengeValue) {
super(templateId, challengeValue);
}
+ /**
+ * @param templateId the identifier of the {@link StatelessTemplate} that originated this
+ * action.
+ */
public CommandAction(@NonNull String templateId) {
this(templateId, null);
}
@@ -40,6 +57,9 @@
super(b);
}
+ /**
+ * @return {@link ControlAction#TYPE_COMMAND}
+ */
@Override
public int getActionType() {
return TYPE;
diff --git a/core/java/android/service/controls/actions/ControlAction.java b/core/java/android/service/controls/actions/ControlAction.java
index 4141da8..45e63d7 100644
--- a/core/java/android/service/controls/actions/ControlAction.java
+++ b/core/java/android/service/controls/actions/ControlAction.java
@@ -21,6 +21,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Bundle;
+import android.service.controls.Control;
import android.service.controls.IControlsActionCallback;
import android.service.controls.templates.ControlTemplate;
import android.util.Log;
@@ -31,7 +32,7 @@
import java.lang.annotation.RetentionPolicy;
/**
- * An abstract action that is executed from a {@link ControlTemplate}.
+ * An abstract action indicating a user interaction with a {@link Control}.
*
* The action may have a value to authenticate the input, when the provider has requested it to
* complete the action.
@@ -58,6 +59,9 @@
})
public @interface ActionType {};
+ /**
+ * Object returned when there is an unparcelling error.
+ */
public static final @NonNull ControlAction ERROR_ACTION = new ControlAction() {
@Override
public int getActionType() {
@@ -65,6 +69,9 @@
}
};
+ /**
+ * The identifier of {@link #ERROR_ACTION}
+ */
public static final @ActionType int TYPE_ERROR = -1;
/**
@@ -77,10 +84,19 @@
*/
public static final @ActionType int TYPE_FLOAT = 2;
+ /**
+ * The identifier of {@link MultiFloatAction}.
+ */
public static final @ActionType int TYPE_MULTI_FLOAT = 3;
+ /**
+ * The identifier of {@link ModeAction}.
+ */
public static final @ActionType int TYPE_MODE = 4;
+ /**
+ * The identifier of {@link CommandAction}.
+ */
public static final @ActionType int TYPE_COMMAND = 5;
diff --git a/core/java/android/service/controls/actions/ModeAction.java b/core/java/android/service/controls/actions/ModeAction.java
index ca40974d..c0e24ad 100644
--- a/core/java/android/service/controls/actions/ModeAction.java
+++ b/core/java/android/service/controls/actions/ModeAction.java
@@ -19,7 +19,15 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Bundle;
+import android.service.controls.Control;
+import android.service.controls.templates.TemperatureControlTemplate;
+/**
+ * Action sent by the user to indicate a change of mode.
+ *
+ * This action is available when the {@link Control} was created with a
+ * {@link TemperatureControlTemplate}.
+ */
public final class ModeAction extends ControlAction {
private static final @ActionType int TYPE = TYPE_MODE;
@@ -27,16 +35,32 @@
private final int mNewMode;
+ /**
+ * @return {@link ControlAction#TYPE_MODE}.
+ */
@Override
public int getActionType() {
return TYPE;
}
+ /**
+ * @param templateId the identifier of the {@link TemperatureControlTemplate} that originated
+ * this action.
+ * @param newMode new value for the mode.
+ * @param challengeValue a value sent by the user along with the action to authenticate. {@code}
+ * null is sent when no authentication is needed or has not been
+ * requested.
+ */
public ModeAction(@NonNull String templateId, int newMode, @Nullable String challengeValue) {
super(templateId, challengeValue);
mNewMode = newMode;
}
+ /**
+ * @param templateId the identifier of the {@link TemperatureControlTemplate} that originated
+ * this action.
+ * @param newMode new value for the mode.
+ */
public ModeAction(@NonNull String templateId, int newMode) {
this(templateId, newMode, null);
}
diff --git a/core/java/android/service/controls/templates/ControlTemplate.java b/core/java/android/service/controls/templates/ControlTemplate.java
index a5156e3..30efd80 100644
--- a/core/java/android/service/controls/templates/ControlTemplate.java
+++ b/core/java/android/service/controls/templates/ControlTemplate.java
@@ -57,6 +57,9 @@
}
};
+ /**
+ * Object returned when there is an unparcelling error.
+ */
public static final @NonNull ControlTemplate ERROR_TEMPLATE = new ControlTemplate("") {
@Override
public int getTemplateType() {
@@ -80,6 +83,9 @@
})
public @interface TemplateType {}
+ /**
+ * Type identifier of {@link #ERROR_TEMPLATE}.
+ */
public static final @TemplateType int TYPE_ERROR = -1;
/**
@@ -102,10 +108,19 @@
*/
public static final @TemplateType int TYPE_THUMBNAIL = 3;
+ /**
+ * Type identifier of {@link ToggleRangeTemplate}.
+ */
public static final @TemplateType int TYPE_TOGGLE_RANGE = 6;
+ /**
+ * Type identifier of {@link TemperatureControlTemplate}.
+ */
public static final @TemplateType int TYPE_TEMPERATURE = 7;
+ /**
+ * Type identifier of {@link StatelessTemplate}.
+ */
public static final @TemplateType int TYPE_STATELESS = 8;
private @NonNull final String mTemplateId;
diff --git a/core/java/android/service/controls/templates/RangeTemplate.java b/core/java/android/service/controls/templates/RangeTemplate.java
index fe0d167..0d977d3 100644
--- a/core/java/android/service/controls/templates/RangeTemplate.java
+++ b/core/java/android/service/controls/templates/RangeTemplate.java
@@ -19,7 +19,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Bundle;
-import android.os.Parcel;
import android.service.controls.Control;
import android.service.controls.actions.FloatAction;
@@ -85,7 +84,7 @@
}
/**
- * Construct a new {@link RangeTemplate} from a {@link Parcel}.
+ * Construct a new {@link RangeTemplate} from a {@link Bundle}.
*
* @throws IllegalArgumentException if the parameters passed do not make a valid range
* @see RangeTemplate#RangeTemplate(String, float, float, float, float, CharSequence)
diff --git a/core/java/android/service/controls/templates/StatelessTemplate.java b/core/java/android/service/controls/templates/StatelessTemplate.java
index 3f98bea..c052412 100644
--- a/core/java/android/service/controls/templates/StatelessTemplate.java
+++ b/core/java/android/service/controls/templates/StatelessTemplate.java
@@ -18,22 +18,36 @@
import android.annotation.NonNull;
import android.os.Bundle;
+import android.service.controls.Control;
+import android.service.controls.actions.CommandAction;
+/**
+ * A template for a {@link Control} which has no state.
+ *
+ * @see CommandAction
+ */
public final class StatelessTemplate extends ControlTemplate {
+ /**
+ * @return {@link ControlTemplate#TYPE_STATELESS}
+ */
@Override
public int getTemplateType() {
return TYPE_STATELESS;
}
/**
- * @param b
+ * Construct a new {@link StatelessTemplate} from a {@link Bundle}
* @hide
*/
StatelessTemplate(@NonNull Bundle b) {
super(b);
}
+ /**
+ * Construct a new {@link StatelessTemplate}
+ * @param templateId the identifier for this template
+ */
public StatelessTemplate(@NonNull String templateId) {
super(templateId);
}
diff --git a/core/java/android/service/controls/templates/TemperatureControlTemplate.java b/core/java/android/service/controls/templates/TemperatureControlTemplate.java
index 9d8dca62..0818c7e 100644
--- a/core/java/android/service/controls/templates/TemperatureControlTemplate.java
+++ b/core/java/android/service/controls/templates/TemperatureControlTemplate.java
@@ -19,6 +19,7 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.os.Bundle;
+import android.service.controls.Control;
import android.util.Log;
import com.android.internal.util.Preconditions;
@@ -26,6 +27,13 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+/**
+ * A template for a temperature related {@link Control} that supports multiple modes.
+ *
+ * Both the current mode and the active mode for the control can be specified. The combination of
+ * the {@link Control#getDeviceType} and the current and active mode will determine colors and
+ * transitions for the UI element.
+ */
public final class TemperatureControlTemplate extends ControlTemplate {
private static final String TAG = "ThermostatTemplate";
@@ -51,6 +59,7 @@
public @interface Mode {}
private static final int NUM_MODES = 6;
+
public static final @Mode int MODE_UNKNOWN = 0;
public static final @Mode int MODE_OFF = 1;
@@ -102,6 +111,18 @@
private final @Mode int mCurrentActiveMode;
private final @ModeFlag int mModes;
+ /**
+ * Construct a new {@link TemperatureControlTemplate}.
+ *
+ * The current and active mode have to be among the ones supported by the flags.
+ *
+ * @param templateId the identifier for this template object
+ * @param controlTemplate a template to use for interaction with the user
+ * @param currentMode the current mode for the {@link Control}
+ * @param currentActiveMode the current active mode for the {@link Control}
+ * @param modesFlag a flag representing the available modes for the {@link Control}
+ * @throws IllegalArgumentException if the parameters passed do not make a valid template.
+ */
public TemperatureControlTemplate(@NonNull String templateId,
@NonNull ControlTemplate controlTemplate,
@Mode int currentMode,
@@ -179,6 +200,9 @@
return mModes;
}
+ /**
+ * @return {@link ControlTemplate#TYPE_TEMPERATURE}
+ */
@Override
public int getTemplateType() {
return TYPE;
diff --git a/core/java/android/service/controls/templates/ToggleRangeTemplate.java b/core/java/android/service/controls/templates/ToggleRangeTemplate.java
index af43b94..cd6a2fc 100644
--- a/core/java/android/service/controls/templates/ToggleRangeTemplate.java
+++ b/core/java/android/service/controls/templates/ToggleRangeTemplate.java
@@ -18,9 +18,16 @@
import android.annotation.NonNull;
import android.os.Bundle;
+import android.service.controls.Control;
import com.android.internal.util.Preconditions;
+/**
+ * A template for a {@link Control} supporting toggling and a range.
+ *
+ * @see ToggleTemplate
+ * @see RangeTemplate
+ */
public final class ToggleRangeTemplate extends ControlTemplate {
private static final @TemplateType int TYPE = TYPE_TOGGLE_RANGE;
@@ -40,6 +47,12 @@
mRangeTemplate = new RangeTemplate(b.getBundle(KEY_RANGE));
}
+ /**
+ * Constructs a new {@link ToggleRangeTemplate}.
+ * @param templateId the identifier for this template.
+ * @param button a {@link ControlButton} to use for the toggle interface
+ * @param range a {@link RangeTemplate} to use for the range interface
+ */
public ToggleRangeTemplate(@NonNull String templateId,
@NonNull ControlButton button,
@NonNull RangeTemplate range) {
@@ -50,6 +63,14 @@
mRangeTemplate = range;
}
+ /**
+ * Constructs a new {@link ToggleRangeTemplate}.
+ * @param templateId the identifier for this template.
+ * @param checked true if the toggle should be rendered as active.
+ * @param actionDescription action description for the button.
+ * @param range {@link RangeTemplate} to use for the range interface
+ * @see ControlButton
+ */
public ToggleRangeTemplate(@NonNull String templateId,
boolean checked,
@NonNull CharSequence actionDescription,
@@ -86,6 +107,9 @@
return mControlButton.getActionDescription();
}
+ /**
+ * @return {@link ControlTemplate#TYPE_TOGGLE_RANGE}
+ */
@Override
public int getTemplateType() {
return TYPE;
diff --git a/core/java/android/view/IRecentsAnimationController.aidl b/core/java/android/view/IRecentsAnimationController.aidl
index 530dffb..a60a5cc 100644
--- a/core/java/android/view/IRecentsAnimationController.aidl
+++ b/core/java/android/view/IRecentsAnimationController.aidl
@@ -67,11 +67,6 @@
void setAnimationTargetsBehindSystemBars(boolean behindSystemBars);
/**
- * Informs the system that the primary split-screen stack should be minimized.
- */
- void setSplitScreenMinimized(boolean minimized);
-
- /**
* Hides the current input method if one is showing.
*/
void hideCurrentInputMethod();
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 1730347..73601d9 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -444,8 +444,7 @@
WindowContentFrameStats getWindowContentFrameStats(IBinder token);
/**
- * @return the dock side the current docked stack is at; must be one of the
- * WindowManagerGlobal.DOCKED_* values
+ * This is a no-op.
*/
@UnsupportedAppUsage
int getDockedStackSide();
@@ -457,27 +456,11 @@
void setDockedStackDividerTouchRegion(in Rect touchableRegion);
/**
- * Registers a listener that will be called when the dock divider changes its visibility or when
- * the docked stack gets added/removed.
- */
- @UnsupportedAppUsage
- void registerDockedStackListener(IDockedStackListener listener);
-
- /**
* Registers a listener that will be called when the pinned stack state changes.
*/
void registerPinnedStackListener(int displayId, IPinnedStackListener listener);
/**
- * Updates the dim layer used while resizing.
- *
- * @param visible Whether the dim layer should be visible.
- * @param targetWindowingMode The windowing mode of the stack the dim layer should be placed on.
- * @param alpha The translucency of the dim layer, between 0 and 1.
- */
- void setResizeDimLayer(boolean visible, int targetWindowingMode, float alpha);
-
- /**
* Requests Keyboard Shortcuts from the displayed window.
*
* @param receiver The receiver to deliver the results to.
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 11ab572..15d18d1 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -29794,7 +29794,7 @@
// accessibility
CharSequence contentDescription = getContentDescription();
- stream.addProperty("accessibility:contentDescription",
+ stream.addUserProperty("accessibility:contentDescription",
contentDescription == null ? "" : contentDescription.toString());
stream.addProperty("accessibility:labelFor", getLabelFor());
stream.addProperty("accessibility:importantForAccessibility", getImportantForAccessibility());
diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java
index 2f44fe0..8a5be75 100644
--- a/core/java/android/view/ViewDebug.java
+++ b/core/java/android/view/ViewDebug.java
@@ -1209,6 +1209,7 @@
ByteArrayOutputStream baOut = new ByteArrayOutputStream();
final ViewHierarchyEncoder encoder = new ViewHierarchyEncoder(baOut);
+ encoder.setUserPropertiesEnabled(false);
encoder.addProperty("window:left", view.mAttachInfo.mWindowLeft);
encoder.addProperty("window:top", view.mAttachInfo.mWindowTop);
view.encode(encoder);
diff --git a/core/java/android/view/ViewHierarchyEncoder.java b/core/java/android/view/ViewHierarchyEncoder.java
index b0e0524..ace05a6 100644
--- a/core/java/android/view/ViewHierarchyEncoder.java
+++ b/core/java/android/view/ViewHierarchyEncoder.java
@@ -66,10 +66,16 @@
private short mPropertyId = 1;
private Charset mCharset = Charset.forName("utf-8");
+ private boolean mUserPropertiesEnabled = true;
+
public ViewHierarchyEncoder(@NonNull ByteArrayOutputStream stream) {
mStream = new DataOutputStream(stream);
}
+ public void setUserPropertiesEnabled(boolean enabled) {
+ mUserPropertiesEnabled = enabled;
+ }
+
public void beginObject(@NonNull Object o) {
startPropertyMap();
addProperty("meta:__name__", o.getClass().getName());
@@ -121,6 +127,17 @@
}
/**
+ * Encodes a user defined property if they are allowed to be encoded
+ *
+ * @see #setUserPropertiesEnabled(boolean)
+ */
+ public void addUserProperty(@NonNull String name, @Nullable String s) {
+ if (mUserPropertiesEnabled) {
+ addProperty(name, s);
+ }
+ }
+
+ /**
* Writes the given name as the property name, and leaves it to the callee
* to fill in value for this property.
*/
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 815cc5c..f3243aa 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -13174,7 +13174,7 @@
stream.addProperty("text:selectionStart", getSelectionStart());
stream.addProperty("text:selectionEnd", getSelectionEnd());
stream.addProperty("text:curTextColor", mCurTextColor);
- stream.addProperty("text:text", mText == null ? null : mText.toString());
+ stream.addUserProperty("text:text", mText == null ? null : mText.toString());
stream.addProperty("text:gravity", mGravity);
}
diff --git a/core/java/com/android/internal/logging/InstanceIdSequence.java b/core/java/com/android/internal/logging/InstanceIdSequence.java
index aa507e5..3464310 100644
--- a/core/java/com/android/internal/logging/InstanceIdSequence.java
+++ b/core/java/com/android/internal/logging/InstanceIdSequence.java
@@ -25,7 +25,7 @@
import java.util.Random;
/**
- * Generates random InstanceIds in range [0, instanceIdMax) for passing to
+ * Generates random InstanceIds in range [1, instanceIdMax] for passing to
* UiEventLogger.logWithInstanceId(). Holds a SecureRandom, which self-seeds on
* first use; try to give it a long lifetime. Safe for concurrent use.
*/
@@ -34,12 +34,12 @@
private final Random mRandom = new SecureRandom();
/**
- * Constructs a sequence with identifiers [0, instanceIdMax). Capped at INSTANCE_ID_MAX.
+ * Constructs a sequence with identifiers [1, instanceIdMax]. Capped at INSTANCE_ID_MAX.
* @param instanceIdMax Limiting value of identifiers. Normally positive: otherwise you get
- * an all-zero sequence.
+ * an all-1 sequence.
*/
public InstanceIdSequence(int instanceIdMax) {
- mInstanceIdMax = min(max(0, instanceIdMax), InstanceId.INSTANCE_ID_MAX);
+ mInstanceIdMax = min(max(1, instanceIdMax), InstanceId.INSTANCE_ID_MAX);
}
/**
@@ -47,7 +47,7 @@
* @return new InstanceId
*/
public InstanceId newInstanceId() {
- return newInstanceIdInternal(mRandom.nextInt(mInstanceIdMax));
+ return newInstanceIdInternal(1 + mRandom.nextInt(mInstanceIdMax));
}
/**
diff --git a/core/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto
index 08db454..e8a0b46 100644
--- a/core/proto/android/server/windowmanagerservice.proto
+++ b/core/proto/android/server/windowmanagerservice.proto
@@ -167,7 +167,7 @@
optional WindowContainerProto window_container = 1;
optional int32 id = 2;
reserved 3; // stacks
- optional DockedStackDividerControllerProto docked_stack_divider_controller = 4;
+ optional DockedStackDividerControllerProto docked_stack_divider_controller = 4 [deprecated=true];
// Will be removed soon.
optional PinnedStackControllerProto pinned_stack_controller = 5 [deprecated=true];
/* non app windows */
@@ -229,7 +229,7 @@
message DockedStackDividerControllerProto {
option (.android.msg_privacy).dest = DEST_AUTOMATIC;
- optional bool minimized_dock = 1;
+ optional bool minimized_dock = 1 [deprecated=true];
}
/* represents PinnedStackController */
diff --git a/data/etc/com.android.documentsui.xml b/data/etc/com.android.documentsui.xml
index 4d98603..0ffaa21 100644
--- a/data/etc/com.android.documentsui.xml
+++ b/data/etc/com.android.documentsui.xml
@@ -18,5 +18,6 @@
<privapp-permissions package="com.android.documentsui">
<permission name="android.permission.CHANGE_OVERLAY_PACKAGES"/>
<permission name="android.permission.INTERACT_ACROSS_USERS"/>
+ <permission name="android.permission.MODIFY_QUIET_MODE"/>
</privapp-permissions>
</permissions>
diff --git a/media/java/android/media/tv/tuner/Tuner.java b/media/java/android/media/tv/tuner/Tuner.java
index 73769be..7a684b3 100644
--- a/media/java/android/media/tv/tuner/Tuner.java
+++ b/media/java/android/media/tv/tuner/Tuner.java
@@ -18,11 +18,13 @@
import android.annotation.BytesLong;
import android.annotation.CallbackExecutor;
+import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.content.Context;
+import android.hardware.tv.tuner.V1_0.Constants;
import android.media.tv.TvInputService;
import android.media.tv.tuner.TunerConstants.Result;
import android.media.tv.tuner.dvr.DvrPlayback;
@@ -45,6 +47,8 @@
import android.os.Looper;
import android.os.Message;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.Executor;
@@ -67,6 +71,22 @@
private static final int MSG_ON_FILTER_STATUS = 3;
private static final int MSG_ON_LNB_EVENT = 4;
+ /** @hide */
+ @IntDef(prefix = "DVR_TYPE_", value = {DVR_TYPE_RECORD, DVR_TYPE_PLAYBACK})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface DvrType {}
+
+ /**
+ * DVR for recording.
+ * @hide
+ */
+ public static final int DVR_TYPE_RECORD = Constants.DvrType.RECORD;
+ /**
+ * DVR for playback of recorded programs.
+ * @hide
+ */
+ public static final int DVR_TYPE_PLAYBACK = Constants.DvrType.PLAYBACK;
+
static {
System.loadLibrary("media_tv_tuner");
nativeInit();
diff --git a/media/java/android/media/tv/tuner/dvr/Dvr.java b/media/java/android/media/tv/tuner/dvr/Dvr.java
deleted file mode 100644
index 4183e3b..0000000
--- a/media/java/android/media/tv/tuner/dvr/Dvr.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright 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.media.tv.tuner.dvr;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.hardware.tv.tuner.V1_0.Constants;
-import android.media.tv.tuner.TunerConstants.Result;
-import android.media.tv.tuner.filter.Filter;
-import android.os.ParcelFileDescriptor;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Digital Video Record (DVR) interface provides record control on Demux's output buffer and
- * playback control on Demux's input buffer.
- *
- * @hide
- */
-@SystemApi
-public class Dvr implements AutoCloseable {
-
- /** @hide */
- @IntDef(prefix = "TYPE_", value = {TYPE_RECORD, TYPE_PLAYBACK})
- @Retention(RetentionPolicy.SOURCE)
- public @interface Type {}
-
- /**
- * DVR for recording.
- */
- public static final int TYPE_RECORD = Constants.DvrType.RECORD;
- /**
- * DVR for playback of recorded programs.
- */
- public static final int TYPE_PLAYBACK = Constants.DvrType.PLAYBACK;
-
-
- final int mType;
- long mNativeContext;
-
- private native int nativeAttachFilter(Filter filter);
- private native int nativeDetachFilter(Filter filter);
- private native int nativeConfigureDvr(DvrSettings settings);
- private native int nativeStartDvr();
- private native int nativeStopDvr();
- private native int nativeFlushDvr();
- private native int nativeClose();
- private native void nativeSetFileDescriptor(int fd);
-
- protected Dvr(int type) {
- mType = type;
- }
-
- /**
- * Attaches a filter to DVR interface for recording.
- *
- * @param filter the filter to be attached.
- * @return result status of the operation.
- */
- @Result
- public int attachFilter(@NonNull Filter filter) {
- return nativeAttachFilter(filter);
- }
-
- /**
- * Detaches a filter from DVR interface.
- *
- * @param filter the filter to be detached.
- * @return result status of the operation.
- */
- @Result
- public int detachFilter(@NonNull Filter filter) {
- return nativeDetachFilter(filter);
- }
-
- /**
- * Configures the DVR.
- *
- * @param settings the settings of the DVR interface.
- * @return result status of the operation.
- */
- @Result
- public int configure(@NonNull DvrSettings settings) {
- return nativeConfigureDvr(settings);
- }
-
- /**
- * Starts DVR.
- *
- * <p>Starts consuming playback data or producing data for recording.
- *
- * @return result status of the operation.
- */
- @Result
- public int start() {
- return nativeStartDvr();
- }
-
- /**
- * Stops DVR.
- *
- * <p>Stops consuming playback data or producing data for recording.
- *
- * @return result status of the operation.
- */
- @Result
- public int stop() {
- return nativeStopDvr();
- }
-
- /**
- * Flushed DVR data.
- *
- * <p>The data in DVR buffer is cleared.
- *
- * @return result status of the operation.
- */
- @Result
- public int flush() {
- return nativeFlushDvr();
- }
-
- /**
- * Closes the DVR instance to release resources.
- */
- public void close() {
- nativeClose();
- }
-
- /**
- * Sets file descriptor to read/write data.
- *
- * @param fd the file descriptor to read/write data.
- */
- public void setFileDescriptor(@NonNull ParcelFileDescriptor fd) {
- nativeSetFileDescriptor(fd.getFd());
- }
-
- @Type
- int getType() {
- return mType;
- }
-}
diff --git a/media/java/android/media/tv/tuner/dvr/DvrPlayback.java b/media/java/android/media/tv/tuner/dvr/DvrPlayback.java
index eb31574..7c15bb7 100644
--- a/media/java/android/media/tv/tuner/dvr/DvrPlayback.java
+++ b/media/java/android/media/tv/tuner/dvr/DvrPlayback.java
@@ -21,6 +21,9 @@
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.hardware.tv.tuner.V1_0.Constants;
+import android.media.tv.tuner.TunerConstants.Result;
+import android.media.tv.tuner.filter.Filter;
+import android.os.ParcelFileDescriptor;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -33,7 +36,7 @@
* @hide
*/
@SystemApi
-public class DvrPlayback extends Dvr {
+public class DvrPlayback implements AutoCloseable {
/** @hide */
@@ -66,17 +69,110 @@
*/
public static final int PLAYBACK_STATUS_FULL = Constants.PlaybackStatus.SPACE_FULL;
+ long mNativeContext;
-
+ private native int nativeAttachFilter(Filter filter);
+ private native int nativeDetachFilter(Filter filter);
+ private native int nativeConfigureDvr(DvrSettings settings);
+ private native int nativeStartDvr();
+ private native int nativeStopDvr();
+ private native int nativeFlushDvr();
+ private native int nativeClose();
+ private native void nativeSetFileDescriptor(int fd);
private native long nativeRead(long size);
private native long nativeRead(byte[] bytes, long offset, long size);
private DvrPlayback() {
- super(Dvr.TYPE_PLAYBACK);
}
/**
+ * Attaches a filter to DVR interface for recording.
+ *
+ * @param filter the filter to be attached.
+ * @return result status of the operation.
+ */
+ @Result
+ public int attachFilter(@NonNull Filter filter) {
+ return nativeAttachFilter(filter);
+ }
+
+ /**
+ * Detaches a filter from DVR interface.
+ *
+ * @param filter the filter to be detached.
+ * @return result status of the operation.
+ */
+ @Result
+ public int detachFilter(@NonNull Filter filter) {
+ return nativeDetachFilter(filter);
+ }
+
+ /**
+ * Configures the DVR.
+ *
+ * @param settings the settings of the DVR interface.
+ * @return result status of the operation.
+ */
+ @Result
+ public int configure(@NonNull DvrSettings settings) {
+ return nativeConfigureDvr(settings);
+ }
+
+ /**
+ * Starts DVR.
+ *
+ * <p>Starts consuming playback data or producing data for recording.
+ *
+ * @return result status of the operation.
+ */
+ @Result
+ public int start() {
+ return nativeStartDvr();
+ }
+
+ /**
+ * Stops DVR.
+ *
+ * <p>Stops consuming playback data or producing data for recording.
+ *
+ * @return result status of the operation.
+ */
+ @Result
+ public int stop() {
+ return nativeStopDvr();
+ }
+
+ /**
+ * Flushed DVR data.
+ *
+ * <p>The data in DVR buffer is cleared.
+ *
+ * @return result status of the operation.
+ */
+ @Result
+ public int flush() {
+ return nativeFlushDvr();
+ }
+
+ /**
+ * Closes the DVR instance to release resources.
+ */
+ @Override
+ public void close() {
+ nativeClose();
+ }
+
+ /**
+ * Sets file descriptor to read/write data.
+ *
+ * @param fd the file descriptor to read/write data.
+ */
+ public void setFileDescriptor(@NonNull ParcelFileDescriptor fd) {
+ nativeSetFileDescriptor(fd.getFd());
+ }
+
+ /**
* Reads data from the file for DVR playback.
*
* @param size the maximum number of bytes to read.
diff --git a/media/java/android/media/tv/tuner/dvr/DvrRecorder.java b/media/java/android/media/tv/tuner/dvr/DvrRecorder.java
index 3128ca5..52ef5e6 100644
--- a/media/java/android/media/tv/tuner/dvr/DvrRecorder.java
+++ b/media/java/android/media/tv/tuner/dvr/DvrRecorder.java
@@ -19,6 +19,9 @@
import android.annotation.BytesLong;
import android.annotation.NonNull;
import android.annotation.SystemApi;
+import android.media.tv.tuner.TunerConstants.Result;
+import android.media.tv.tuner.filter.Filter;
+import android.os.ParcelFileDescriptor;
/**
* Digital Video Record (DVR) recorder class which provides record control on Demux's output buffer.
@@ -26,12 +29,108 @@
* @hide
*/
@SystemApi
-public class DvrRecorder extends Dvr {
+public class DvrRecorder implements AutoCloseable {
+ long mNativeContext;
+
+ private native int nativeAttachFilter(Filter filter);
+ private native int nativeDetachFilter(Filter filter);
+ private native int nativeConfigureDvr(DvrSettings settings);
+ private native int nativeStartDvr();
+ private native int nativeStopDvr();
+ private native int nativeFlushDvr();
+ private native int nativeClose();
+ private native void nativeSetFileDescriptor(int fd);
private native long nativeWrite(long size);
private native long nativeWrite(byte[] bytes, long offset, long size);
private DvrRecorder() {
- super(Dvr.TYPE_RECORD);
+ }
+
+
+ /**
+ * Attaches a filter to DVR interface for recording.
+ *
+ * @param filter the filter to be attached.
+ * @return result status of the operation.
+ */
+ @Result
+ public int attachFilter(@NonNull Filter filter) {
+ return nativeAttachFilter(filter);
+ }
+
+ /**
+ * Detaches a filter from DVR interface.
+ *
+ * @param filter the filter to be detached.
+ * @return result status of the operation.
+ */
+ @Result
+ public int detachFilter(@NonNull Filter filter) {
+ return nativeDetachFilter(filter);
+ }
+
+ /**
+ * Configures the DVR.
+ *
+ * @param settings the settings of the DVR interface.
+ * @return result status of the operation.
+ */
+ @Result
+ public int configure(@NonNull DvrSettings settings) {
+ return nativeConfigureDvr(settings);
+ }
+
+ /**
+ * Starts DVR.
+ *
+ * <p>Starts consuming playback data or producing data for recording.
+ *
+ * @return result status of the operation.
+ */
+ @Result
+ public int start() {
+ return nativeStartDvr();
+ }
+
+ /**
+ * Stops DVR.
+ *
+ * <p>Stops consuming playback data or producing data for recording.
+ *
+ * @return result status of the operation.
+ */
+ @Result
+ public int stop() {
+ return nativeStopDvr();
+ }
+
+ /**
+ * Flushed DVR data.
+ *
+ * <p>The data in DVR buffer is cleared.
+ *
+ * @return result status of the operation.
+ */
+ @Result
+ public int flush() {
+ return nativeFlushDvr();
+ }
+
+ /**
+ * Closes the DVR instance to release resources.
+ */
+ @Override
+ public void close() {
+ nativeClose();
+ }
+
+ /**
+ * Sets file descriptor to read/write data.
+ *
+ * @param fd the file descriptor to read/write data.
+ */
+ public void setFileDescriptor(@NonNull ParcelFileDescriptor fd) {
+ nativeSetFileDescriptor(fd.getFd());
}
/**
diff --git a/media/java/android/media/tv/tuner/dvr/DvrSettings.java b/media/java/android/media/tv/tuner/dvr/DvrSettings.java
index f9dc682..362b108 100644
--- a/media/java/android/media/tv/tuner/dvr/DvrSettings.java
+++ b/media/java/android/media/tv/tuner/dvr/DvrSettings.java
@@ -30,7 +30,7 @@
import java.lang.annotation.RetentionPolicy;
/**
- * DVR settings used to configure {@link Dvr}.
+ * DVR settings used to configure {@link DvrPlayback} and {@link DvrRecorder}.
*
* @hide
*/
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index a4eada4..f39f912 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -122,6 +122,7 @@
import com.android.systemui.statusbar.phone.LockscreenWallpaper;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
import com.android.systemui.statusbar.phone.NotificationShadeWindowController;
+import com.android.systemui.statusbar.phone.PhoneStatusBarPolicy;
import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.statusbar.phone.ShadeController;
import com.android.systemui.statusbar.phone.StatusBar;
@@ -324,6 +325,7 @@
KeyguardDismissUtil keyguardDismissUtil,
ExtensionController extensionController,
UserInfoControllerImpl userInfoControllerImpl,
+ PhoneStatusBarPolicy phoneStatusBarPolicy,
DismissCallbackRegistry dismissCallbackRegistry,
StatusBarTouchableRegionManager statusBarTouchableRegionManager,
/* Car Settings injected components. */
@@ -407,6 +409,7 @@
keyguardDismissUtil,
extensionController,
userInfoControllerImpl,
+ phoneStatusBarPolicy,
dismissCallbackRegistry,
statusBarTouchableRegionManager);
mUserSwitcherController = userSwitcherController;
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarModule.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarModule.java
index 7294965..843e7c5 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarModule.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarModule.java
@@ -82,6 +82,7 @@
import com.android.systemui.statusbar.phone.LockscreenWallpaper;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
import com.android.systemui.statusbar.phone.NotificationShadeWindowController;
+import com.android.systemui.statusbar.phone.PhoneStatusBarPolicy;
import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.statusbar.phone.ShadeController;
import com.android.systemui.statusbar.phone.StatusBarIconController;
@@ -197,6 +198,7 @@
KeyguardDismissUtil keyguardDismissUtil,
ExtensionController extensionController,
UserInfoControllerImpl userInfoControllerImpl,
+ PhoneStatusBarPolicy phoneStatusBarPolicy,
DismissCallbackRegistry dismissCallbackRegistry,
StatusBarTouchableRegionManager statusBarTouchableRegionManager,
CarServiceProvider carServiceProvider,
@@ -278,6 +280,7 @@
keyguardDismissUtil,
extensionController,
userInfoControllerImpl,
+ phoneStatusBarPolicy,
dismissCallbackRegistry,
statusBarTouchableRegionManager,
carServiceProvider,
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 6d11461..2297ddf 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -892,9 +892,9 @@
<!-- UI debug setting: enable gpu debug layers summary [CHAR LIMIT=50] -->
<string name="enable_gpu_debug_layers_summary">Allow loading GPU debug layers for debug apps</string>
- <!-- UI debug setting: enable verbose vendor logging [CHAR LIMIT=30] -->
+ <!-- UI debug setting: enable verbose vendor logging [CHAR LIMIT=60] -->
<string name="enable_verbose_vendor_logging">Enable verbose vendor logging</string>
- <!-- UI debug setting: enable verbose vendor logging summary [CHAR LIMIT=100] -->
+ <!-- UI debug setting: enable verbose vendor logging summary [CHAR LIMIT=NONE] -->
<string name="enable_verbose_vendor_logging_summary">Allow additional vendor logs to be included in bug reports, may contain private information</string>
<!-- UI debug setting: scaling factor for window animations [CHAR LIMIT=25] -->
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.java
index d233649..0e6a60b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.java
@@ -68,7 +68,8 @@
for (int reason = 0; reason <= getMaxNetworkSelectionDisableReason(); reason++) {
if (networkStatus.getDisableReasonCounter(reason) != 0) {
summary.append(" ")
- .append(NetworkSelectionStatus.getNetworkDisableReasonString(reason))
+ .append(NetworkSelectionStatus
+ .getNetworkSelectionDisableReasonString(reason))
.append("=")
.append(networkStatus.getDisableReasonCounter(reason));
}
diff --git a/packages/SystemUI/res/layout/controls_management.xml b/packages/SystemUI/res/layout/controls_management.xml
index a7379be..6533c18 100644
--- a/packages/SystemUI/res/layout/controls_management.xml
+++ b/packages/SystemUI/res/layout/controls_management.xml
@@ -70,12 +70,14 @@
android:layout_height="match_parent"
android:padding="4dp">
- <TextView
+ <Button
+ android:id="@+id/other_apps"
+ android:visibility="gone"
android:layout_width="wrap_content"
android:layout_height="match_parent"
+ android:gravity="center_vertical"
android:text="See other apps"
- android:textAppearance="@style/TextAppearance.Control.Title"
- android:textColor="?android:attr/colorPrimary"
+ style="@*android:style/Widget.DeviceDefault.Button.Borderless.Colored"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
@@ -85,6 +87,7 @@
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="Done"
+ style="@*android:style/Widget.DeviceDefault.Button.Colored"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
diff --git a/packages/SystemUI/res/layout/controls_management_favorites.xml b/packages/SystemUI/res/layout/controls_management_favorites.xml
index 62056e6..aab32f4 100644
--- a/packages/SystemUI/res/layout/controls_management_favorites.xml
+++ b/packages/SystemUI/res/layout/controls_management_favorites.xml
@@ -14,97 +14,26 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-<androidx.constraintlayout.widget.ConstraintLayout
+<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
- android:id="@+id/error_message"
+ android:id="@+id/status_message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/controls_management_list_margin"
- android:text="@string/controls_favorite_load_error"
android:textAppearance="?android:attr/textAppearanceSmall"
- android:visibility="gone"
android:gravity="center_horizontal"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintTop_toBottomOf="parent"
- app:layout_constraintBottom_toTopOf="@id/text_favorites"
/>
- <TextView
- android:id="@+id/text_favorites"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="@dimen/controls_management_list_margin"
- android:text="@string/controls_favorite_header_favorites"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:textAllCaps="true"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintBottom_toTopOf="@id/divider1"
- app:layout_constraintTop_toBottomOf="@id/error_message"
- />
-
- <View
- android:id="@+id/divider1"
- android:layout_width="match_parent"
- android:layout_height="@dimen/controls_app_divider_height"
- android:layout_gravity="center_horizontal|top"
- android:background="?android:attr/listDivider"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintBottom_toTopOf="@id/listFavorites"
- app:layout_constraintTop_toBottomOf="@id/text_favorites"
- />
-
- <androidx.recyclerview.widget.RecyclerView
- android:id="@+id/listFavorites"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_marginTop="@dimen/controls_management_list_margin"
- android:nestedScrollingEnabled="false"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintBottom_toTopOf="@id/text_all"
- app:layout_constraintTop_toBottomOf="@id/divider1"/>
-
- <TextView
- android:id="@+id/text_all"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="@dimen/controls_management_list_margin"
- android:text="@string/controls_favorite_header_all"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:textAllCaps="true"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintBottom_toTopOf="@id/divider2"
- app:layout_constraintTop_toBottomOf="@id/listFavorites"
- />
-
- <View
- android:id="@+id/divider2"
- android:layout_width="match_parent"
- android:layout_height="@dimen/controls_app_divider_height"
- android:layout_gravity="center_horizontal|top"
- android:background="?android:attr/listDivider"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintBottom_toTopOf="@id/listAll"
- app:layout_constraintTop_toBottomOf="@id/text_all"
- />
-
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/listAll"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="@dimen/controls_management_list_margin"
- android:nestedScrollingEnabled="false"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintTop_toBottomOf="@id/divider2"/>
+ android:nestedScrollingEnabled="false"/>
-</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
+</LinearLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/status_bar.xml b/packages/SystemUI/res/layout/status_bar.xml
index 4fae3c5..f8db97d 100644
--- a/packages/SystemUI/res/layout/status_bar.xml
+++ b/packages/SystemUI/res/layout/status_bar.xml
@@ -24,7 +24,6 @@
android:layout_width="match_parent"
android:layout_height="@dimen/status_bar_height"
android:id="@+id/status_bar"
- android:background="@drawable/system_bar_background"
android:orientation="vertical"
android:focusable="false"
android:descendantFocusability="afterDescendants"
diff --git a/packages/SystemUI/res/layout/super_status_bar.xml b/packages/SystemUI/res/layout/super_status_bar.xml
index 8fee2cf9..7142929 100644
--- a/packages/SystemUI/res/layout/super_status_bar.xml
+++ b/packages/SystemUI/res/layout/super_status_bar.xml
@@ -28,5 +28,6 @@
<FrameLayout
android:id="@+id/status_bar_container"
android:layout_width="match_parent"
- android:layout_height="wrap_content" />
+ android:layout_height="wrap_content"
+ android:background="@drawable/system_bar_background" />
</com.android.systemui.statusbar.phone.StatusBarWindowView>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index a49aedf..8cb0c02 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -201,6 +201,13 @@
always-on display) -->
<string name="doze_brightness_sensor_type" translatable="false"></string>
+ <!-- Override value to use for proximity sensor. -->
+ <string name="proximity_sensor_type" translatable="false"></string>
+
+ <!-- If using proximity_sensor_type, specifies a threshold value to distinguish near and
+ far break points. A sensor value less than this is considered "near". -->
+ <item name="proximity_sensor_threshold" translatable="false" format="float" type="dimen"></item>
+
<!-- Doze: pulse parameter - how long does it take to fade in? -->
<integer name="doze_pulse_duration_in">130</integer>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 4aafec8..ff28b4d 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -2614,8 +2614,8 @@
<string name="controls_providers_subtitle">Choose an app from which to add controls</string>
<!-- Number of favorites for controls management screen [CHAR LIMIT=NONE]-->
<plurals name="controls_number_of_favorites">
- <item quantity="one"><xliff:g id="number" example="1">%s</xliff:g> current favorite.</item>
- <item quantity="other"><xliff:g id="number" example="3">%s</xliff:g> current favorites.</item>
+ <item quantity="one"><xliff:g id="number" example="1">%s</xliff:g> control added.</item>
+ <item quantity="other"><xliff:g id="number" example="3">%s</xliff:g> controls added.</item>
</plurals>
<!-- Controls management controls screen default title [CHAR LIMIT=30] -->
@@ -2626,6 +2626,10 @@
<string name="controls_favorite_header_favorites">Favorites</string>
<!-- Controls management controls screen all header [CHAR LIMIT=50] -->
<string name="controls_favorite_header_all">All</string>
- <!-- Controls management controls screen error on load message [CHAR LIMIT=50] -->
+ <!-- Controls management controls screen error on load message [CHAR LIMIT=60] -->
<string name="controls_favorite_load_error">The list of all controls could not be loaded.</string>
+ <!-- Controls management controls screen header for Other zone [CHAR LIMIT=60] -->
+ <string name="controls_favorite_other_zone_header">Other</string>
+
+
</resources>
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
index a130092..49e3e57 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
@@ -370,8 +370,7 @@
Rect initialBounds) {
try {
return ActivityTaskManager.getService().setTaskWindowingModeSplitScreenPrimary(taskId,
- createMode, true /* onTop */, false /* animate */, initialBounds,
- true /* showRecents */);
+ true /* onTop */);
} catch (RemoteException e) {
return false;
}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java
index 6cd6118..bbb83c7 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java
@@ -61,14 +61,6 @@
}
}
- public void setSplitScreenMinimized(boolean minimized) {
- try {
- mAnimationController.setSplitScreenMinimized(minimized);
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to set minimize dock", e);
- }
- }
-
public void hideCurrentInputMethod() {
try {
mAnimationController.hideCurrentInputMethod();
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java
index e28b1e2..d64bf77 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java
@@ -191,18 +191,6 @@
}
/**
- * Registers a docked stack listener with the system.
- */
- public void registerDockedStackListener(DockedStackListenerCompat listener) {
- try {
- WindowManagerGlobal.getWindowManagerService().registerDockedStackListener(
- listener.mListener);
- } catch (RemoteException e) {
- Log.w(TAG, "Failed to register docked stack listener");
- }
- }
-
- /**
* Adds a pinned stack listener, which will receive updates from the window manager service
* along with any other pinned stack listeners that were added via this method.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
index 4473b01..dbcdead 100644
--- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
@@ -20,7 +20,9 @@
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Rect;
+import android.os.Handler;
import android.os.HandlerThread;
+import android.os.SystemClock;
import android.os.Trace;
import android.service.wallpaper.WallpaperService;
import android.util.Log;
@@ -94,18 +96,28 @@
private EglHelper mEglHelper;
private StatusBarStateController mController;
private final Runnable mFinishRenderingTask = this::finishRendering;
- private final boolean mNeedTransition;
private boolean mShouldStopTransition;
- @VisibleForTesting
- final boolean mIsHighEndGfx;
- private final boolean mDisplayNeedsBlanking;
private final DisplayInfo mDisplayInfo = new DisplayInfo();
private final Object mMonitor = new Object();
+ @VisibleForTesting
+ boolean mIsHighEndGfx;
+ private boolean mDisplayNeedsBlanking;
+ private boolean mNeedTransition;
private boolean mNeedRedraw;
// This variable can only be accessed in synchronized block.
private boolean mWaitingForRendering;
GLEngine(Context context, DozeParameters dozeParameters) {
+ init(dozeParameters);
+ }
+
+ @VisibleForTesting
+ GLEngine(DozeParameters dozeParameters, Handler handler) {
+ super(SystemClock::elapsedRealtime, handler);
+ init(dozeParameters);
+ }
+
+ private void init(DozeParameters dozeParameters) {
mIsHighEndGfx = ActivityManager.isHighEndGfx();
mDisplayNeedsBlanking = dozeParameters.getDisplayNeedsBlanking();
mNeedTransition = mIsHighEndGfx && !mDisplayNeedsBlanking;
diff --git a/packages/SystemUI/src/com/android/systemui/Prefs.java b/packages/SystemUI/src/com/android/systemui/Prefs.java
index 10ae343..f0a82c5 100644
--- a/packages/SystemUI/src/com/android/systemui/Prefs.java
+++ b/packages/SystemUI/src/com/android/systemui/Prefs.java
@@ -164,7 +164,7 @@
get(context).unregisterOnSharedPreferenceChangeListener(listener);
}
- private static SharedPreferences get(Context context) {
+ public static SharedPreferences get(Context context) {
return context.getSharedPreferences(context.getPackageName(), Context.MODE_PRIVATE);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java
index 0ac1c12..79b691b 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java
@@ -39,6 +39,7 @@
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.FalsingPlugin;
import com.android.systemui.plugins.PluginListener;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.util.DeviceConfigProxy;
import com.android.systemui.util.sensors.ProximitySensor;
@@ -69,6 +70,7 @@
private final DockManager mDockManager;
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
private Executor mUiBgExecutor;
+ private final StatusBarStateController mStatusBarStateController;
@Inject
FalsingManagerProxy(Context context, PluginManager pluginManager, @Main Executor executor,
@@ -76,12 +78,14 @@
DeviceConfigProxy deviceConfig, DockManager dockManager,
KeyguardUpdateMonitor keyguardUpdateMonitor,
DumpManager dumpManager,
- @UiBackground Executor uiBgExecutor) {
+ @UiBackground Executor uiBgExecutor,
+ StatusBarStateController statusBarStateController) {
mDisplayMetrics = displayMetrics;
mProximitySensor = proximitySensor;
mDockManager = dockManager;
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mUiBgExecutor = uiBgExecutor;
+ mStatusBarStateController = statusBarStateController;
mProximitySensor.setTag(PROXIMITY_SENSOR_TAG);
mProximitySensor.setSensorDelay(SensorManager.SENSOR_DELAY_GAME);
mDeviceConfig = deviceConfig;
@@ -143,7 +147,8 @@
mKeyguardUpdateMonitor,
mProximitySensor,
mDeviceConfig,
- mDockManager
+ mDockManager,
+ mStatusBarStateController
);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java
index a084ae6..ec81b9f 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java
@@ -32,6 +32,8 @@
import com.android.systemui.classifier.Classifier;
import com.android.systemui.dock.DockManager;
import com.android.systemui.plugins.FalsingManager;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.util.DeviceConfigProxy;
import com.android.systemui.util.sensors.ProximitySensor;
@@ -59,6 +61,7 @@
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
private final ProximitySensor mProximitySensor;
private final DockManager mDockManager;
+ private final StatusBarStateController mStatusBarStateController;
private boolean mSessionStarted;
private MetricsLogger mMetricsLogger;
private int mIsFalseTouchCalls;
@@ -88,15 +91,29 @@
};
private boolean mPreviousResult = false;
+ private StatusBarStateController.StateListener mStatusBarStateListener =
+ new StatusBarStateController.StateListener() {
+ @Override
+ public void onStateChanged(int newState) {
+ logDebug("StatusBarState=" + StatusBarState.toShortString(newState));
+ mState = newState;
+ updateSessionActive();
+ }
+ };
+ private int mState;
+
public BrightLineFalsingManager(FalsingDataProvider falsingDataProvider,
KeyguardUpdateMonitor keyguardUpdateMonitor, ProximitySensor proximitySensor,
DeviceConfigProxy deviceConfigProxy,
- DockManager dockManager) {
+ DockManager dockManager, StatusBarStateController statusBarStateController) {
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mDataProvider = falsingDataProvider;
mProximitySensor = proximitySensor;
mDockManager = dockManager;
+ mStatusBarStateController = statusBarStateController;
mKeyguardUpdateMonitor.registerCallback(mKeyguardUpdateCallback);
+ mStatusBarStateController.addCallback(mStatusBarStateListener);
+ mState = mStatusBarStateController.getState();
mMetricsLogger = new MetricsLogger();
mClassifiers = new ArrayList<>();
@@ -116,13 +133,12 @@
mProximitySensor.register(mSensorEventListener);
}
-
private void unregisterSensors() {
mProximitySensor.unregister(mSensorEventListener);
}
private void sessionStart() {
- if (!mSessionStarted && !mShowingAod && mScreenOn) {
+ if (!mSessionStarted && shouldSessionBeActive()) {
logDebug("Starting Session");
mSessionStarted = true;
mJustUnlockedWithFace = false;
@@ -145,6 +161,19 @@
}
}
+
+ private void updateSessionActive() {
+ if (shouldSessionBeActive()) {
+ sessionStart();
+ } else {
+ sessionEnd();
+ }
+ }
+
+ private boolean shouldSessionBeActive() {
+ return mScreenOn && (mState == StatusBarState.KEYGUARD) && !mShowingAod;
+ }
+
private void updateInteractionType(@Classifier.InteractionType int type) {
logDebug("InteractionType: " + type);
mDataProvider.setInteractionType(type);
@@ -232,11 +261,7 @@
@Override
public void setShowingAod(boolean showingAod) {
mShowingAod = showingAod;
- if (showingAod) {
- sessionEnd();
- } else {
- sessionStart();
- }
+ updateSessionActive();
}
@Override
@@ -343,13 +368,13 @@
@Override
public void onScreenTurningOn() {
mScreenOn = true;
- sessionStart();
+ updateSessionActive();
}
@Override
public void onScreenOff() {
mScreenOn = false;
- sessionEnd();
+ updateSessionActive();
}
@@ -421,6 +446,7 @@
public void cleanup() {
unregisterSensors();
mKeyguardUpdateMonitor.removeCallback(mKeyguardUpdateCallback);
+ mStatusBarStateController.removeCallback(mStatusBarStateListener);
}
static void logDebug(String msg) {
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/AllModel.kt b/packages/SystemUI/src/com/android/systemui/controls/management/AllModel.kt
new file mode 100644
index 0000000..c053517
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/AllModel.kt
@@ -0,0 +1,114 @@
+/*
+ * 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.systemui.controls.management
+
+import android.text.TextUtils
+import android.util.ArrayMap
+import com.android.systemui.controls.ControlStatus
+import com.android.systemui.controls.controller.ControlInfo
+
+/**
+ * This model is used to show all controls separated by zones.
+ *
+ * The model will sort the controls and zones in the following manner:
+ * * The zones will be sorted in a first seen basis
+ * * The controls in each zone will be sorted in a first seen basis.
+ *
+ * @property controls List of all controls as returned by loading
+ * @property initialFavoriteIds sorted ids of favorite controls
+ * @property noZoneString text to use as header for all controls that have blank or `null` zone.
+ */
+class AllModel(
+ private val controls: List<ControlStatus>,
+ initialFavoriteIds: List<String>,
+ private val emptyZoneString: CharSequence
+) : ControlsModel {
+
+ override val favorites: List<ControlInfo.Builder>
+ get() = favoriteIds.mapNotNull { id ->
+ val control = controls.firstOrNull { it.control.controlId == id }?.control
+ control?.let {
+ ControlInfo.Builder().apply {
+ controlId = it.controlId
+ controlTitle = it.title
+ deviceType = it.deviceType
+ }
+ }
+ }
+
+ private val favoriteIds = initialFavoriteIds.toMutableList()
+
+ override val elements: List<ElementWrapper> = createWrappers(controls)
+
+ override fun changeFavoriteStatus(controlId: String, favorite: Boolean) {
+ if (favorite) {
+ favoriteIds.add(controlId)
+ } else {
+ favoriteIds.remove(controlId)
+ }
+ }
+
+ private fun createWrappers(list: List<ControlStatus>): List<ElementWrapper> {
+ val map = list.groupByTo(OrderedMap(ArrayMap<CharSequence, MutableList<ControlStatus>>())) {
+ it.control.zone ?: ""
+ }
+ val output = mutableListOf<ElementWrapper>()
+ var emptyZoneValues: Sequence<ControlWrapper>? = null
+ for (zoneName in map.orderedKeys) {
+ val values = map.getValue(zoneName).asSequence().map { ControlWrapper(it) }
+ if (TextUtils.isEmpty(zoneName)) {
+ emptyZoneValues = values
+ } else {
+ output.add(ZoneNameWrapper(zoneName))
+ output.addAll(values)
+ }
+ }
+ // Add controls with empty zone at the end
+ if (emptyZoneValues != null) {
+ if (map.size != 1) {
+ output.add(ZoneNameWrapper(emptyZoneString))
+ }
+ output.addAll(emptyZoneValues)
+ }
+ return output
+ }
+
+ private class OrderedMap<K, V>(private val map: MutableMap<K, V>) : MutableMap<K, V> by map {
+
+ val orderedKeys = mutableListOf<K>()
+
+ override fun put(key: K, value: V): V? {
+ if (key !in map) {
+ orderedKeys.add(key)
+ }
+ return map.put(key, value)
+ }
+
+ override fun clear() {
+ orderedKeys.clear()
+ map.clear()
+ }
+
+ override fun remove(key: K): V? {
+ val removed = map.remove(key)
+ if (removed != null) {
+ orderedKeys.remove(key)
+ }
+ return removed
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/AppAdapter.kt b/packages/SystemUI/src/com/android/systemui/controls/management/AppAdapter.kt
index ac5e089..25ebc65 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/AppAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/AppAdapter.kt
@@ -116,6 +116,10 @@
fun renderFavoritesForComponent(component: ComponentName): String {
val qty = favoriteFunction(component)
- return resources.getQuantityString(R.plurals.controls_number_of_favorites, qty, qty)
+ if (qty != 0) {
+ return resources.getQuantityString(R.plurals.controls_number_of_favorites, qty, qty)
+ } else {
+ return ""
+ }
}
}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt
index d3cabe6..0870a4d 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt
@@ -42,8 +42,7 @@
* @param onlyFavorites set to true to only display favorites instead of all controls
*/
class ControlAdapter(
- private val layoutInflater: LayoutInflater,
- private val onlyFavorites: Boolean = false
+ private val layoutInflater: LayoutInflater
) : RecyclerView.Adapter<Holder>() {
companion object {
@@ -57,22 +56,21 @@
}
}
- var modelList: List<ElementWrapper> = emptyList()
- private var favoritesModel: FavoriteModel? = null
+ private var model: ControlsModel? = null
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {
return when (viewType) {
TYPE_CONTROL -> {
ControlHolder(
- layoutInflater.inflate(R.layout.controls_base_item, parent, false).apply {
- layoutParams.apply {
- width = ViewGroup.LayoutParams.MATCH_PARENT
- }
- elevation = 15f
- },
- { id, favorite ->
- favoritesModel?.changeFavoriteStatus(id, favorite)
- })
+ layoutInflater.inflate(R.layout.controls_base_item, parent, false).apply {
+ layoutParams.apply {
+ width = ViewGroup.LayoutParams.MATCH_PARENT
+ }
+ elevation = 15f
+ }
+ ) { id, favorite ->
+ model?.changeFavoriteStatus(id, favorite)
+ }
}
TYPE_ZONE -> {
ZoneHolder(layoutInflater.inflate(R.layout.controls_zone_header, parent, false))
@@ -81,27 +79,26 @@
}
}
- fun changeFavoritesModel(favoritesModel: FavoriteModel) {
- this.favoritesModel = favoritesModel
- if (onlyFavorites) {
- modelList = favoritesModel.favorites
- } else {
- modelList = favoritesModel.all
- }
+ fun changeModel(model: ControlsModel) {
+ this.model = model
notifyDataSetChanged()
}
- override fun getItemCount() = modelList.size
+ override fun getItemCount() = model?.elements?.size ?: 0
override fun onBindViewHolder(holder: Holder, index: Int) {
- holder.bindData(modelList[index])
+ model?.let {
+ holder.bindData(it.elements[index])
+ }
}
override fun getItemViewType(position: Int): Int {
- return when (modelList[position]) {
- is ZoneNameWrapper -> TYPE_ZONE
- is ControlWrapper -> TYPE_CONTROL
- }
+ model?.let {
+ return when (it.elements.get(position)) {
+ is ZoneNameWrapper -> TYPE_ZONE
+ is ControlWrapper -> TYPE_CONTROL
+ }
+ } ?: throw IllegalStateException("Getting item type for null model")
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt
index af4a977..2c014498 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt
@@ -26,11 +26,9 @@
import android.widget.Button
import android.widget.TextView
import androidx.recyclerview.widget.GridLayoutManager
-import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView
import com.android.systemui.R
import com.android.systemui.broadcast.BroadcastDispatcher
-import com.android.systemui.controls.controller.ControlInfo
import com.android.systemui.controls.controller.ControlsControllerImpl
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.settings.CurrentUserTracker
@@ -51,33 +49,10 @@
private lateinit var recyclerViewAll: RecyclerView
private lateinit var adapterAll: ControlAdapter
- private lateinit var recyclerViewFavorites: RecyclerView
- private lateinit var adapterFavorites: ControlAdapter
- private lateinit var errorText: TextView
+ private lateinit var statusText: TextView
+ private var model: ControlsModel? = null
private var component: ComponentName? = null
- private var currentModel: FavoriteModel? = null
- private var itemTouchHelperCallback = object : ItemTouchHelper.SimpleCallback(
- /* dragDirs */ ItemTouchHelper.UP
- or ItemTouchHelper.DOWN
- or ItemTouchHelper.LEFT
- or ItemTouchHelper.RIGHT,
- /* swipeDirs */0
- ) {
- override fun onMove(
- recyclerView: RecyclerView,
- viewHolder: RecyclerView.ViewHolder,
- target: RecyclerView.ViewHolder
- ): Boolean {
- return currentModel?.onMoveItem(
- viewHolder.layoutPosition, target.layoutPosition) != null
- }
-
- override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {}
-
- override fun isItemViewSwipeEnabled() = false
- }
-
private val currentUserTracker = object : CurrentUserTracker(broadcastDispatcher) {
private val startingUser = controller.currentUserId
@@ -89,6 +64,10 @@
}
}
+ override fun onBackPressed() {
+ finish()
+ }
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.controls_management)
@@ -99,21 +78,27 @@
val app = intent.getCharSequenceExtra(EXTRA_APP)
component = intent.getParcelableExtra<ComponentName>(Intent.EXTRA_COMPONENT_NAME)
- errorText = requireViewById(R.id.error_message)
+ statusText = requireViewById(R.id.status_message)
- setUpRecyclerViews()
+ setUpRecyclerView()
requireViewById<TextView>(R.id.title).text = app?.let { it }
?: resources.getText(R.string.controls_favorite_default_title)
requireViewById<TextView>(R.id.subtitle).text =
resources.getText(R.string.controls_favorite_subtitle)
+ requireViewById<Button>(R.id.other_apps).apply {
+ visibility = View.VISIBLE
+ setOnClickListener {
+ this@ControlsFavoritingActivity.onBackPressed()
+ }
+ }
+
requireViewById<Button>(R.id.done).setOnClickListener {
if (component == null) return@setOnClickListener
- val favoritesForStorage = currentModel?.favorites?.map {
- with(it.controlStatus.control) {
- ControlInfo(component!!, controlId, title, deviceType)
- }
+ val favoritesForStorage = model?.favorites?.map {
+ it.componentName = component!!
+ it.build()
}
if (favoritesForStorage != null) {
controller.replaceFavoritesForComponent(component!!, favoritesForStorage)
@@ -122,20 +107,22 @@
}
component?.let {
+ statusText.text = resources.getText(com.android.internal.R.string.loading)
controller.loadForComponent(it, Consumer { data ->
val allControls = data.allControls
val favoriteKeys = data.favoritesIds
val error = data.errorOnLoad
executor.execute {
- val favoriteModel = FavoriteModel(
- allControls,
- favoriteKeys,
- allAdapter = adapterAll,
- favoritesAdapter = adapterFavorites)
- adapterAll.changeFavoritesModel(favoriteModel)
- adapterFavorites.changeFavoritesModel(favoriteModel)
- currentModel = favoriteModel
- errorText.visibility = if (error) View.VISIBLE else View.GONE
+ val emptyZoneString = resources.getText(
+ R.string.controls_favorite_other_zone_header)
+ val model = AllModel(allControls, favoriteKeys, emptyZoneString)
+ adapterAll.changeModel(model)
+ this.model = model
+ if (error) {
+ statusText.text = resources.getText(R.string.controls_favorite_load_error)
+ } else {
+ statusText.visibility = View.GONE
+ }
}
})
}
@@ -143,7 +130,7 @@
currentUserTracker.startTracking()
}
- private fun setUpRecyclerViews() {
+ private fun setUpRecyclerView() {
val margin = resources.getDimensionPixelSize(R.dimen.controls_card_margin)
val itemDecorator = MarginItemDecorator(margin, margin)
val layoutInflater = LayoutInflater.from(applicationContext)
@@ -156,14 +143,6 @@
}
addItemDecoration(itemDecorator)
}
-
- adapterFavorites = ControlAdapter(layoutInflater, true)
- recyclerViewFavorites = requireViewById<RecyclerView>(R.id.listFavorites).apply {
- layoutManager = GridLayoutManager(applicationContext, 2)
- adapter = adapterFavorites
- addItemDecoration(itemDecorator)
- }
- ItemTouchHelper(itemTouchHelperCallback).attachToRecyclerView(recyclerViewFavorites)
}
override fun onDestroy() {
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsModel.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsModel.kt
new file mode 100644
index 0000000..a995a2e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsModel.kt
@@ -0,0 +1,59 @@
+/*
+ * 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.systemui.controls.management
+
+import com.android.systemui.controls.ControlStatus
+import com.android.systemui.controls.controller.ControlInfo
+
+/**
+ * Model for using with [ControlAdapter].
+ *
+ * Implementations of this interface provide different views of the controls to show.
+ */
+interface ControlsModel {
+
+ /**
+ * List of favorites (builders) in order.
+ *
+ * This should be obtained prior to storing the favorites using
+ * [ControlsController.replaceFavoritesForComponent].
+ */
+ val favorites: List<ControlInfo.Builder>
+
+ /**
+ * List of all the elements to display by the corresponding [RecyclerView].
+ */
+ val elements: List<ElementWrapper>
+
+ /**
+ * Change the favorite status of a particular control.
+ */
+ fun changeFavoriteStatus(controlId: String, favorite: Boolean) {}
+
+ /**
+ * Move an item (in elements) from one position to another.
+ */
+ fun onMoveItem(from: Int, to: Int) {}
+}
+
+/**
+ * Wrapper classes for the different types of elements shown in the [RecyclerView]s in
+ * [ControlAdapter].
+ */
+sealed class ElementWrapper
+data class ZoneNameWrapper(val zoneName: CharSequence) : ElementWrapper()
+data class ControlWrapper(val controlStatus: ControlStatus) : ElementWrapper()
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt
index ad4bdef..098caf6 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt
@@ -21,6 +21,7 @@
import android.os.Bundle
import android.view.LayoutInflater
import android.view.ViewStub
+import android.widget.Button
import android.widget.TextView
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
@@ -86,6 +87,10 @@
requireViewById<TextView>(R.id.subtitle).text =
resources.getText(R.string.controls_providers_subtitle)
+ requireViewById<Button>(R.id.done).setOnClickListener {
+ this@ControlsProviderSelectorActivity.finishAffinity()
+ }
+
currentUserTracker.startTracking()
}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/FavoriteModel.kt b/packages/SystemUI/src/com/android/systemui/controls/management/FavoriteModel.kt
index 6bade0a..5c51e3d 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/FavoriteModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/FavoriteModel.kt
@@ -142,12 +142,4 @@
else if (p0 != null && p1 == null) return 1
return p0.toString().compareTo(p1.toString())
}
-}
-
-/**
- * Wrapper classes for the different types of elements shown in the [RecyclerView]s in
- * [ControlsFavoritingActivity].
- */
-sealed class ElementWrapper
-data class ZoneNameWrapper(val zoneName: CharSequence) : ElementWrapper()
-data class ControlWrapper(val controlStatus: ControlStatus) : ElementWrapper()
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
index 7c0033c..024378d 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
@@ -20,6 +20,7 @@
import android.app.INotificationManager;
import android.content.Context;
+import android.content.SharedPreferences;
import android.hardware.display.AmbientDisplayConfiguration;
import android.hardware.display.NightDisplayListener;
import android.os.Handler;
@@ -34,6 +35,7 @@
import com.android.internal.util.NotificationMessagingUtil;
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.ViewMediatorCallback;
+import com.android.systemui.Prefs;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.doze.AlwaysOnDisplayPolicy;
@@ -79,6 +81,13 @@
/** */
@Provides
+ @Main
+ public SharedPreferences provideSharePreferences(Context context) {
+ return Prefs.get(context);
+ }
+
+ /** */
+ @Provides
public AmbientDisplayConfiguration provideAmbientDispalyConfiguration(Context context) {
return new AmbientDisplayConfiguration(context);
}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemServicesModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemServicesModule.java
index 3aa14a3..352ee33 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemServicesModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemServicesModule.java
@@ -209,6 +209,7 @@
@Provides
@Singleton
+ @Nullable
static TelecomManager provideTelecomManager(Context context) {
return context.getSystemService(TelecomManager.class);
}
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index 5da02dc..24f505d 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -206,7 +206,7 @@
ConfigurationController configurationController, ActivityStarter activityStarter,
KeyguardStateController keyguardStateController, UserManager userManager,
TrustManager trustManager, IActivityManager iActivityManager,
- TelecomManager telecomManager, MetricsLogger metricsLogger,
+ @Nullable TelecomManager telecomManager, MetricsLogger metricsLogger,
BlurUtils blurUtils, SysuiColorExtractor colorExtractor,
IStatusBarService statusBarService,
NotificationShadeWindowController notificationShadeWindowController,
@@ -568,13 +568,16 @@
@Override
public void onPress() {
mMetricsLogger.action(MetricsEvent.ACTION_EMERGENCY_DIALER_FROM_POWER_MENU);
- Intent intent = mTelecomManager.createLaunchEmergencyDialerIntent(null /* number */);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
- | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
- | Intent.FLAG_ACTIVITY_CLEAR_TOP);
- intent.putExtra(EmergencyDialerConstants.EXTRA_ENTRY_TYPE,
- EmergencyDialerConstants.ENTRY_TYPE_POWER_MENU);
- mContext.startActivityAsUser(intent, UserHandle.CURRENT);
+ if (mTelecomManager != null) {
+ Intent intent = mTelecomManager.createLaunchEmergencyDialerIntent(
+ null /* number */);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
+ | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ intent.putExtra(EmergencyDialerConstants.EXTRA_ENTRY_TYPE,
+ EmergencyDialerConstants.ENTRY_TYPE_POWER_MENU);
+ mContext.startActivityAsUser(intent, UserHandle.CURRENT);
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
index ebf45a6..9f7b84a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
@@ -53,6 +53,7 @@
import com.android.systemui.R;
import com.android.systemui.SysUIToast;
import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.qs.DetailAdapter;
import com.android.systemui.plugins.qs.QSTile.BooleanState;
@@ -79,6 +80,7 @@
private final ZenModeController mController;
private final DndDetailAdapter mDetailAdapter;
private final ActivityStarter mActivityStarter;
+ private final SharedPreferences mSharedPreferences;
private final BroadcastDispatcher mBroadcastDispatcher;
private boolean mListening;
@@ -87,10 +89,12 @@
@Inject
public DndTile(QSHost host, ZenModeController zenModeController,
- ActivityStarter activityStarter, BroadcastDispatcher broadcastDispatcher) {
+ ActivityStarter activityStarter, BroadcastDispatcher broadcastDispatcher,
+ @Main SharedPreferences sharedPreferences) {
super(host);
mController = zenModeController;
mActivityStarter = activityStarter;
+ mSharedPreferences = sharedPreferences;
mDetailAdapter = new DndDetailAdapter();
mBroadcastDispatcher = broadcastDispatcher;
broadcastDispatcher.registerReceiver(mReceiver, new IntentFilter(ACTION_SET_VISIBLE));
@@ -111,16 +115,16 @@
Prefs.putBoolean(context, Prefs.Key.DND_TILE_VISIBLE, visible);
}
- public static boolean isVisible(Context context) {
- return Prefs.getBoolean(context, Prefs.Key.DND_TILE_VISIBLE, false /* defaultValue */);
+ public static boolean isVisible(SharedPreferences prefs) {
+ return prefs.getBoolean(Prefs.Key.DND_TILE_VISIBLE, false /* defaultValue */);
}
public static void setCombinedIcon(Context context, boolean combined) {
Prefs.putBoolean(context, Prefs.Key.DND_TILE_COMBINED_ICON, combined);
}
- public static boolean isCombinedIcon(Context context) {
- return Prefs.getBoolean(context, Prefs.Key.DND_TILE_COMBINED_ICON,
+ public static boolean isCombinedIcon(SharedPreferences sharedPreferences) {
+ return sharedPreferences.getBoolean(Prefs.Key.DND_TILE_COMBINED_ICON,
false /* defaultValue */);
}
@@ -301,7 +305,7 @@
@Override
public boolean isAvailable() {
- return isVisible(mContext);
+ return isVisible(mSharedPreferences);
}
private final OnSharedPreferenceChangeListener mPrefListener
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
index 2557226..5dcb4e3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
@@ -16,9 +16,9 @@
package com.android.systemui.qs.tiles;
-import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
+import android.content.res.Resources;
import android.provider.Settings;
import android.service.quicksettings.Tile;
import android.widget.Switch;
@@ -81,11 +81,11 @@
}
public static boolean isCurrentOrientationLockPortrait(RotationLockController controller,
- Context context) {
+ Resources resources) {
int lockOrientation = controller.getRotationLockOrientation();
if (lockOrientation == Configuration.ORIENTATION_UNDEFINED) {
// Freely rotating device; use current rotation
- return context.getResources().getConfiguration().orientation
+ return resources.getConfiguration().orientation
!= Configuration.ORIENTATION_LANDSCAPE;
} else {
return lockOrientation != Configuration.ORIENTATION_LANDSCAPE;
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index f06cd54..3afd5dc 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -514,12 +514,17 @@
1, cornerScale, mFastOutSlowIn.getInterpolation(t / scalePct));
mScreenshotView.setScaleX(scale);
mScreenshotView.setScaleY(scale);
+ } else {
+ mScreenshotView.setScaleX(cornerScale);
+ mScreenshotView.setScaleY(cornerScale);
}
if (t < xPositionPct) {
float xCenter = MathUtils.lerp(startPos.x, finalPos.x,
mFastOutSlowIn.getInterpolation(t / xPositionPct));
mScreenshotView.setX(xCenter - width * mScreenshotView.getScaleX() / 2f);
+ } else {
+ mScreenshotView.setX(finalPos.x - width * mScreenshotView.getScaleX() / 2f);
}
float yCenter = MathUtils.lerp(startPos.y, finalPos.y,
mFastOutSlowIn.getInterpolation(t));
@@ -544,6 +549,10 @@
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
+ mScreenshotView.setScaleX(cornerScale);
+ mScreenshotView.setScaleY(cornerScale);
+ mScreenshotView.setX(finalPos.x - height * cornerScale / 2f);
+ mScreenshotView.setY(finalPos.y - height * cornerScale / 2f);
Rect bounds = new Rect();
mScreenshotView.getBoundsOnScreen(bounds);
mDismissButton.setX(bounds.right - mDismissButtonSize / 2f);
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
index 56cdff4..27b799b 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
@@ -401,6 +401,7 @@
return;
}
mMinimized = minimized;
+ WindowManagerProxy.applyPrimaryFocusable(mSplits, !mMinimized);
mView.setMinimizedDockStack(minimized, getAnimDuration(), mHomeStackResizable);
updateTouchable();
});
@@ -504,6 +505,7 @@
final boolean wasMinimized = mMinimized;
mMinimized = true;
setHomeStackResizable(mSplits.mSecondary.isResizable());
+ WindowManagerProxy.applyPrimaryFocusable(mSplits, false /* focusable */);
if (!inSplitMode()) {
// Wasn't in split-mode yet, so enter now.
if (DEBUG) {
@@ -521,6 +523,9 @@
}
void ensureNormalSplit() {
+ if (mMinimized) {
+ WindowManagerProxy.applyPrimaryFocusable(mSplits, true /* focusable */);
+ }
if (!inSplitMode()) {
// Wasn't in split-mode, so enter now.
if (DEBUG) {
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java b/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java
index 7685733..167c33a 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java
@@ -292,10 +292,23 @@
for (int i = freeHomeAndRecents.size() - 1; i >= 0; --i) {
wct.setBounds(freeHomeAndRecents.get(i).token, null);
}
+ // Reset focusable to true
+ wct.setFocusable(tiles.mPrimary.token, true /* focusable */);
ActivityTaskManager.getTaskOrganizerController().applyContainerTransaction(wct,
null /* organizer */);
} catch (RemoteException e) {
Log.w(TAG, "Failed to remove stack: " + e);
}
}
+
+ static void applyPrimaryFocusable(SplitScreenTaskOrganizer splits, boolean focusable) {
+ try {
+ WindowContainerTransaction wct = new WindowContainerTransaction();
+ wct.setFocusable(splits.mPrimary.token, focusable);
+ ActivityTaskManager.getTaskOrganizerController().applyContainerTransaction(wct,
+ null /* organizer */);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Error setting focusability: " + e);
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java
index 8729e04..f38d416 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java
@@ -44,8 +44,9 @@
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.DragDownHelper;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
-import com.android.systemui.statusbar.PulseExpansionHandler;
import com.android.systemui.statusbar.NotificationShadeWindowBlurController;
+import com.android.systemui.statusbar.PulseExpansionHandler;
+import com.android.systemui.statusbar.SuperStatusBarViewFactory;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
@@ -91,6 +92,7 @@
private boolean mExpandAnimationRunning;
private NotificationStackScrollLayout mStackScrollLayout;
private PhoneStatusBarView mStatusBarView;
+ private PhoneStatusBarTransitions mBarTransitions;
private StatusBar mService;
private DragDownHelper mDragDownHelper;
private boolean mDoubleTapEnabled;
@@ -98,6 +100,7 @@
private boolean mExpandingBelowNotch;
private final DockManager mDockManager;
private final NotificationPanelViewController mNotificationPanelViewController;
+ private final SuperStatusBarViewFactory mStatusBarViewFactory;
// Used for determining view / touch intersection
private int[] mTempLocation = new int[2];
@@ -124,8 +127,9 @@
ShadeController shadeController,
DockManager dockManager,
@Nullable NotificationShadeWindowBlurController blurController,
- NotificationShadeWindowView statusBarWindowView,
- NotificationPanelViewController notificationPanelViewController) {
+ NotificationShadeWindowView notificationShadeWindowView,
+ NotificationPanelViewController notificationPanelViewController,
+ SuperStatusBarViewFactory statusBarViewFactory) {
mInjectionInflationController = injectionInflationController;
mCoordinator = coordinator;
mPulseExpansionHandler = pulseExpansionHandler;
@@ -141,11 +145,12 @@
mDozeLog = dozeLog;
mDozeParameters = dozeParameters;
mCommandQueue = commandQueue;
- mView = statusBarWindowView;
+ mView = notificationShadeWindowView;
mShadeController = shadeController;
mDockManager = dockManager;
mNotificationPanelViewController = notificationPanelViewController;
mBlurController = blurController;
+ mStatusBarViewFactory = statusBarViewFactory;
// This view is not part of the newly inflated expanded status bar.
mBrightnessMirror = mView.findViewById(R.id.brightness_mirror);
@@ -440,8 +445,18 @@
}
}
+ public PhoneStatusBarTransitions getBarTransitions() {
+ return mBarTransitions;
+ }
+
public void setStatusBarView(PhoneStatusBarView statusBarView) {
mStatusBarView = statusBarView;
+ if (statusBarView != null && mStatusBarViewFactory != null) {
+ mBarTransitions = new PhoneStatusBarTransitions(
+ statusBarView,
+ mStatusBarViewFactory.getStatusBarWindowView()
+ .findViewById(R.id.status_bar_container));
+ }
}
public void setService(StatusBar statusBar) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index 1ab36c5..14af466 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -16,15 +16,18 @@
package com.android.systemui.statusbar.phone;
-import android.app.ActivityManager;
+import android.annotation.Nullable;
import android.app.ActivityTaskManager;
import android.app.AlarmManager;
import android.app.AlarmManager.AlarmClockInfo;
+import android.app.IActivityManager;
import android.app.SynchronousUserSwitchObserver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.SharedPreferences;
+import android.content.res.Resources;
import android.media.AudioManager;
import android.os.Handler;
import android.os.RemoteException;
@@ -33,13 +36,13 @@
import android.provider.Settings.Global;
import android.service.notification.ZenModeConfig;
import android.telecom.TelecomManager;
-import android.telephony.TelephonyManager;
import android.text.format.DateFormat;
import android.util.Log;
-import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.dagger.qualifiers.DisplayId;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dagger.qualifiers.UiBackground;
import com.android.systemui.qs.tiles.DndTile;
import com.android.systemui.qs.tiles.RotationLockTile;
@@ -61,10 +64,13 @@
import com.android.systemui.statusbar.policy.SensorPrivacyController;
import com.android.systemui.statusbar.policy.UserInfoController;
import com.android.systemui.statusbar.policy.ZenModeController;
+import com.android.systemui.util.time.DateFormatUtil;
import java.util.Locale;
import java.util.concurrent.Executor;
+import javax.inject.Inject;
+
/**
* This class contains all of the policy about which icons are installed in the status bar at boot
* time. It goes through the normal API for icons, even though it probably strictly doesn't need to.
@@ -82,7 +88,7 @@
private static final String TAG = "PhoneStatusBarPolicy";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
- public static final int LOCATION_STATUS_ICON_ID =
+ static final int LOCATION_STATUS_ICON_ID =
com.android.internal.R.drawable.perm_group_location;
private final String mSlotCast;
@@ -97,20 +103,26 @@
private final String mSlotHeadset;
private final String mSlotDataSaver;
private final String mSlotLocation;
- private final String mSlotMicrophone;
- private final String mSlotCamera;
private final String mSlotSensorsOff;
private final String mSlotScreenRecord;
+ private final int mDisplayId;
+ private final SharedPreferences mSharedPreferences;
+ private final DateFormatUtil mDateFormatUtil;
+ private final TelecomManager mTelecomManager;
+ private final AudioManager mAudioManager;
- private final Context mContext;
private final Handler mHandler = new Handler();
private final CastController mCast;
private final HotspotController mHotspot;
private final NextAlarmController mNextAlarmController;
private final AlarmManager mAlarmManager;
private final UserInfoController mUserInfoController;
+ private final IActivityManager mIActivityManager;
private final UserManager mUserManager;
private final StatusBarIconController mIconController;
+ private final CommandQueue mCommandQueue;
+ private final BroadcastDispatcher mBroadcastDispatcher;
+ private final Resources mResources;
private final RotationLockController mRotationLockController;
private final DataSaverController mDataSaver;
private final ZenModeController mZenController;
@@ -121,10 +133,6 @@
private final SensorPrivacyController mSensorPrivacyController;
private final RecordingController mRecordingController;
- // Assume it's all good unless we hear otherwise. We don't always seem
- // to get broadcasts that it *is* there.
- int mSimState = TelephonyManager.SIM_STATE_READY;
-
private boolean mZenVisible;
private boolean mVolumeVisible;
private boolean mCurrentUserSetup;
@@ -134,47 +142,70 @@
private BluetoothController mBluetooth;
private AlarmManager.AlarmClockInfo mNextAlarm;
- public PhoneStatusBarPolicy(Context context, StatusBarIconController iconController,
+ @Inject
+ public PhoneStatusBarPolicy(StatusBarIconController iconController,
CommandQueue commandQueue, BroadcastDispatcher broadcastDispatcher,
- @UiBackground Executor uiBgExecutor) {
- mContext = context;
+ @UiBackground Executor uiBgExecutor, @Main Resources resources,
+ CastController castController, HotspotController hotspotController,
+ BluetoothController bluetoothController, NextAlarmController nextAlarmController,
+ UserInfoController userInfoController, RotationLockController rotationLockController,
+ DataSaverController dataSaverController, ZenModeController zenModeController,
+ DeviceProvisionedController deviceProvisionedController,
+ KeyguardStateController keyguardStateController,
+ LocationController locationController,
+ SensorPrivacyController sensorPrivacyController, IActivityManager iActivityManager,
+ AlarmManager alarmManager, UserManager userManager, AudioManager audioManager,
+ RecordingController recordingController,
+ @Nullable TelecomManager telecomManager, @DisplayId int displayId,
+ @Main SharedPreferences sharedPreferences, DateFormatUtil dateFormatUtil) {
mIconController = iconController;
- mCast = Dependency.get(CastController.class);
- mHotspot = Dependency.get(HotspotController.class);
- mBluetooth = Dependency.get(BluetoothController.class);
- mNextAlarmController = Dependency.get(NextAlarmController.class);
- mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
- mUserInfoController = Dependency.get(UserInfoController.class);
- mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
- mRotationLockController = Dependency.get(RotationLockController.class);
- mDataSaver = Dependency.get(DataSaverController.class);
- mZenController = Dependency.get(ZenModeController.class);
- mProvisionedController = Dependency.get(DeviceProvisionedController.class);
- mKeyguardStateController = Dependency.get(KeyguardStateController.class);
- mLocationController = Dependency.get(LocationController.class);
- mSensorPrivacyController = Dependency.get(SensorPrivacyController.class);
- mRecordingController = Dependency.get(RecordingController.class);
+ mCommandQueue = commandQueue;
+ mBroadcastDispatcher = broadcastDispatcher;
+ mResources = resources;
+ mCast = castController;
+ mHotspot = hotspotController;
+ mBluetooth = bluetoothController;
+ mNextAlarmController = nextAlarmController;
+ mAlarmManager = alarmManager;
+ mUserInfoController = userInfoController;
+ mIActivityManager = iActivityManager;
+ mUserManager = userManager;
+ mRotationLockController = rotationLockController;
+ mDataSaver = dataSaverController;
+ mZenController = zenModeController;
+ mProvisionedController = deviceProvisionedController;
+ mKeyguardStateController = keyguardStateController;
+ mLocationController = locationController;
+ mSensorPrivacyController = sensorPrivacyController;
+ mRecordingController = recordingController;
mUiBgExecutor = uiBgExecutor;
+ mAudioManager = audioManager;
+ mTelecomManager = telecomManager;
- mSlotCast = context.getString(com.android.internal.R.string.status_bar_cast);
- mSlotHotspot = context.getString(com.android.internal.R.string.status_bar_hotspot);
- mSlotBluetooth = context.getString(com.android.internal.R.string.status_bar_bluetooth);
- mSlotTty = context.getString(com.android.internal.R.string.status_bar_tty);
- mSlotZen = context.getString(com.android.internal.R.string.status_bar_zen);
- mSlotVolume = context.getString(com.android.internal.R.string.status_bar_volume);
- mSlotAlarmClock = context.getString(com.android.internal.R.string.status_bar_alarm_clock);
- mSlotManagedProfile = context.getString(
+ mSlotCast = resources.getString(com.android.internal.R.string.status_bar_cast);
+ mSlotHotspot = resources.getString(com.android.internal.R.string.status_bar_hotspot);
+ mSlotBluetooth = resources.getString(com.android.internal.R.string.status_bar_bluetooth);
+ mSlotTty = resources.getString(com.android.internal.R.string.status_bar_tty);
+ mSlotZen = resources.getString(com.android.internal.R.string.status_bar_zen);
+ mSlotVolume = resources.getString(com.android.internal.R.string.status_bar_volume);
+ mSlotAlarmClock = resources.getString(com.android.internal.R.string.status_bar_alarm_clock);
+ mSlotManagedProfile = resources.getString(
com.android.internal.R.string.status_bar_managed_profile);
- mSlotRotate = context.getString(com.android.internal.R.string.status_bar_rotate);
- mSlotHeadset = context.getString(com.android.internal.R.string.status_bar_headset);
- mSlotDataSaver = context.getString(com.android.internal.R.string.status_bar_data_saver);
- mSlotLocation = context.getString(com.android.internal.R.string.status_bar_location);
- mSlotMicrophone = context.getString(com.android.internal.R.string.status_bar_microphone);
- mSlotCamera = context.getString(com.android.internal.R.string.status_bar_camera);
- mSlotSensorsOff = context.getString(com.android.internal.R.string.status_bar_sensors_off);
- mSlotScreenRecord = context.getString(
+ mSlotRotate = resources.getString(com.android.internal.R.string.status_bar_rotate);
+ mSlotHeadset = resources.getString(com.android.internal.R.string.status_bar_headset);
+ mSlotDataSaver = resources.getString(com.android.internal.R.string.status_bar_data_saver);
+ mSlotLocation = resources.getString(com.android.internal.R.string.status_bar_location);
+ mSlotSensorsOff = resources.getString(com.android.internal.R.string.status_bar_sensors_off);
+ mSlotScreenRecord = resources.getString(
com.android.internal.R.string.status_bar_screen_record);
+ mDisplayId = displayId;
+ mSharedPreferences = sharedPreferences;
+ mDateFormatUtil = dateFormatUtil;
+ }
+
+ /** Initialize the object after construction. */
+ public void init() {
// listen for broadcasts
IntentFilter filter = new IntentFilter();
filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
@@ -185,11 +216,11 @@
filter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE);
filter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE);
filter.addAction(Intent.ACTION_MANAGED_PROFILE_REMOVED);
- broadcastDispatcher.registerReceiverWithHandler(mIntentReceiver, filter, mHandler);
+ mBroadcastDispatcher.registerReceiverWithHandler(mIntentReceiver, filter, mHandler);
// listen for user / profile change.
try {
- ActivityManager.getService().registerUserSwitchObserver(mUserSwitchListener, TAG);
+ mIActivityManager.registerUserSwitchObserver(mUserSwitchListener, TAG);
} catch (RemoteException e) {
// Ignore
}
@@ -219,26 +250,26 @@
// hotspot
mIconController.setIcon(mSlotHotspot, R.drawable.stat_sys_hotspot,
- mContext.getString(R.string.accessibility_status_bar_hotspot));
+ mResources.getString(R.string.accessibility_status_bar_hotspot));
mIconController.setIconVisibility(mSlotHotspot, mHotspot.isHotspotEnabled());
// managed profile
mIconController.setIcon(mSlotManagedProfile, R.drawable.stat_sys_managed_profile_status,
- mContext.getString(R.string.accessibility_managed_profile));
+ mResources.getString(R.string.accessibility_managed_profile));
mIconController.setIconVisibility(mSlotManagedProfile, mManagedProfileIconVisible);
// data saver
mIconController.setIcon(mSlotDataSaver, R.drawable.stat_sys_data_saver,
- context.getString(R.string.accessibility_data_saver_on));
+ mResources.getString(R.string.accessibility_data_saver_on));
mIconController.setIconVisibility(mSlotDataSaver, false);
mIconController.setIcon(mSlotLocation, LOCATION_STATUS_ICON_ID,
- mContext.getString(R.string.accessibility_location_active));
+ mResources.getString(R.string.accessibility_location_active));
mIconController.setIconVisibility(mSlotLocation, false);
// sensors off
mIconController.setIcon(mSlotSensorsOff, R.drawable.stat_sys_sensors_off,
- mContext.getString(R.string.accessibility_sensors_off_active));
+ mResources.getString(R.string.accessibility_sensors_off_active));
mIconController.setIconVisibility(mSlotSensorsOff,
mSensorPrivacyController.isSensorPrivacyEnabled());
@@ -259,7 +290,7 @@
mLocationController.addCallback(this);
mRecordingController.addCallback(this);
- commandQueue.addCallback(this);
+ mCommandQueue.addCallback(this);
}
@Override
@@ -284,51 +315,17 @@
private String buildAlarmContentDescription() {
if (mNextAlarm == null) {
- return mContext.getString(R.string.status_bar_alarm);
+ return mResources.getString(R.string.status_bar_alarm);
}
- return formatNextAlarm(mNextAlarm, mContext);
- }
- private static String formatNextAlarm(AlarmManager.AlarmClockInfo info, Context context) {
- if (info == null) {
- return "";
- }
- String skeleton = DateFormat.is24HourFormat(
- context, ActivityManager.getCurrentUser()) ? "EHm" : "Ehma";
+ String skeleton = mDateFormatUtil.is24HourFormat() ? "EHm" : "Ehma";
String pattern = DateFormat.getBestDateTimePattern(Locale.getDefault(), skeleton);
- String dateString = DateFormat.format(pattern, info.getTriggerTime()).toString();
+ String dateString = DateFormat.format(pattern, mNextAlarm.getTriggerTime()).toString();
- return context.getString(R.string.accessibility_quick_settings_alarm, dateString);
- }
-
- private final void updateSimState(Intent intent) {
- String stateExtra = intent.getStringExtra(Intent.EXTRA_SIM_STATE);
- if (Intent.SIM_STATE_ABSENT.equals(stateExtra)) {
- mSimState = TelephonyManager.SIM_STATE_READY;
- } else if (Intent.SIM_STATE_CARD_IO_ERROR.equals(stateExtra)) {
- mSimState = TelephonyManager.SIM_STATE_CARD_IO_ERROR;
- } else if (Intent.SIM_STATE_CARD_RESTRICTED.equals(stateExtra)) {
- mSimState = TelephonyManager.SIM_STATE_CARD_RESTRICTED;
- } else if (Intent.SIM_STATE_READY.equals(stateExtra)) {
- mSimState = TelephonyManager.SIM_STATE_READY;
- } else if (Intent.SIM_STATE_LOCKED.equals(stateExtra)) {
- final String lockedReason =
- intent.getStringExtra(Intent.EXTRA_SIM_LOCKED_REASON);
- if (Intent.SIM_LOCKED_ON_PIN.equals(lockedReason)) {
- mSimState = TelephonyManager.SIM_STATE_PIN_REQUIRED;
- } else if (Intent.SIM_LOCKED_ON_PUK.equals(lockedReason)) {
- mSimState = TelephonyManager.SIM_STATE_PUK_REQUIRED;
- } else {
- mSimState = TelephonyManager.SIM_STATE_NETWORK_LOCKED;
- }
- } else {
- mSimState = TelephonyManager.SIM_STATE_UNKNOWN;
- }
+ return mResources.getString(R.string.accessibility_quick_settings_alarm, dateString);
}
private final void updateVolumeZen() {
- AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
-
boolean zenVisible = false;
int zenIconId = 0;
String zenDescription = null;
@@ -338,29 +335,29 @@
String volumeDescription = null;
int zen = mZenController.getZen();
- if (DndTile.isVisible(mContext) || DndTile.isCombinedIcon(mContext)) {
+ if (DndTile.isVisible(mSharedPreferences) || DndTile.isCombinedIcon(mSharedPreferences)) {
zenVisible = zen != Global.ZEN_MODE_OFF;
zenIconId = R.drawable.stat_sys_dnd;
- zenDescription = mContext.getString(R.string.quick_settings_dnd_label);
+ zenDescription = mResources.getString(R.string.quick_settings_dnd_label);
} else if (zen == Global.ZEN_MODE_NO_INTERRUPTIONS) {
zenVisible = true;
zenIconId = R.drawable.stat_sys_dnd;
- zenDescription = mContext.getString(R.string.interruption_level_none);
+ zenDescription = mResources.getString(R.string.interruption_level_none);
} else if (zen == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) {
zenVisible = true;
zenIconId = R.drawable.stat_sys_dnd;
- zenDescription = mContext.getString(R.string.interruption_level_priority);
+ zenDescription = mResources.getString(R.string.interruption_level_priority);
}
if (!ZenModeConfig.isZenOverridingRinger(zen, mZenController.getConsolidatedPolicy())) {
- if (audioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_VIBRATE) {
+ if (mAudioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_VIBRATE) {
volumeVisible = true;
volumeIconId = R.drawable.stat_sys_ringer_vibrate;
- volumeDescription = mContext.getString(R.string.accessibility_ringer_vibrate);
- } else if (audioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_SILENT) {
+ volumeDescription = mResources.getString(R.string.accessibility_ringer_vibrate);
+ } else if (mAudioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_SILENT) {
volumeVisible = true;
volumeIconId = R.drawable.stat_sys_ringer_silent;
- volumeDescription = mContext.getString(R.string.accessibility_ringer_silent);
+ volumeDescription = mResources.getString(R.string.accessibility_ringer_silent);
}
}
@@ -395,13 +392,13 @@
private final void updateBluetooth() {
int iconId = R.drawable.stat_sys_data_bluetooth_connected;
String contentDescription =
- mContext.getString(R.string.accessibility_quick_settings_bluetooth_on);
+ mResources.getString(R.string.accessibility_quick_settings_bluetooth_on);
boolean bluetoothVisible = false;
if (mBluetooth != null) {
if (mBluetooth.isBluetoothConnected()
&& (mBluetooth.isBluetoothAudioActive()
|| !mBluetooth.isBluetoothAudioProfileOnly())) {
- contentDescription = mContext.getString(
+ contentDescription = mResources.getString(
R.string.accessibility_bluetooth_connected);
bluetoothVisible = mBluetooth.isBluetoothEnabled();
}
@@ -412,12 +409,10 @@
}
private final void updateTTY() {
- TelecomManager telecomManager =
- (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
- if (telecomManager == null) {
+ if (mTelecomManager == null) {
updateTTY(TelecomManager.TTY_MODE_OFF);
} else {
- updateTTY(telecomManager.getCurrentTtyMode());
+ updateTTY(mTelecomManager.getCurrentTtyMode());
}
}
@@ -430,7 +425,7 @@
// TTY is on
if (DEBUG) Log.v(TAG, "updateTTY: set TTY on");
mIconController.setIcon(mSlotTty, R.drawable.stat_sys_tty_mode,
- mContext.getString(R.string.accessibility_tty_enabled));
+ mResources.getString(R.string.accessibility_tty_enabled));
mIconController.setIconVisibility(mSlotTty, true);
} else {
// TTY is off
@@ -452,7 +447,7 @@
mHandler.removeCallbacks(mRemoveCastIconRunnable);
if (isCasting && !mRecordingController.isRecording()) { // screen record has its own icon
mIconController.setIcon(mSlotCast, R.drawable.stat_sys_cast,
- mContext.getString(R.string.accessibility_casting));
+ mResources.getString(R.string.accessibility_casting));
mIconController.setIconVisibility(mSlotCast, true);
} else {
// don't turn off the screen-record icon for a few seconds, just to make sure the user
@@ -478,7 +473,7 @@
showIcon = true;
mIconController.setIcon(mSlotManagedProfile,
R.drawable.stat_sys_managed_profile_status,
- mContext.getString(R.string.accessibility_managed_profile));
+ mResources.getString(R.string.accessibility_managed_profile));
} else {
showIcon = false;
}
@@ -545,7 +540,7 @@
@Override
public void appTransitionStarting(int displayId, long startTime, long duration,
boolean forced) {
- if (mContext.getDisplayId() == displayId) {
+ if (mDisplayId == displayId) {
updateManagedProfile();
}
}
@@ -567,14 +562,14 @@
@Override
public void onRotationLockStateChanged(boolean rotationLocked, boolean affordanceVisible) {
boolean portrait = RotationLockTile.isCurrentOrientationLockPortrait(
- mRotationLockController, mContext);
+ mRotationLockController, mResources);
if (rotationLocked) {
if (portrait) {
mIconController.setIcon(mSlotRotate, R.drawable.stat_sys_rotate_portrait,
- mContext.getString(R.string.accessibility_rotation_lock_on_portrait));
+ mResources.getString(R.string.accessibility_rotation_lock_on_portrait));
} else {
mIconController.setIcon(mSlotRotate, R.drawable.stat_sys_rotate_landscape,
- mContext.getString(R.string.accessibility_rotation_lock_on_landscape));
+ mResources.getString(R.string.accessibility_rotation_lock_on_landscape));
}
mIconController.setIconVisibility(mSlotRotate, true);
} else {
@@ -586,7 +581,7 @@
boolean connected = intent.getIntExtra("state", 0) != 0;
boolean hasMic = intent.getIntExtra("microphone", 0) != 0;
if (connected) {
- String contentDescription = mContext.getString(hasMic
+ String contentDescription = mResources.getString(hasMic
? R.string.accessibility_status_bar_headset
: R.string.accessibility_status_bar_headphones);
mIconController.setIcon(mSlotHeadset, hasMic ? R.drawable.stat_sys_headset_mic
@@ -630,7 +625,6 @@
if (intent.getBooleanExtra(Intent.EXTRA_REBROADCAST_ON_UNLOCK, false)) {
break;
}
- updateSimState(intent);
break;
case TelecomManager.ACTION_CURRENT_TTY_MODE_CHANGED:
updateTTY(intent.getIntExtra(TelecomManager.EXTRA_CURRENT_TTY_MODE,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java
index e8bc2f5..2052ee6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java
@@ -29,23 +29,21 @@
private static final float ICON_ALPHA_WHEN_LIGHTS_OUT_BATTERY_CLOCK = 0.5f;
private static final float ICON_ALPHA_WHEN_LIGHTS_OUT_NON_BATTERY_CLOCK = 0;
- private final PhoneStatusBarView mView;
private final float mIconAlphaWhenOpaque;
- private View mLeftSide, mStatusIcons, mBattery, mClock;
+ private View mLeftSide, mStatusIcons, mBattery;
private Animator mCurrentAnimation;
- public PhoneStatusBarTransitions(PhoneStatusBarView view) {
- super(view, R.drawable.status_background);
- mView = view;
- final Resources res = mView.getContext().getResources();
+ /**
+ * @param backgroundView view to apply the background drawable
+ */
+ public PhoneStatusBarTransitions(PhoneStatusBarView statusBarView, View backgroundView) {
+ super(backgroundView, R.drawable.status_background);
+ final Resources res = statusBarView.getContext().getResources();
mIconAlphaWhenOpaque = res.getFraction(R.dimen.status_bar_icon_drawing_alpha, 1, 1);
- }
-
- public void init() {
- mLeftSide = mView.findViewById(R.id.status_bar_left_side);
- mStatusIcons = mView.findViewById(R.id.statusIcons);
- mBattery = mView.findViewById(R.id.battery);
+ mLeftSide = statusBarView.findViewById(R.id.status_bar_left_side);
+ mStatusIcons = statusBarView.findViewById(R.id.statusIcons);
+ mBattery = statusBarView.findViewById(R.id.battery);
applyModeBackground(-1, getMode(), false /*animate*/);
applyMode(getMode(), false /*animate*/);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
index b949e3a..1359f74 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
@@ -53,7 +53,6 @@
StatusBar mBar;
boolean mIsFullyOpenedPanel = false;
- private final PhoneStatusBarTransitions mBarTransitions;
private ScrimController mScrimController;
private float mMinFraction;
private Runnable mHideExpandedRunnable = new Runnable() {
@@ -83,15 +82,9 @@
public PhoneStatusBarView(Context context, AttributeSet attrs) {
super(context, attrs);
-
- mBarTransitions = new PhoneStatusBarTransitions(this);
mCommandQueue = Dependency.get(CommandQueue.class);
}
- public BarTransitions getBarTransitions() {
- return mBarTransitions;
- }
-
public void setBar(StatusBar bar) {
mBar = bar;
}
@@ -102,7 +95,6 @@
@Override
public void onFinishInflate() {
- mBarTransitions.init();
mBattery = findViewById(R.id.battery);
mCutoutSpace = findViewById(R.id.cutout_space_view);
mCenterIconSpace = findViewById(R.id.centered_icon_area);
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 0d3b09a..b620d17 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -676,6 +676,7 @@
KeyguardDismissUtil keyguardDismissUtil,
ExtensionController extensionController,
UserInfoControllerImpl userInfoControllerImpl,
+ PhoneStatusBarPolicy phoneStatusBarPolicy,
DismissCallbackRegistry dismissCallbackRegistry,
StatusBarTouchableRegionManager statusBarTouchableRegionManager) {
super(context);
@@ -751,6 +752,7 @@
mKeyguardDismissUtil = keyguardDismissUtil;
mExtensionController = extensionController;
mUserInfoControllerImpl = userInfoControllerImpl;
+ mIconPolicy = phoneStatusBarPolicy;
mDismissCallbackRegistry = dismissCallbackRegistry;
mBubbleExpandListener =
@@ -875,8 +877,7 @@
// end old BaseStatusBar.start().
// Lastly, call to the icon policy to install/update all the icons.
- mIconPolicy = new PhoneStatusBarPolicy(mContext, mIconController, mCommandQueue,
- mBroadcastDispatcher, mUiBgExecutor);
+ mIconPolicy.init();
mSignalPolicy = new StatusBarSignalPolicy(mContext, mIconController);
mKeyguardStateController.addCallback(this);
@@ -2305,13 +2306,14 @@
}
protected BarTransitions getStatusBarTransitions() {
- return mStatusBarView.getBarTransitions();
+ return mNotificationShadeWindowViewController.getBarTransitions();
}
void checkBarModes() {
if (mDemoMode) return;
- if (mStatusBarView != null) checkBarMode(mStatusBarMode, mStatusBarWindowState,
- getStatusBarTransitions());
+ if (mNotificationShadeWindowViewController != null) {
+ checkBarMode(mStatusBarMode, mStatusBarWindowState, getStatusBarTransitions());
+ }
mNavigationBarController.checkNavBarModes(mDisplayId);
mNoAnimationOnNextBarModeChange = false;
}
@@ -2329,8 +2331,9 @@
}
private void finishBarAnimations() {
- if (mStatusBarView != null) {
- mStatusBarView.getBarTransitions().finishAnimations();
+ if (mNotificationShadeWindowController != null
+ && mNotificationShadeWindowViewController.getBarTransitions() != null) {
+ mNotificationShadeWindowViewController.getBarTransitions().finishAnimations();
}
mNavigationBarController.finishBarAnimations(mDisplayId);
}
@@ -2396,12 +2399,11 @@
pw.print(" mDozing="); pw.println(mDozing);
pw.print(" mWallpaperSupported= "); pw.println(mWallpaperSupported);
- if (mStatusBarView != null) {
- dumpBarTransitions(pw, "mStatusBarView", mStatusBarView.getBarTransitions());
- }
pw.println(" StatusBarWindowView: ");
if (mNotificationShadeWindowViewController != null) {
mNotificationShadeWindowViewController.dump(fd, pw, args);
+ dumpBarTransitions(pw, "PhoneStatusBarTransitions",
+ mNotificationShadeWindowViewController.getBarTransitions());
}
pw.println(" mMediaManager: ");
@@ -3004,8 +3006,10 @@
-1;
if (barMode != -1) {
boolean animate = true;
- if (mStatusBarView != null) {
- mStatusBarView.getBarTransitions().transitionTo(barMode, animate);
+ if (mNotificationShadeWindowController != null
+ && mNotificationShadeWindowViewController.getBarTransitions() != null) {
+ mNotificationShadeWindowViewController.getBarTransitions().transitionTo(
+ barMode, animate);
}
mNavigationBarController.transitionTo(mDisplayId, barMode, animate);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
index e64f821..0a4fdc9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
@@ -79,6 +79,7 @@
import com.android.systemui.statusbar.phone.LockscreenWallpaper;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
import com.android.systemui.statusbar.phone.NotificationShadeWindowController;
+import com.android.systemui.statusbar.phone.PhoneStatusBarPolicy;
import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.statusbar.phone.ShadeController;
import com.android.systemui.statusbar.phone.StatusBar;
@@ -193,6 +194,7 @@
KeyguardDismissUtil keyguardDismissUtil,
ExtensionController extensionController,
UserInfoControllerImpl userInfoControllerImpl,
+ PhoneStatusBarPolicy phoneStatusBarPolicy,
DismissCallbackRegistry dismissCallbackRegistry,
StatusBarTouchableRegionManager statusBarTouchableRegionManager) {
return new StatusBar(
@@ -269,6 +271,7 @@
keyguardDismissUtil,
extensionController,
userInfoControllerImpl,
+ phoneStatusBarPolicy,
dismissCallbackRegistry,
statusBarTouchableRegionManager);
}
diff --git a/packages/SystemUI/src/com/android/systemui/util/sensors/ProximitySensor.java b/packages/SystemUI/src/com/android/systemui/util/sensors/ProximitySensor.java
index b5bede4..13ba1a3c 100644
--- a/packages/SystemUI/src/com/android/systemui/util/sensors/ProximitySensor.java
+++ b/packages/SystemUI/src/com/android/systemui/util/sensors/ProximitySensor.java
@@ -40,12 +40,11 @@
*/
public class ProximitySensor {
private static final String TAG = "ProxSensor";
- private static final boolean DEBUG = false;
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
private final Sensor mSensor;
private final AsyncSensorManager mSensorManager;
- private final boolean mUsingBrightnessSensor;
- private final float mMaxRange;
+ private final float mThreshold;
private List<ProximitySensorListener> mListeners = new ArrayList<>();
private String mTag = null;
@VisibleForTesting ProximityEvent mLastEvent;
@@ -68,20 +67,27 @@
public ProximitySensor(@Main Resources resources,
AsyncSensorManager sensorManager) {
mSensorManager = sensorManager;
- Sensor sensor = findBrightnessSensor(resources);
+ Sensor sensor = findCustomProxSensor(resources);
+ float threshold = 0;
+ if (sensor != null) {
+ try {
+ threshold = getCustomProxThreshold(resources);
+ } catch (IllegalStateException e) {
+ Log.e(TAG, "Can not load custom proximity sensor.", e);
+ sensor = null;
+ }
+ }
if (sensor == null) {
- mUsingBrightnessSensor = false;
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
- } else {
- mUsingBrightnessSensor = true;
+ if (sensor != null) {
+ threshold = sensor.getMaximumRange();
+ }
}
+
+ mThreshold = threshold;
+
mSensor = sensor;
- if (mSensor != null) {
- mMaxRange = mSensor.getMaximumRange();
- } else {
- mMaxRange = 0;
- }
}
public void setTag(String tag) {
@@ -107,9 +113,15 @@
mPaused = false;
registerInternal();
}
+ /**
+ * Returns a brightness sensor that can be used for proximity purposes.
+ */
+ private Sensor findCustomProxSensor(Resources resources) {
+ String sensorType = resources.getString(R.string.proximity_sensor_type);
+ if (sensorType.isEmpty()) {
+ return null;
+ }
- private Sensor findBrightnessSensor(Resources resources) {
- String sensorType = resources.getString(R.string.doze_brightness_sensor_type);
List<Sensor> sensorList = mSensorManager.getSensorList(Sensor.TYPE_ALL);
Sensor sensor = null;
for (Sensor s : sensorList) {
@@ -123,6 +135,17 @@
}
/**
+ * Returns a threshold value that can be used along with {@link #findCustomProxSensor}
+ */
+ private float getCustomProxThreshold(Resources resources) {
+ try {
+ return resources.getFloat(R.dimen.proximity_sensor_threshold);
+ } catch (Resources.NotFoundException e) {
+ throw new IllegalStateException("R.dimen.proximity_sensor_threshold must be set.");
+ }
+ }
+
+ /**
* Returns true if we are registered with the SensorManager.
*/
public boolean isRegistered() {
@@ -157,7 +180,6 @@
if (mRegistered || mPaused || mListeners.isEmpty()) {
return;
}
- logDebug("Using brightness sensor? " + mUsingBrightnessSensor);
logDebug("Registering sensor listener");
mRegistered = true;
mSensorManager.registerListener(mSensorEventListener, mSensor, mSensorDelay);
@@ -196,10 +218,7 @@
}
private void onSensorEvent(SensorEvent event) {
- boolean near = event.values[0] < mMaxRange;
- if (mUsingBrightnessSensor) {
- near = event.values[0] == 0;
- }
+ boolean near = event.values[0] < mThreshold;
mLastEvent = new ProximityEvent(near, event.timestamp);
alertListeners();
}
diff --git a/packages/SystemUI/src/com/android/systemui/util/time/DateFormatUtil.java b/packages/SystemUI/src/com/android/systemui/util/time/DateFormatUtil.java
new file mode 100644
index 0000000..d7c4e93
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/time/DateFormatUtil.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2020 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.systemui.util.time;
+
+import android.app.ActivityManager;
+import android.content.Context;
+import android.text.format.DateFormat;
+
+import javax.inject.Inject;
+
+/**
+ * Instantiable wrapper around {@link DateFormat}.
+ */
+public class DateFormatUtil {
+ private final Context mContext;
+
+ @Inject
+ public DateFormatUtil(Context context) {
+ mContext = context;
+ }
+
+ /** Returns true if the phone is in 24 hour format. */
+ public boolean is24HourFormat() {
+ return DateFormat.is24HourFormat(mContext, ActivityManager.getCurrentUser());
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ImageWallpaperTest.java b/packages/SystemUI/tests/src/com/android/systemui/ImageWallpaperTest.java
index 689eed9..678cfd2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/ImageWallpaperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/ImageWallpaperTest.java
@@ -34,6 +34,7 @@
import android.graphics.ColorSpace;
import android.graphics.Rect;
import android.hardware.display.DisplayManagerGlobal;
+import android.os.Handler;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
@@ -72,6 +73,8 @@
private Bitmap mWallpaperBitmap;
@Mock
private DozeParameters mDozeParam;
+ @Mock
+ private Handler mHandler;
private CountDownLatch mEventCountdown;
@@ -104,7 +107,7 @@
return new ImageWallpaper(mDozeParam) {
@Override
public Engine onCreateEngine() {
- return new GLEngine(mMockContext, mDozeParam) {
+ return new GLEngine(mDozeParam, mHandler) {
@Override
public Context getDisplayContext() {
return mMockContext;
@@ -196,5 +199,6 @@
when(mSurfaceHolder.getSurfaceFrame()).thenReturn(frame);
assertThat(engineSpy.checkIfShouldStopTransition()).isEqualTo(assertion);
+ // destroy
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
index 7ac5443..a36f2c7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
@@ -86,7 +86,9 @@
public void SysuiTeardown() {
InstrumentationRegistry.registerInstance(mRealInstrumentation,
InstrumentationRegistry.getArguments());
- // Reset the assert's testable looper to null.
+ if (TestableLooper.get(this) != null) {
+ TestableLooper.get(this).processAllMessages();
+ }
disallowTestableLooperAsMainThread();
SystemUIFactory.cleanup();
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingManagerProxyTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingManagerProxyTest.java
index 545d2d4..5b78067 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingManagerProxyTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingManagerProxyTest.java
@@ -33,7 +33,9 @@
import com.android.systemui.dock.DockManager;
import com.android.systemui.dock.DockManagerFake;
import com.android.systemui.dump.DumpManager;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.shared.plugins.PluginManager;
+import com.android.systemui.statusbar.StatusBarStateControllerImpl;
import com.android.systemui.util.DeviceConfigProxy;
import com.android.systemui.util.DeviceConfigProxyFake;
import com.android.systemui.util.concurrency.FakeExecutor;
@@ -63,6 +65,7 @@
private FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock());
private DockManager mDockManager = new DockManagerFake();
+ private StatusBarStateController mStatusBarStateController = new StatusBarStateControllerImpl();
@Before
public void setup() {
@@ -83,7 +86,7 @@
public void test_brightLineFalsingManagerDisabled() {
mProxy = new FalsingManagerProxy(getContext(), mPluginManager, mExecutor, mDisplayMetrics,
mProximitySensor, mDeviceConfig, mDockManager, mKeyguardUpdateMonitor,
- mDumpManager, mUiBgExecutor);
+ mDumpManager, mUiBgExecutor, mStatusBarStateController);
assertThat(mProxy.getInternalFalsingManager(), instanceOf(FalsingManagerImpl.class));
}
@@ -94,7 +97,7 @@
mExecutor.runAllReady();
mProxy = new FalsingManagerProxy(getContext(), mPluginManager, mExecutor, mDisplayMetrics,
mProximitySensor, mDeviceConfig, mDockManager, mKeyguardUpdateMonitor,
- mDumpManager, mUiBgExecutor);
+ mDumpManager, mUiBgExecutor, mStatusBarStateController);
assertThat(mProxy.getInternalFalsingManager(), instanceOf(BrightLineFalsingManager.class));
}
@@ -102,7 +105,7 @@
public void test_brightLineFalsingManagerToggled() throws InterruptedException {
mProxy = new FalsingManagerProxy(getContext(), mPluginManager, mExecutor, mDisplayMetrics,
mProximitySensor, mDeviceConfig, mDockManager, mKeyguardUpdateMonitor,
- mDumpManager, mUiBgExecutor);
+ mDumpManager, mUiBgExecutor, mStatusBarStateController);
assertThat(mProxy.getInternalFalsingManager(), instanceOf(FalsingManagerImpl.class));
mDeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/BrightLineFalsingManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/BrightLineFalsingManagerTest.java
index 0aaa3b6..8b5cc9a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/BrightLineFalsingManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/BrightLineFalsingManagerTest.java
@@ -22,12 +22,16 @@
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
import android.util.DisplayMetrics;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.dock.DockManager;
import com.android.systemui.dock.DockManagerFake;
+import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.StatusBarStateControllerImpl;
+import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.util.DeviceConfigProxy;
import com.android.systemui.util.DeviceConfigProxyFake;
import com.android.systemui.util.sensors.ProximitySensor;
@@ -40,6 +44,7 @@
@SmallTest
@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
public class BrightLineFalsingManagerTest extends SysuiTestCase {
@@ -47,6 +52,7 @@
private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@Mock
private ProximitySensor mProximitySensor;
+ private SysuiStatusBarStateController mStatusBarStateController;
private BrightLineFalsingManager mFalsingManager;
@@ -61,8 +67,11 @@
FalsingDataProvider falsingDataProvider = new FalsingDataProvider(dm);
DeviceConfigProxy deviceConfigProxy = new DeviceConfigProxyFake();
DockManager dockManager = new DockManagerFake();
+ mStatusBarStateController = new StatusBarStateControllerImpl();
+ mStatusBarStateController.setState(StatusBarState.KEYGUARD);
mFalsingManager = new BrightLineFalsingManager(falsingDataProvider,
- mKeyguardUpdateMonitor, mProximitySensor, deviceConfigProxy, dockManager);
+ mKeyguardUpdateMonitor, mProximitySensor, deviceConfigProxy, dockManager,
+ mStatusBarStateController);
}
@Test
@@ -98,4 +107,12 @@
mFalsingManager.onBouncerHidden();
verify(mProximitySensor).register(any(ProximitySensor.ProximitySensorListener.class));
}
+
+ @Test
+ public void testUnregisterSensor_StateTransition() {
+ mFalsingManager.onScreenTurningOn();
+ reset(mProximitySensor);
+ mStatusBarStateController.setState(StatusBarState.SHADE);
+ verify(mProximitySensor).unregister(any(ProximitySensor.ProximitySensorListener.class));
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/management/AllModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/management/AllModelTest.kt
new file mode 100644
index 0000000..68e1ec1
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/management/AllModelTest.kt
@@ -0,0 +1,192 @@
+/*
+ * 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.systemui.controls.management
+
+import android.app.PendingIntent
+import android.service.controls.Control
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.controls.ControlStatus
+import com.android.systemui.controls.controller.ControlInfo
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertTrue
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class AllModelTest : SysuiTestCase() {
+
+ companion object {
+ private const val EMPTY_STRING = "Other"
+ }
+
+ @Mock
+ lateinit var pendingIntent: PendingIntent
+
+ val idPrefix = "controlId"
+ val favoritesIndices = listOf(7, 3, 1, 9)
+ val favoritesList = favoritesIndices.map { "controlId$it" }
+ lateinit var controls: List<ControlStatus>
+
+ lateinit var model: AllModel
+
+ private fun zoneMap(id: Int): String? {
+ return when (id) {
+ 10 -> ""
+ 11 -> null
+ else -> ((id + 1) % 3).toString()
+ }
+ }
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+
+ // controlId0 --> zone = 1
+ // controlId1 --> zone = 2, favorite
+ // controlId2 --> zone = 0
+ // controlId3 --> zone = 1, favorite
+ // controlId4 --> zone = 2
+ // controlId5 --> zone = 0
+ // controlId6 --> zone = 1
+ // controlId7 --> zone = 2, favorite
+ // controlId8 --> zone = 0
+ // controlId9 --> zone = 1, favorite
+ // controlId10 --> zone = ""
+ // controlId11 --> zone = null
+ controls = (0..11).map {
+ ControlStatus(
+ Control.StatelessBuilder("$idPrefix$it", pendingIntent)
+ .setZone(zoneMap(it))
+ .build(),
+ it in favoritesIndices
+ )
+ }
+ model = AllModel(controls, favoritesList, EMPTY_STRING)
+ }
+
+ @Test
+ fun testElements() {
+
+ // Zones are sorted by order of appearance, with empty at the end with special header.
+ val expected = listOf(
+ ZoneNameWrapper("1"),
+ ControlWrapper(controls[0]),
+ ControlWrapper(controls[3]),
+ ControlWrapper(controls[6]),
+ ControlWrapper(controls[9]),
+ ZoneNameWrapper("2"),
+ ControlWrapper(controls[1]),
+ ControlWrapper(controls[4]),
+ ControlWrapper(controls[7]),
+ ZoneNameWrapper("0"),
+ ControlWrapper(controls[2]),
+ ControlWrapper(controls[5]),
+ ControlWrapper(controls[8]),
+ ZoneNameWrapper(EMPTY_STRING),
+ ControlWrapper(controls[10]),
+ ControlWrapper(controls[11])
+ )
+ expected.zip(model.elements).forEachIndexed { index, it ->
+ assertEquals("Error in item at index $index", it.first, it.second)
+ }
+ }
+
+ private fun sameControl(controlInfo: ControlInfo.Builder, control: Control): Boolean {
+ return controlInfo.controlId == control.controlId &&
+ controlInfo.controlTitle == control.title &&
+ controlInfo.deviceType == control.deviceType
+ }
+
+ @Test
+ fun testAllEmpty_noHeader() {
+ val selected_controls = listOf(controls[10], controls[11])
+ val new_model = AllModel(selected_controls, emptyList(), EMPTY_STRING)
+ val expected = listOf(
+ ControlWrapper(controls[10]),
+ ControlWrapper(controls[11])
+ )
+
+ expected.zip(new_model.elements).forEachIndexed { index, it ->
+ assertEquals("Error in item at index $index", it.first, it.second)
+ }
+ }
+
+ @Test
+ fun testFavorites() {
+ val expectedFavorites = favoritesIndices.map(controls::get).map(ControlStatus::control)
+ model.favorites.zip(expectedFavorites).forEach {
+ assertTrue(sameControl(it.first, it.second))
+ }
+ }
+
+ @Test
+ fun testAddFavorite() {
+ val indexToAdd = 6
+ model.changeFavoriteStatus("$idPrefix$indexToAdd", true)
+
+ val expectedFavorites = favoritesIndices.map(controls::get).map(ControlStatus::control) +
+ controls[indexToAdd].control
+
+ model.favorites.zip(expectedFavorites).forEach {
+ assertTrue(sameControl(it.first, it.second))
+ }
+ }
+
+ @Test
+ fun testAddFavorite_alreadyThere() {
+ val indexToAdd = 7
+ model.changeFavoriteStatus("$idPrefix$indexToAdd", true)
+
+ val expectedFavorites = favoritesIndices.map(controls::get).map(ControlStatus::control)
+
+ model.favorites.zip(expectedFavorites).forEach {
+ assertTrue(sameControl(it.first, it.second))
+ }
+ }
+
+ @Test
+ fun testRemoveFavorite() {
+ val indexToRemove = 3
+ model.changeFavoriteStatus("$idPrefix$indexToRemove", false)
+
+ val expectedFavorites = (favoritesIndices.filterNot { it == indexToRemove })
+ .map(controls::get)
+ .map(ControlStatus::control)
+
+ model.favorites.zip(expectedFavorites).forEach {
+ assertTrue(sameControl(it.first, it.second))
+ }
+ }
+
+ @Test
+ fun testRemoveFavorite_notThere() {
+ val indexToRemove = 4
+ model.changeFavoriteStatus("$idPrefix$indexToRemove", false)
+
+ val expectedFavorites = favoritesIndices.map(controls::get).map(ControlStatus::control)
+
+ model.favorites.zip(expectedFavorites).forEach {
+ assertTrue(sameControl(it.first, it.second))
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java
index e917c93..c5b6969 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java
@@ -37,8 +37,9 @@
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.DragDownHelper;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
-import com.android.systemui.statusbar.PulseExpansionHandler;
import com.android.systemui.statusbar.NotificationShadeWindowBlurController;
+import com.android.systemui.statusbar.PulseExpansionHandler;
+import com.android.systemui.statusbar.SuperStatusBarViewFactory;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
@@ -81,6 +82,7 @@
@Mock private NotificationPanelViewController mNotificationPanelViewController;
@Mock private NotificationStackScrollLayout mNotificationStackScrollLayout;
@Mock private NotificationShadeWindowBlurController mNotificationShadeWindowBlurController;
+ @Mock private SuperStatusBarViewFactory mStatusBarViewFactory;
@Before
public void setUp() {
@@ -116,7 +118,8 @@
mDockManager,
mNotificationShadeWindowBlurController,
mView,
- mNotificationPanelViewController);
+ mNotificationPanelViewController,
+ mStatusBarViewFactory);
mController.setupExpandedStatusBar();
mController.setService(mStatusBar);
mController.setDragDownHelper(mDragDownHelper);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index d81b8c2..5253e2ca 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -247,6 +247,7 @@
@Mock private KeyguardDismissUtil mKeyguardDismissUtil;
@Mock private ExtensionController mExtensionController;
@Mock private UserInfoControllerImpl mUserInfoControllerImpl;
+ @Mock private PhoneStatusBarPolicy mPhoneStatusBarPolicy;
private ShadeController mShadeController;
private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock());
private InitController mInitController = new InitController();
@@ -400,6 +401,7 @@
mKeyguardDismissUtil,
mExtensionController,
mUserInfoControllerImpl,
+ mPhoneStatusBarPolicy,
mDismissCallbackRegistry,
mStatusBarTouchableRegionManager);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/sensors/FakeProximitySensor.java b/packages/SystemUI/tests/src/com/android/systemui/util/sensors/FakeProximitySensor.java
index 54cb0b8..31d884c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/sensors/FakeProximitySensor.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/sensors/FakeProximitySensor.java
@@ -20,11 +20,9 @@
public class FakeProximitySensor extends ProximitySensor {
private boolean mAvailable;
- private boolean mPaused;
public FakeProximitySensor(Resources resources, AsyncSensorManager sensorManager) {
super(resources, sensorManager);
-
mAvailable = true;
}
diff --git a/services/core/java/com/android/server/adb/AdbService.java b/services/core/java/com/android/server/adb/AdbService.java
index 7ccb284..7aaf9be 100644
--- a/services/core/java/com/android/server/adb/AdbService.java
+++ b/services/core/java/com/android/server/adb/AdbService.java
@@ -144,6 +144,18 @@
public File getAdbTempKeysFile() {
return mDebuggingManager.getAdbTempKeysFile();
}
+
+ @Override
+ public void startAdbdForTransport(byte transportType) {
+ FgThread.getHandler().sendMessage(obtainMessage(
+ AdbService::setAdbdEnabledForTransport, AdbService.this, true, transportType));
+ }
+
+ @Override
+ public void stopAdbdForTransport(byte transportType) {
+ FgThread.getHandler().sendMessage(obtainMessage(
+ AdbService::setAdbdEnabledForTransport, AdbService.this, false, transportType));
+ }
}
private void initAdbState() {
@@ -437,6 +449,19 @@
}
}
+ private void setAdbdEnabledForTransport(boolean enable, byte transportType) {
+ if (transportType == AdbTransportType.USB) {
+ mIsAdbUsbEnabled = enable;
+ } else if (transportType == AdbTransportType.WIFI) {
+ mIsAdbWifiEnabled = enable;
+ }
+ if (enable) {
+ startAdbd();
+ } else {
+ stopAdbd();
+ }
+ }
+
private void setAdbEnabled(boolean enable, byte transportType) {
if (DEBUG) {
Slog.d(TAG, "setAdbEnabled(" + enable + "), mIsAdbUsbEnabled=" + mIsAdbUsbEnabled
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 211da0a..f408fe7 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -4869,6 +4869,19 @@
return true;
}
+ if (r.app != null) {
+ ActiveInstrumentation instr = r.app.getActiveInstrumentation();
+ if (instr != null && instr.mHasBackgroundActivityStartsPermission) {
+ return true;
+ }
+ }
+
+ final boolean hasAllowBackgroundActivityStartsToken = r.app != null
+ ? !r.app.mAllowBackgroundActivityStartsTokens.isEmpty() : false;
+ if (hasAllowBackgroundActivityStartsToken) {
+ return true;
+ }
+
if (mAm.checkPermission(START_ACTIVITIES_FROM_BACKGROUND, callingPid, callingUid)
== PERMISSION_GRANTED) {
return true;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index cea3bb8..b2fb530 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -6515,14 +6515,6 @@
}
@Override
- public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
- Rect tempDockedTaskInsetBounds,
- Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
- mActivityTaskManager.resizeDockedStack(dockedBounds, tempDockedTaskBounds,
- tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds);
- }
-
- @Override
public void positionTaskInStack(int taskId, int stackId, int position) {
mActivityTaskManager.positionTaskInStack(taskId, stackId, position);
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index bf79729..2941e77 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -2570,8 +2570,6 @@
switch (op) {
case "move-task":
return runStackMoveTask(pw);
- case "resize-docked-stack":
- return runStackResizeDocked(pw);
case "positiontask":
return runStackPositionTask(pw);
case "list":
@@ -2646,17 +2644,6 @@
return 0;
}
- int runStackResizeDocked(PrintWriter pw) throws RemoteException {
- final Rect bounds = getBounds();
- final Rect taskBounds = getBounds();
- if (bounds == null || taskBounds == null) {
- getErrPrintWriter().println("Error: invalid input bounds");
- return -1;
- }
- mTaskInterface.resizeDockedStack(bounds, taskBounds, null, null, null);
- return 0;
- }
-
int runStackPositionTask(PrintWriter pw) throws RemoteException {
String taskIdStr = getNextArgRequired();
int taskId = Integer.parseInt(taskIdStr);
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index e5b8403..76bc366 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -4178,13 +4178,6 @@
final DisplayContent displayContent = getDisplayContent();
if (!displayContent.mClosingApps.contains(this)
&& !displayContent.mOpeningApps.contains(this)) {
- // The token is not closing nor opening, so even if there is an animation set, that
- // doesn't mean that it goes through the normal app transition cycle so we have
- // to inform the docked controller about visibility change.
- // TODO(multi-display): notify docked divider on all displays where visibility was
- // affected.
- displayContent.getDockedDividerController().notifyAppVisibilityChanged();
-
// Take the screenshot before possibly hiding the WSA, otherwise the screenshot
// will not be taken.
mWmService.mTaskSnapshotController.notifyAppVisibilityChanged(this, visible);
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index ff890ff..598389b 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -17,8 +17,6 @@
package com.android.server.wm;
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
-import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT;
-import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SPLIT_SCREEN;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
@@ -39,16 +37,10 @@
import static android.content.pm.ActivityInfo.FLAG_RESUME_WHILE_PAUSING;
import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
-import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
import static android.view.Display.INVALID_DISPLAY;
-import static android.view.WindowManager.DOCKED_BOTTOM;
-import static android.view.WindowManager.DOCKED_INVALID;
-import static android.view.WindowManager.DOCKED_LEFT;
-import static android.view.WindowManager.DOCKED_RIGHT;
-import static android.view.WindowManager.DOCKED_TOP;
import static android.view.WindowManager.TRANSIT_ACTIVITY_CLOSE;
import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
import static android.view.WindowManager.TRANSIT_CRASHING_ACTIVITY_CLOSE;
@@ -98,13 +90,8 @@
import static com.android.server.wm.ActivityTaskManagerService.H.FIRST_ACTIVITY_STACK_MSG;
import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_FREE_RESIZE;
import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_WINDOWING_MODE_RESIZE;
-import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_DOCKED_DIVIDER;
import static com.android.server.wm.TaskProto.ACTIVITIES;
import static com.android.server.wm.TaskProto.ACTIVITY_TYPE;
-import static com.android.server.wm.TaskProto.ADJUSTED_BOUNDS;
-import static com.android.server.wm.TaskProto.ADJUSTED_FOR_IME;
-import static com.android.server.wm.TaskProto.ADJUST_DIVIDER_AMOUNT;
-import static com.android.server.wm.TaskProto.ADJUST_IME_AMOUNT;
import static com.android.server.wm.TaskProto.ANIMATING_BOUNDS;
import static com.android.server.wm.TaskProto.BOUNDS;
import static com.android.server.wm.TaskProto.CREATED_BY_ORGANIZER;
@@ -113,7 +100,6 @@
import static com.android.server.wm.TaskProto.DISPLAY_ID;
import static com.android.server.wm.TaskProto.FILLS_PARENT;
import static com.android.server.wm.TaskProto.LAST_NON_FULLSCREEN_BOUNDS;
-import static com.android.server.wm.TaskProto.MINIMIZE_AMOUNT;
import static com.android.server.wm.TaskProto.MIN_HEIGHT;
import static com.android.server.wm.TaskProto.MIN_WIDTH;
import static com.android.server.wm.TaskProto.ORIG_ACTIVITY;
@@ -168,7 +154,6 @@
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
import android.view.Display;
-import android.view.DisplayCutout;
import android.view.DisplayInfo;
import android.view.ITaskOrganizer;
import android.view.SurfaceControl;
@@ -177,8 +162,6 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IVoiceInteractor;
import com.android.internal.os.logging.MetricsLoggerWrapper;
-import com.android.internal.policy.DividerSnapAlgorithm;
-import com.android.internal.policy.DockedDividerUtils;
import com.android.internal.util.function.pooled.PooledConsumer;
import com.android.internal.util.function.pooled.PooledFunction;
import com.android.internal.util.function.pooled.PooledLambda;
@@ -238,13 +221,6 @@
/** Stack is completely invisible. */
static final int STACK_VISIBILITY_INVISIBLE = 2;
- /** Minimum size of an adjusted stack bounds relative to original stack bounds. Used to
- * restrict IME adjustment so that a min portion of top stack remains visible.*/
- private static final float ADJUSTED_STACK_FRACTION_MIN = 0.3f;
-
- /** Dimming amount for non-focused stack when stacks are IME-adjusted. */
- private static final float IME_ADJUST_DIM_AMOUNT = 0.25f;
-
enum ActivityState {
INITIALIZING,
STARTED,
@@ -294,28 +270,10 @@
/** For Pinned stack controlling. */
private Rect mTmpToBounds = new Rect();
- /** Stack bounds adjusted to screen content area (taking into account IM windows, etc.) */
- private final Rect mAdjustedBounds = new Rect();
-
- /**
- * Fully adjusted IME bounds. These are different from {@link #mAdjustedBounds} because they
- * represent the state when the animation has ended.
- */
- private final Rect mFullyAdjustedImeBounds = new Rect();
-
/** Detach this stack from its display when animation completes. */
// TODO: maybe tie this to WindowContainer#removeChild some how...
private boolean mDeferRemoval;
- private final Rect mTmpAdjustedBounds = new Rect();
- private boolean mAdjustedForIme;
- private boolean mImeGoingAway;
- private WindowState mImeWin;
- private float mMinimizeAmount;
- private float mAdjustImeAmount;
- private float mAdjustDividerAmount;
- private final int mDockedStackMinimizeThickness;
-
// If this is true, we are in the bounds animating mode. The task will be down or upscaled to
// perfectly fit the region it would have been cropped to. We may also avoid certain logic we
// would otherwise apply while resizing, while resizing in the bounds animating mode.
@@ -643,8 +601,6 @@
_realActivitySuspended, userSetupComplete, minWidth, minHeight, info, _voiceSession,
_voiceInteractor, stack);
- mDockedStackMinimizeThickness = mWmService.mContext.getResources().getDimensionPixelSize(
- com.android.internal.R.dimen.docked_stack_minimize_thickness);
EventLogTags.writeWmStackCreated(id);
mHandler = new ActivityStackHandler(mStackSupervisor.mLooper);
mCurrentUser = mAtmService.mAmInternal.getCurrentUserId();
@@ -1202,8 +1158,8 @@
@Override
boolean isFocusable() {
- return super.isFocusable() && !(inSplitScreenPrimaryWindowingMode()
- && mRootWindowContainer.mIsDockMinimized);
+ // Special check for tile which isn't really in the hierarchy
+ return mTile != null ? mTile.isFocusable() : super.isFocusable();
}
boolean isTopActivityFocusable() {
@@ -3497,43 +3453,6 @@
forAllLeafTasks(Task::prepareFreezingBounds, true /* traverseTopToBottom */);
}
- /**
- * Overrides the adjusted bounds, i.e. sets temporary layout bounds which are different from
- * the normal task bounds.
- *
- * @param bounds The adjusted bounds.
- */
- private void setAdjustedBounds(Rect bounds) {
- if (mAdjustedBounds.equals(bounds) && !isAnimatingForIme()) {
- return;
- }
-
- mAdjustedBounds.set(bounds);
- final boolean adjusted = !mAdjustedBounds.isEmpty();
- Rect insetBounds = null;
- if (adjusted && isAdjustedForMinimizedDockedStack()) {
- insetBounds = getRawBounds();
- } else if (adjusted && mAdjustedForIme) {
- if (mImeGoingAway) {
- insetBounds = getRawBounds();
- } else {
- insetBounds = mFullyAdjustedImeBounds;
- }
- }
-
- if (!matchParentBounds()) {
- final boolean alignBottom = mAdjustedForIme && getDockSide() == DOCKED_TOP;
- final PooledConsumer c = PooledLambda.obtainConsumer(Task::alignToAdjustedBounds,
- PooledLambda.__(Task.class), adjusted ? mAdjustedBounds : getRawBounds(),
- insetBounds, alignBottom);
- forAllLeafTasks(c, true /* traverseTopToBottom */);
- c.recycle();
- }
-
- mDisplayContent.setLayoutNeeded();
- updateSurfaceBounds();
- }
-
@Override
public int setBounds(Rect bounds) {
// Calling Task#setBounds() for leaf task since this is the a specialization of
@@ -3552,8 +3471,6 @@
final int result = super.setBounds(!inMultiWindowMode() ? null : bounds);
- updateAdjustedBounds();
-
updateSurfaceBounds();
return result;
}
@@ -3575,19 +3492,6 @@
bounds.set(getBounds());
}
- @Override
- public Rect getBounds() {
- // If we're currently adjusting for IME or minimized docked stack, we use the adjusted
- // bounds; otherwise, no need to adjust the output bounds if fullscreen or the docked
- // stack is visible since it is already what we want to represent to the rest of the
- // system.
- if (!mAdjustedBounds.isEmpty()) {
- return mAdjustedBounds;
- } else {
- return super.getBounds();
- }
- }
-
/**
* @return the final bounds for the bounds animation.
*/
@@ -3620,113 +3524,6 @@
}
/**
- * Updates the passed-in {@code inOutBounds} based on the current state of the
- * docked controller. This gets run *after* the override configuration is updated, so it's
- * safe to rely on the controller's state in here (though eventually this dependence should
- * be removed).
- *
- * This does NOT modify this TaskStack's configuration. However, it does, for the time-being,
- * update docked controller state.
- *
- * @param parentConfig the parent configuration for reference.
- * @param inOutBounds the bounds to update (both input and output).
- */
- void calculateDockedBoundsForConfigChange(Configuration parentConfig, Rect inOutBounds) {
- final boolean primary =
- getRequestedOverrideWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
- repositionSplitScreenStackAfterRotation(parentConfig, primary, inOutBounds);
- final DisplayCutout cutout = mDisplayContent.getDisplayInfo().displayCutout;
- snapDockedStackAfterRotation(parentConfig, cutout, inOutBounds);
- if (primary) {
- final int newDockSide = getDockSide(parentConfig, inOutBounds);
- // Update the dock create mode and clear the dock create bounds, these
- // might change after a rotation and the original values will be invalid.
- mWmService.setDockedStackCreateStateLocked(
- (newDockSide == DOCKED_LEFT || newDockSide == DOCKED_TOP)
- ? SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT
- : SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT,
- null);
- mDisplayContent.getDockedDividerController().notifyDockSideChanged(newDockSide);
- }
- }
-
- /**
- * Some primary split screen sides are not allowed by the policy. This method queries the policy
- * and moves the primary stack around if needed.
- *
- * @param parentConfig the configuration of the stack's parent.
- * @param primary true if adjusting the primary docked stack, false for secondary.
- * @param inOutBounds the bounds of the stack to adjust.
- */
- void repositionSplitScreenStackAfterRotation(Configuration parentConfig, boolean primary,
- Rect inOutBounds) {
- final int dockSide = getDockSide(mDisplayContent, parentConfig, inOutBounds);
- final int otherDockSide = DockedDividerUtils.invertDockSide(dockSide);
- final int primaryDockSide = primary ? dockSide : otherDockSide;
- if (mDisplayContent.getDockedDividerController()
- .canPrimaryStackDockTo(primaryDockSide,
- parentConfig.windowConfiguration.getBounds(),
- parentConfig.windowConfiguration.getRotation())) {
- return;
- }
- final Rect parentBounds = parentConfig.windowConfiguration.getBounds();
- switch (otherDockSide) {
- case DOCKED_LEFT:
- int movement = inOutBounds.left;
- inOutBounds.left -= movement;
- inOutBounds.right -= movement;
- break;
- case DOCKED_RIGHT:
- movement = parentBounds.right - inOutBounds.right;
- inOutBounds.left += movement;
- inOutBounds.right += movement;
- break;
- case DOCKED_TOP:
- movement = inOutBounds.top;
- inOutBounds.top -= movement;
- inOutBounds.bottom -= movement;
- break;
- case DOCKED_BOTTOM:
- movement = parentBounds.bottom - inOutBounds.bottom;
- inOutBounds.top += movement;
- inOutBounds.bottom += movement;
- break;
- }
- }
-
- /**
- * Snaps the bounds after rotation to the closest snap target for the docked stack.
- */
- void snapDockedStackAfterRotation(Configuration parentConfig, DisplayCutout displayCutout,
- Rect outBounds) {
-
- // Calculate the current position.
- final int dividerSize = mDisplayContent.getDockedDividerController().getContentWidth();
- final int dockSide = getDockSide(parentConfig, outBounds);
- final int dividerPosition = DockedDividerUtils.calculatePositionForBounds(outBounds,
- dockSide, dividerSize);
- final int displayWidth = parentConfig.windowConfiguration.getBounds().width();
- final int displayHeight = parentConfig.windowConfiguration.getBounds().height();
-
- // Snap the position to a target.
- final int rotation = parentConfig.windowConfiguration.getRotation();
- final int orientation = parentConfig.orientation;
- mDisplayContent.getDisplayPolicy().getStableInsetsLw(rotation, displayWidth, displayHeight,
- displayCutout, outBounds);
- final DividerSnapAlgorithm algorithm = new DividerSnapAlgorithm(
- mWmService.mContext.getResources(), displayWidth, displayHeight,
- dividerSize, orientation == Configuration.ORIENTATION_PORTRAIT, outBounds,
- getDockSide(), isMinimizedDockAndHomeStackResizable());
- final DividerSnapAlgorithm.SnapTarget target =
- algorithm.calculateNonDismissingSnapTarget(dividerPosition);
-
- // Recalculate the bounds based on the position of the target.
- DockedDividerUtils.calculateBoundsForPosition(target.position, dockSide,
- outBounds, displayWidth, displayHeight,
- dividerSize);
- }
-
- /**
* Put a Task in this stack. Used for adding only.
* When task is added to top of the stack, the entire branch of the hierarchy (including stack
* and display) will be brought to top.
@@ -3916,445 +3713,8 @@
}
}
- /**
- * Determines the stack and task bounds of the other stack when in docked mode. The current task
- * bounds is passed in but depending on the stack, the task and stack must match. Only in
- * minimized mode with resizable launcher, the other stack ignores calculating the stack bounds
- * and uses the task bounds passed in as the stack and task bounds, otherwise the stack bounds
- * is calculated and is also used for its task bounds.
- * If any of the out bounds are empty, it represents default bounds
- *
- * @param currentTempTaskBounds the current task bounds of the other stack
- * @param outStackBounds the calculated stack bounds of the other stack
- * @param outTempTaskBounds the calculated task bounds of the other stack
- */
- void getStackDockedModeBounds(Rect dockedBounds,
- Rect currentTempTaskBounds, Rect outStackBounds, Rect outTempTaskBounds) {
- final Configuration parentConfig = getParent().getConfiguration();
- outTempTaskBounds.setEmpty();
-
- if (dockedBounds == null || dockedBounds.isEmpty()) {
- // Calculate the primary docked bounds.
- final boolean dockedOnTopOrLeft = mWmService.mDockedStackCreateMode
- == SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
- getStackDockedModeBounds(parentConfig,
- true /* primary */, outStackBounds, dockedBounds,
- mDisplayContent.mDividerControllerLocked.getContentWidth(), dockedOnTopOrLeft);
- return;
- }
- final int dockedSide = getDockSide(parentConfig, dockedBounds);
-
- // When the home stack is resizable, should always have the same stack and task bounds
- if (isActivityTypeHome()) {
- final Task homeTask = getTopMostTask();
- if (homeTask == null || homeTask.isResizeable()) {
- // Calculate the home stack bounds when in docked mode and the home stack is
- // resizeable.
- getDisplayContent().mDividerControllerLocked
- .getHomeStackBoundsInDockedMode(parentConfig,
- dockedSide, outStackBounds);
- } else {
- // Home stack isn't resizeable, so don't specify stack bounds.
- outStackBounds.setEmpty();
- }
-
- outTempTaskBounds.set(outStackBounds);
- return;
- }
-
- // When minimized state, the stack bounds for all non-home and docked stack bounds should
- // match the passed task bounds
- if (isMinimizedDockAndHomeStackResizable() && currentTempTaskBounds != null) {
- outStackBounds.set(currentTempTaskBounds);
- return;
- }
-
- if (dockedSide == DOCKED_INVALID) {
- // Not sure how you got here...Only thing we can do is return current bounds.
- Slog.e(TAG_WM, "Failed to get valid docked side for docked stack");
- outStackBounds.set(getRawBounds());
- return;
- }
-
- final boolean dockedOnTopOrLeft = dockedSide == DOCKED_TOP || dockedSide == DOCKED_LEFT;
- getStackDockedModeBounds(parentConfig,
- false /* primary */, outStackBounds, dockedBounds,
- mDisplayContent.mDividerControllerLocked.getContentWidth(), dockedOnTopOrLeft);
- }
-
- /**
- * Outputs the bounds a stack should be given the presence of a docked stack on the display.
- * @param parentConfig The parent configuration.
- * @param primary {@code true} if getting the primary stack bounds.
- * @param outBounds Output bounds that should be used for the stack.
- * @param dockedBounds Bounds of the docked stack.
- * @param dockDividerWidth We need to know the width of the divider make to the output bounds
- * close to the side of the dock.
- * @param dockOnTopOrLeft If the docked stack is on the top or left side of the screen.
- */
- private void getStackDockedModeBounds(Configuration parentConfig, boolean primary,
- Rect outBounds, Rect dockedBounds, int dockDividerWidth,
- boolean dockOnTopOrLeft) {
- final Rect displayRect = parentConfig.windowConfiguration.getBounds();
- final boolean splitHorizontally = displayRect.width() > displayRect.height();
-
- outBounds.set(displayRect);
- if (primary) {
- if (mWmService.mDockedStackCreateBounds != null) {
- outBounds.set(mWmService.mDockedStackCreateBounds);
- return;
- }
-
- // The initial bounds of the docked stack when it is created about half the screen space
- // and its bounds can be adjusted after that. The bounds of all other stacks are
- // adjusted to occupy whatever screen space the docked stack isn't occupying.
- final DisplayCutout displayCutout = mDisplayContent.getDisplayInfo().displayCutout;
- mDisplayContent.getDisplayPolicy().getStableInsetsLw(
- parentConfig.windowConfiguration.getRotation(),
- displayRect.width(), displayRect.height(), displayCutout, mTmpRect2);
- final int position = new DividerSnapAlgorithm(mWmService.mContext.getResources(),
- displayRect.width(),
- displayRect.height(),
- dockDividerWidth,
- parentConfig.orientation == ORIENTATION_PORTRAIT,
- mTmpRect2).getMiddleTarget().position;
-
- if (dockOnTopOrLeft) {
- if (splitHorizontally) {
- outBounds.right = position;
- } else {
- outBounds.bottom = position;
- }
- } else {
- if (splitHorizontally) {
- outBounds.left = position + dockDividerWidth;
- } else {
- outBounds.top = position + dockDividerWidth;
- }
- }
- return;
- }
-
- // Other stacks occupy whatever space is left by the docked stack.
- if (!dockOnTopOrLeft) {
- if (splitHorizontally) {
- outBounds.right = dockedBounds.left - dockDividerWidth;
- } else {
- outBounds.bottom = dockedBounds.top - dockDividerWidth;
- }
- } else {
- if (splitHorizontally) {
- outBounds.left = dockedBounds.right + dockDividerWidth;
- } else {
- outBounds.top = dockedBounds.bottom + dockDividerWidth;
- }
- }
- DockedDividerUtils.sanitizeStackBounds(outBounds, !dockOnTopOrLeft);
- }
-
- void resetDockedStackToMiddle() {
- if (!inSplitScreenPrimaryWindowingMode()) {
- throw new IllegalStateException("Not a docked stack=" + this);
- }
-
- mWmService.mDockedStackCreateBounds = null;
-
- final Rect bounds = new Rect();
- final Rect tempBounds = new Rect();
- getStackDockedModeBounds(null /* dockedBounds */, null /* currentTempTaskBounds */,
- bounds, tempBounds);
- mStackSupervisor.resizeDockedStackLocked(bounds, null /* tempTaskBounds */,
- null /* tempTaskInsetBounds */, null /* tempOtherTaskBounds */,
- null /* tempOtherTaskInsetBounds */, false /* preserveWindows */,
- false /* deferResume */);
- }
-
- /**
- * Adjusts the stack bounds if the IME is visible.
- *
- * @param imeWin The IME window.
- * @param keepLastAmount Use {@code true} to keep the last adjusted amount from
- * {@link DockedStackDividerController} for adjusting the stack bounds,
- * Use {@code false} to reset adjusted amount as 0.
- * @see #updateAdjustForIme(float, float, boolean)
- */
- void setAdjustedForIme(WindowState imeWin, boolean keepLastAmount) {
- mImeWin = imeWin;
- mImeGoingAway = false;
- if (!mAdjustedForIme || keepLastAmount) {
- mAdjustedForIme = true;
- DockedStackDividerController controller = getDisplayContent().mDividerControllerLocked;
- final float adjustImeAmount = keepLastAmount ? controller.mLastAnimationProgress : 0f;
- final float adjustDividerAmount = keepLastAmount ? controller.mLastDividerProgress : 0f;
- updateAdjustForIme(adjustImeAmount, adjustDividerAmount, true /* force */);
- }
- }
-
- boolean isAdjustedForIme() {
- return mAdjustedForIme;
- }
-
- boolean isAnimatingForIme() {
- return mImeWin != null && mImeWin.isAnimatingLw();
- }
-
- /**
- * Update the stack's bounds (crop or position) according to the IME window's
- * current position. When IME window is animated, the bottom stack is animated
- * together to track the IME window's current position, and the top stack is
- * cropped as necessary.
- *
- * @return true if a traversal should be performed after the adjustment.
- */
- boolean updateAdjustForIme(float adjustAmount, float adjustDividerAmount, boolean force) {
- if (adjustAmount != mAdjustImeAmount
- || adjustDividerAmount != mAdjustDividerAmount || force) {
- mAdjustImeAmount = adjustAmount;
- mAdjustDividerAmount = adjustDividerAmount;
- updateAdjustedBounds();
- return isVisible();
- } else {
- return false;
- }
- }
-
- /**
- * Resets the adjustment after it got adjusted for the IME.
- * @param adjustBoundsNow if true, reset and update the bounds immediately and forget about
- * animations; otherwise, set flag and animates the window away together
- * with IME window.
- */
- void resetAdjustedForIme(boolean adjustBoundsNow) {
- if (adjustBoundsNow) {
- mImeWin = null;
- mImeGoingAway = false;
- mAdjustImeAmount = 0f;
- mAdjustDividerAmount = 0f;
- if (!mAdjustedForIme) {
- return;
- }
- mAdjustedForIme = false;
- updateAdjustedBounds();
- mWmService.setResizeDimLayer(false, getWindowingMode(), 1.0f);
- } else {
- mImeGoingAway |= mAdjustedForIme;
- }
- }
-
- /**
- * Sets the amount how much we currently minimize our stack.
- *
- * @param minimizeAmount The amount, between 0 and 1.
- * @return Whether the amount has changed and a layout is needed.
- */
- boolean setAdjustedForMinimizedDock(float minimizeAmount) {
- if (minimizeAmount != mMinimizeAmount) {
- mMinimizeAmount = minimizeAmount;
- updateAdjustedBounds();
- return isVisible();
- } else {
- return false;
- }
- }
-
boolean shouldIgnoreInput() {
- return isAdjustedForMinimizedDockedStack()
- || (inSplitScreenPrimaryWindowingMode() && isMinimizedDockAndHomeStackResizable());
- }
-
- /**
- * Puts all visible tasks that are adjusted for IME into resizing mode and adds the windows
- * to the list of to be drawn windows the service is waiting for.
- */
- void beginImeAdjustAnimation() {
- forAllLeafTasks((t) -> {
- if (t.hasContentToDisplay()) {
- t.setDragResizing(true, DRAG_RESIZE_MODE_DOCKED_DIVIDER);
- t.setWaitingForDrawnIfResizingChanged();
- }
- }, true /* traverseTopToBottom */);
- }
-
- /** Resets the resizing state of all windows. */
- void endImeAdjustAnimation() {
- forAllLeafTasks((t) -> {
- t.setDragResizing(false, DRAG_RESIZE_MODE_DOCKED_DIVIDER);
- }, true /* traverseTopToBottom */);
- }
-
- private int getMinTopStackBottom(final Rect displayContentRect, int originalStackBottom) {
- return displayContentRect.top + (int)
- ((originalStackBottom - displayContentRect.top) * ADJUSTED_STACK_FRACTION_MIN);
- }
-
- private boolean adjustForIME(final WindowState imeWin) {
- // To prevent task stack resize animation may flicking when playing app transition
- // animation & IME window enter animation in parallel, we need to make sure app
- // transition is done and then adjust task size for IME, skip the new adjusted frame when
- // app transition is still running.
- if (getDisplayContent().mAppTransition.isRunning()) {
- return false;
- }
-
- final int dockedSide = getDockSide();
- final boolean dockedTopOrBottom = dockedSide == DOCKED_TOP || dockedSide == DOCKED_BOTTOM;
- if (imeWin == null || !dockedTopOrBottom) {
- return false;
- }
-
- final Rect displayStableRect = mTmpRect;
- final Rect contentBounds = mTmpRect2;
-
- // Calculate the content bounds excluding the area occupied by IME
- getDisplayContent().getStableRect(displayStableRect);
- contentBounds.set(displayStableRect);
- int imeTop = Math.max(imeWin.getFrameLw().top, contentBounds.top);
-
- imeTop += imeWin.getGivenContentInsetsLw().top;
- if (contentBounds.bottom > imeTop) {
- contentBounds.bottom = imeTop;
- }
-
- final int yOffset = displayStableRect.bottom - contentBounds.bottom;
-
- final int dividerWidth =
- getDisplayContent().mDividerControllerLocked.getContentWidth();
- final int dividerWidthInactive =
- getDisplayContent().mDividerControllerLocked.getContentWidthInactive();
-
- if (dockedSide == DOCKED_TOP) {
- // If this stack is docked on top, we make it smaller so the bottom stack is not
- // occluded by IME. We shift its bottom up by the height of the IME, but
- // leaves at least 30% of the top stack visible.
- final int minTopStackBottom =
- getMinTopStackBottom(displayStableRect, getRawBounds().bottom);
- final int bottom = Math.max(
- getRawBounds().bottom - yOffset + dividerWidth - dividerWidthInactive,
- minTopStackBottom);
- mTmpAdjustedBounds.set(getRawBounds());
- mTmpAdjustedBounds.bottom = (int) (mAdjustImeAmount * bottom + (1 - mAdjustImeAmount)
- * getRawBounds().bottom);
- mFullyAdjustedImeBounds.set(getRawBounds());
- } else {
- // When the stack is on bottom and has no focus, it's only adjusted for divider width.
- final int dividerWidthDelta = dividerWidthInactive - dividerWidth;
-
- // When the stack is on bottom and has focus, it needs to be moved up so as to
- // not occluded by IME, and at the same time adjusted for divider width.
- // We try to move it up by the height of the IME window, but only to the extent
- // that leaves at least 30% of the top stack visible.
- // 'top' is where the top of bottom stack will move to in this case.
- final int topBeforeImeAdjust =
- getRawBounds().top - dividerWidth + dividerWidthInactive;
- final int minTopStackBottom =
- getMinTopStackBottom(displayStableRect,
- getRawBounds().top - dividerWidth);
- final int top = Math.max(
- getRawBounds().top - yOffset, minTopStackBottom + dividerWidthInactive);
-
- mTmpAdjustedBounds.set(getRawBounds());
- // Account for the adjustment for IME and divider width separately.
- // (top - topBeforeImeAdjust) is the amount of movement due to IME only,
- // and dividerWidthDelta is due to divider width change only.
- mTmpAdjustedBounds.top =
- getRawBounds().top + (int) (mAdjustImeAmount * (top - topBeforeImeAdjust)
- + mAdjustDividerAmount * dividerWidthDelta);
- mFullyAdjustedImeBounds.set(getRawBounds());
- mFullyAdjustedImeBounds.top = top;
- mFullyAdjustedImeBounds.bottom = top + getRawBounds().height();
- }
- return true;
- }
-
- private boolean adjustForMinimizedDockedStack(float minimizeAmount) {
- final int dockSide = getDockSide();
- if (dockSide == DOCKED_INVALID && !mTmpAdjustedBounds.isEmpty()) {
- return false;
- }
-
- if (dockSide == DOCKED_TOP) {
- mWmService.getStableInsetsLocked(DEFAULT_DISPLAY, mTmpRect);
- int topInset = mTmpRect.top;
- mTmpAdjustedBounds.set(getRawBounds());
- mTmpAdjustedBounds.bottom = (int) (minimizeAmount * topInset + (1 - minimizeAmount)
- * getRawBounds().bottom);
- } else if (dockSide == DOCKED_LEFT) {
- mTmpAdjustedBounds.set(getRawBounds());
- final int width = getRawBounds().width();
- mTmpAdjustedBounds.right =
- (int) (minimizeAmount * mDockedStackMinimizeThickness
- + (1 - minimizeAmount) * getRawBounds().right);
- mTmpAdjustedBounds.left = mTmpAdjustedBounds.right - width;
- } else if (dockSide == DOCKED_RIGHT) {
- mTmpAdjustedBounds.set(getRawBounds());
- mTmpAdjustedBounds.left =
- (int) (minimizeAmount * (getRawBounds().right - mDockedStackMinimizeThickness)
- + (1 - minimizeAmount) * getRawBounds().left);
- }
- return true;
- }
-
- boolean isMinimizedDockAndHomeStackResizable() {
- return mDisplayContent.mDividerControllerLocked.isMinimizedDock()
- && mDisplayContent.mDividerControllerLocked.isHomeStackResizable();
- }
-
- /**
- * @return the distance in pixels how much the stack gets minimized from it's original size
- */
- int getMinimizeDistance() {
- final int dockSide = getDockSide();
- if (dockSide == DOCKED_INVALID) {
- return 0;
- }
-
- if (dockSide == DOCKED_TOP) {
- mWmService.getStableInsetsLocked(DEFAULT_DISPLAY, mTmpRect);
- int topInset = mTmpRect.top;
- return getRawBounds().bottom - topInset;
- } else if (dockSide == DOCKED_LEFT || dockSide == DOCKED_RIGHT) {
- return getRawBounds().width() - mDockedStackMinimizeThickness;
- } else {
- return 0;
- }
- }
-
- /**
- * Updates the adjustment depending on it's current state.
- */
- private void updateAdjustedBounds() {
- boolean adjust = false;
- if (mMinimizeAmount != 0f) {
- adjust = adjustForMinimizedDockedStack(mMinimizeAmount);
- } else if (mAdjustedForIme) {
- adjust = adjustForIME(mImeWin);
- }
- if (!adjust) {
- mTmpAdjustedBounds.setEmpty();
- }
- setAdjustedBounds(mTmpAdjustedBounds);
-
- final boolean isImeTarget = (mWmService.getImeFocusStackLocked() == this);
- if (mAdjustedForIme && adjust && !isImeTarget) {
- final float alpha = Math.max(mAdjustImeAmount, mAdjustDividerAmount)
- * IME_ADJUST_DIM_AMOUNT;
- mWmService.setResizeDimLayer(true, getWindowingMode(), alpha);
- }
- }
-
- void applyAdjustForImeIfNeeded(Task task) {
- if (mMinimizeAmount != 0f || !mAdjustedForIme || mAdjustedBounds.isEmpty()) {
- return;
- }
-
- final Rect insetBounds = mImeGoingAway ? getRawBounds() : mFullyAdjustedImeBounds;
- task.alignToAdjustedBounds(mAdjustedBounds, insetBounds, getDockSide() == DOCKED_TOP);
- mDisplayContent.setLayoutNeeded();
- }
-
-
- boolean isAdjustedForMinimizedDockedStack() {
- return mMinimizeAmount != 0f;
+ return inSplitScreenPrimaryWindowingMode() && !isFocusable();
}
@Override
@@ -4362,17 +3722,6 @@
pw.println(prefix + "mStackId=" + getRootTaskId());
pw.println(prefix + "mDeferRemoval=" + mDeferRemoval);
pw.println(prefix + "mBounds=" + getRawBounds().toShortString());
- if (mMinimizeAmount != 0f) {
- pw.println(prefix + "mMinimizeAmount=" + mMinimizeAmount);
- }
- if (mAdjustedForIme) {
- pw.println(prefix + "mAdjustedForIme=true");
- pw.println(prefix + "mAdjustImeAmount=" + mAdjustImeAmount);
- pw.println(prefix + "mAdjustDividerAmount=" + mAdjustDividerAmount);
- }
- if (!mAdjustedBounds.isEmpty()) {
- pw.println(prefix + "mAdjustedBounds=" + mAdjustedBounds.toShortString());
- }
for (int taskNdx = mChildren.size() - 1; taskNdx >= 0; taskNdx--) {
mChildren.get(taskNdx).dump(pw, prefix + " ", dumpAll);
}
@@ -4391,39 +3740,6 @@
}
/**
- * For docked workspace (or workspace that's side-by-side to the docked), provides
- * information which side of the screen was the dock anchored.
- */
- int getDockSide() {
- return getDockSide(mDisplayContent.getConfiguration(), getRawBounds());
- }
-
- int getDockSideForDisplay(DisplayContent dc) {
- return getDockSide(dc, dc.getConfiguration(), getRawBounds());
- }
-
- int getDockSide(Configuration parentConfig, Rect bounds) {
- if (mDisplayContent == null) {
- return DOCKED_INVALID;
- }
- return getDockSide(mDisplayContent, parentConfig, bounds);
- }
-
- private int getDockSide(DisplayContent dc, Configuration parentConfig, Rect bounds) {
- return dc.getDockedDividerController().getDockSide(bounds,
- parentConfig.windowConfiguration.getBounds(),
- parentConfig.orientation, parentConfig.windowConfiguration.getRotation());
- }
-
- boolean hasTaskForUser(int userId) {
- final PooledPredicate p = PooledLambda.obtainPredicate(
- Task::isTaskForUser, PooledLambda.__(Task.class), userId);
- final Task task = getTask(p);
- p.recycle();
- return task != null;
- }
-
- /**
* Sets the current picture-in-picture aspect ratio.
*/
void setPictureInPictureAspectRatio(float aspectRatio) {
@@ -4639,16 +3955,11 @@
bounds.dumpDebug(proto, BOUNDS);
}
getOverrideDisplayedBounds().dumpDebug(proto, DISPLAYED_BOUNDS);
- mAdjustedBounds.dumpDebug(proto, ADJUSTED_BOUNDS);
if (mLastNonFullscreenBounds != null) {
mLastNonFullscreenBounds.dumpDebug(proto, LAST_NON_FULLSCREEN_BOUNDS);
}
proto.write(DEFER_REMOVAL, mDeferRemoval);
- proto.write(MINIMIZE_AMOUNT, mMinimizeAmount);
- proto.write(ADJUSTED_FOR_IME, mAdjustedForIme);
- proto.write(ADJUST_IME_AMOUNT, mAdjustImeAmount);
- proto.write(ADJUST_DIVIDER_AMOUNT, mAdjustDividerAmount);
proto.write(ANIMATING_BOUNDS, mBoundsAnimating);
if (mSurfaceControl != null) {
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index b2d2f62..6d7f8fb 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -35,12 +35,10 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
-import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.content.pm.PackageManager.NOTIFY_PACKAGE_USE_ACTIVITY;
import static android.content.pm.PackageManager.PERMISSION_DENIED;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-import static android.graphics.Rect.copyOrNull;
import static android.os.PowerManager.PARTIAL_WAKE_LOCK;
import static android.os.Process.INVALID_UID;
import static android.os.Process.SYSTEM_UID;
@@ -210,17 +208,6 @@
/** True if the docked stack is currently being resized. */
private boolean mDockedStackResizing;
- /**
- * True if there are pending docked bounds that need to be applied after
- * {@link #mDockedStackResizing} is reset to false.
- */
- private boolean mHasPendingDockedBounds;
- private Rect mPendingDockedBounds;
- private Rect mPendingTempDockedTaskBounds;
- private Rect mPendingTempDockedTaskInsetBounds;
- private Rect mPendingTempOtherTaskBounds;
- private Rect mPendingTempOtherTaskInsetBounds;
-
// Activity actions an app cannot start if it uses a permission which is not granted.
private static final ArrayMap<String, String> ACTION_TO_RUNTIME_PERMISSION =
new ArrayMap<>();
@@ -387,15 +374,6 @@
*/
private final ArraySet<Integer> mResizingTasksDuringAnimation = new ArraySet<>();
-
- /**
- * If set to {@code false} all calls to resize the docked stack {@link #resizeDockedStackLocked}
- * will be ignored. Useful for the case where the caller is handling resizing of other stack and
- * moving tasks around and doesn't want dock stack to be resized due to an automatic trigger
- * like the docked stack going empty.
- */
- private boolean mAllowDockedStackResize = true;
-
private KeyguardController mKeyguardController;
private PowerManager mPowerManager;
@@ -1541,12 +1519,6 @@
}
otherStack.setWindowingMode(WINDOWING_MODE_UNDEFINED);
}
-
- // Also disable docked stack resizing since we have manually adjusted the
- // size of other stacks above and we don't want to trigger a docked stack
- // resize when we remove task from it below and it is detached from the
- // display because it no longer contains any tasks.
- mAllowDockedStackResize = false;
}
// If we are moving from the pinned stack, then the animation takes care of updating
@@ -1563,7 +1535,6 @@
mRootWindowContainer.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS);
mRootWindowContainer.resumeFocusedStacksTopActivities();
} finally {
- mAllowDockedStackResize = true;
mService.continueWindowLayout();
}
}
@@ -1580,120 +1551,6 @@
mDockedStackResizing = resizing;
mWindowManager.setDockedStackResizing(resizing);
-
- if (!resizing && mHasPendingDockedBounds) {
- resizeDockedStackLocked(mPendingDockedBounds, mPendingTempDockedTaskBounds,
- mPendingTempDockedTaskInsetBounds, mPendingTempOtherTaskBounds,
- mPendingTempOtherTaskInsetBounds, PRESERVE_WINDOWS);
-
- mHasPendingDockedBounds = false;
- mPendingDockedBounds = null;
- mPendingTempDockedTaskBounds = null;
- mPendingTempDockedTaskInsetBounds = null;
- mPendingTempOtherTaskBounds = null;
- mPendingTempOtherTaskInsetBounds = null;
- }
- }
-
- void resizeDockedStackLocked(Rect dockedBounds, Rect tempDockedTaskBounds,
- Rect tempDockedTaskInsetBounds, Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds,
- boolean preserveWindows) {
- resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds, tempDockedTaskInsetBounds,
- tempOtherTaskBounds, tempOtherTaskInsetBounds, preserveWindows,
- false /* deferResume */);
- }
-
- void resizeDockedStackLocked(Rect displayedBounds, Rect tempDockedTaskBounds,
- Rect tempDockedTaskInsetBounds, Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds,
- boolean preserveWindows, boolean deferResume) {
-
- if (!mAllowDockedStackResize) {
- // Docked stack resize currently disabled.
- return;
- }
-
- final ActivityStack stack =
- mRootWindowContainer.getDefaultDisplay().getRootSplitScreenPrimaryTask();
- if (stack == null) {
- Slog.w(TAG, "resizeDockedStackLocked: docked stack not found");
- return;
- }
-
- if (mDockedStackResizing) {
- mHasPendingDockedBounds = true;
- mPendingDockedBounds = copyOrNull(displayedBounds);
- mPendingTempDockedTaskBounds = copyOrNull(tempDockedTaskBounds);
- mPendingTempDockedTaskInsetBounds = copyOrNull(tempDockedTaskInsetBounds);
- mPendingTempOtherTaskBounds = copyOrNull(tempOtherTaskBounds);
- mPendingTempOtherTaskInsetBounds = copyOrNull(tempOtherTaskInsetBounds);
- }
-
- Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "resizeDockedStack");
- mService.deferWindowLayout();
- try {
- // Don't allow re-entry while resizing. E.g. due to docked stack detaching.
- mAllowDockedStackResize = false;
- ActivityRecord r = stack.topRunningActivity();
- stack.resize(displayedBounds, tempDockedTaskBounds,
- !PRESERVE_WINDOWS, DEFER_RESUME);
-
- // TODO: Checking for isAttached might not be needed as if the user passes in null
- // dockedBounds then they want the docked stack to be dismissed.
- if (stack.getWindowingMode() == WINDOWING_MODE_FULLSCREEN
- || (displayedBounds == null && !stack.isAttached())) {
- // The dock stack either was dismissed or went fullscreen, which is kinda the same.
- // In this case we make all other static stacks fullscreen and move all
- // docked stack tasks to the fullscreen stack.
- moveTasksToFullscreenStackLocked(stack, ON_TOP);
-
- // stack shouldn't contain anymore activities, so nothing to resume.
- r = null;
- } else {
- // Docked stacks occupy a dedicated region on screen so the size of all other
- // static stacks need to be adjusted so they don't overlap with the docked stack.
- // We get the bounds to use from window manager which has been adjusted for any
- // screen controls and is also the same for all stacks.
- final DisplayContent display = mRootWindowContainer.getDefaultDisplay();
- final Rect otherTaskRect = new Rect();
- for (int i = display.getStackCount() - 1; i >= 0; --i) {
- final ActivityStack current = display.getStackAt(i);
- if (!current.inSplitScreenSecondaryWindowingMode()) {
- continue;
- }
- if (!current.affectedBySplitScreenResize()) {
- continue;
- }
- if (mDockedStackResizing && !current.isTopActivityVisible()) {
- // Non-visible stacks get resized once we're done with the resize
- // interaction.
- continue;
- }
- current.getStackDockedModeBounds(displayedBounds,
- tempOtherTaskBounds /* currentTempTaskBounds */,
- tempRect /* outStackBounds */,
- otherTaskRect /* outTempTaskBounds */);
-
- if (tempRect.isEmpty()) {
- // If this scenario is hit, it means something is not working right.
- // Empty/null bounds implies fullscreen. In the event that this stack
- // *should* be fullscreen, its mode should be set explicitly in a form
- // of setWindowingMode so that other parts of the system are updated
- // properly.
- throw new IllegalArgumentException("Trying to set null bounds on a"
- + " non-fullscreen stack");
- }
-
- current.resize(tempRect, tempOtherTaskBounds, preserveWindows, deferResume);
- }
- }
- if (!deferResume) {
- stack.ensureVisibleActivitiesConfiguration(r, preserveWindows);
- }
- } finally {
- mAllowDockedStackResize = true;
- mService.continueWindowLayout();
- Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
- }
}
private void removeStackInSurfaceTransaction(ActivityStack stack) {
@@ -2723,9 +2580,6 @@
mService.deferWindowLayout();
try {
if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
- mWindowManager.setDockedStackCreateStateLocked(
- activityOptions.getSplitScreenCreateMode(), null /* initialBounds */);
-
// Defer updating the stack in which recents is until the app transition is done, to
// not run into issues where we still need to draw the task in recents but the
// docked stack is already created.
@@ -2801,24 +2655,6 @@
// the window renders full-screen with the background filling the void. Also only
// call this at the end to make sure that tasks exists on the window manager side.
setResizingDuringAnimation(task);
-
- final DisplayContent display = task.getStack().getDisplay();
- final ActivityStack topSecondaryStack =
- display.getTopStackInWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
- if (topSecondaryStack != null && topSecondaryStack.isActivityTypeHome()) {
- // If the home activity is the top split-screen secondary stack, then the
- // primary split-screen stack is in the minimized mode which means it can't
- // receive input keys, so we should move the focused app to the home app so that
- // window manager can correctly calculate the focus window that can receive
- // input keys.
- display.moveHomeActivityToTop(
- "startActivityFromRecents: homeVisibleInSplitScreen");
-
- // Immediately update the minimized docked stack mode, the upcoming animation
- // for the docked activity (WMS.overridePendingAppTransitionMultiThumbFuture)
- // will do the animation to the target bounds
- mWindowManager.checkSplitScreenMinimizedChanged(false /* animate */);
- }
}
mService.continueWindowLayout();
}
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
index 510072d..ca856ca 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
@@ -169,12 +169,6 @@
public abstract List<IBinder> getTopVisibleActivities();
/**
- * Callback for window manager to let activity manager know that docked stack changes its
- * minimized state.
- */
- public abstract void notifyDockedStackMinimizedChanged(boolean minimized);
-
- /**
* Notify listeners that contents are drawn for the first time on a single task display.
*
* @param displayId An ID of the display on which contents are drawn.
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index d2d7ad3..770dabf 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -31,12 +31,12 @@
import static android.app.ActivityManagerInternal.ALLOW_NON_FULL;
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static android.app.ActivityTaskManager.RESIZE_MODE_PRESERVE_WINDOW;
-import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
+import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
@@ -2309,9 +2309,7 @@
@Override
public boolean setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) {
if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
- return setTaskWindowingModeSplitScreenPrimary(taskId,
- SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT,
- toTop, ANIMATE, null /* initialBounds */, true /* showRecents */);
+ return setTaskWindowingModeSplitScreenPrimary(taskId, toTop);
}
enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()");
synchronized (mGlobalLock) {
@@ -2681,10 +2679,6 @@
throw new IllegalArgumentException("moveTaskToStack: Attempt to move task "
+ taskId + " to stack " + stackId);
}
- if (stack.inSplitScreenPrimaryWindowingMode()) {
- mWindowManager.setDockedStackCreateStateLocked(
- SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
- }
task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
"moveTaskToStack");
} finally {
@@ -2697,22 +2691,11 @@
* Moves the specified task to the primary-split-screen stack.
*
* @param taskId Id of task to move.
- * @param createMode The mode the primary split screen stack should be created in if it doesn't
- * exist already. See
- * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT}
- * and
- * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT}
* @param toTop If the task and stack should be moved to the top.
- * @param animate Whether we should play an animation for the moving the task.
- * @param initialBounds If the primary stack gets created, it will use these bounds for the
- * stack. Pass {@code null} to use default bounds.
- * @param showRecents If the recents activity should be shown on the other side of the task
- * going into split-screen mode.
* @return Whether the task was successfully put into splitscreen.
*/
@Override
- public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode,
- boolean toTop, boolean animate, Rect initialBounds, boolean showRecents) {
+ public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, boolean toTop) {
enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
"setTaskWindowingModeSplitScreenPrimary()");
synchronized (mGlobalLock) {
@@ -4273,6 +4256,7 @@
}
}
+ // TODO(b/149338177): remove when CTS no-longer requires it
@Override
public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
Rect tempDockedTaskInsetBounds,
@@ -4281,9 +4265,42 @@
long ident = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) {
- mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
- tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
- PRESERVE_WINDOWS);
+ final DisplayContent dc = mRootWindowContainer.getDefaultDisplay();
+ TaskTile primary = null;
+ TaskTile secondary = null;
+ for (int i = dc.getStackCount() - 1; i >= 0; --i) {
+ final TaskTile t = dc.getStackAt(i).asTile();
+ if (t == null) {
+ continue;
+ }
+ if (t.getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
+ primary = t;
+ } else if (t.getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY) {
+ secondary = t;
+ }
+ }
+ if (primary == null || secondary == null) {
+ return;
+ }
+ final WindowContainerTransaction wct = new WindowContainerTransaction();
+ final Rect primaryRect =
+ tempDockedTaskInsetBounds != null ? tempDockedTaskInsetBounds
+ : (tempDockedTaskBounds != null ? tempDockedTaskBounds
+ : dockedBounds);
+ wct.setBounds(primary.mRemoteToken, primaryRect);
+ Rect otherRect = tempOtherTaskInsetBounds != null ? tempOtherTaskInsetBounds
+ : tempOtherTaskBounds;
+ if (otherRect == null) {
+ // Temporary estimation... again this is just for tests.
+ otherRect = new Rect(secondary.getBounds());
+ if (dc.getBounds().width() > dc.getBounds().height()) {
+ otherRect.left = primaryRect.right + 6;
+ } else {
+ otherRect.top = primaryRect.bottom + 6;
+ }
+ }
+ wct.setBounds(secondary.mRemoteToken, otherRect);
+ mTaskOrganizerController.applyContainerTransaction(wct, null /* organizer */);
}
} finally {
Binder.restoreCallingIdentity(ident);
@@ -6136,13 +6153,6 @@
}
@Override
- public void notifyDockedStackMinimizedChanged(boolean minimized) {
- synchronized (mGlobalLock) {
- mRootWindowContainer.setDockedStackMinimized(minimized);
- }
- }
-
- @Override
public int startActivitiesAsPackage(String packageName, @Nullable String featureId,
int userId, Intent[] intents, Bundle bOptions) {
Objects.requireNonNull(intents, "intents");
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index ca09537..4916c31 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -446,8 +446,6 @@
? topOpeningAnim.getStatusBarTransitionsStartTime()
: SystemClock.uptimeMillis(),
AnimationAdapter.STATUS_BAR_TRANSITION_DURATION);
- mDisplayContent.getDockedDividerController()
- .notifyAppTransitionStarting(openingApps, transit);
if (mRemoteAnimationController != null) {
mRemoteAnimationController.goodToGo();
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 30e8da2..5cd2930 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -94,7 +94,6 @@
import static com.android.server.wm.DisplayContentProto.CLOSING_APPS;
import static com.android.server.wm.DisplayContentProto.DISPLAY_FRAMES;
import static com.android.server.wm.DisplayContentProto.DISPLAY_INFO;
-import static com.android.server.wm.DisplayContentProto.DOCKED_STACK_DIVIDER_CONTROLLER;
import static com.android.server.wm.DisplayContentProto.DPI;
import static com.android.server.wm.DisplayContentProto.FOCUSED_APP;
import static com.android.server.wm.DisplayContentProto.FOCUSED_ROOT_TASK_ID;
@@ -131,7 +130,7 @@
import static com.android.server.wm.WindowManagerService.H.REPORT_FOCUS_CHANGE;
import static com.android.server.wm.WindowManagerService.H.REPORT_HARD_KEYBOARD_STATUS_CHANGE;
import static com.android.server.wm.WindowManagerService.H.REPORT_LOSING_FOCUS;
-import static com.android.server.wm.WindowManagerService.H.UPDATE_DOCKED_STACK_DIVIDER;
+import static com.android.server.wm.WindowManagerService.H.UPDATE_MULTI_WINDOW_STACKS;
import static com.android.server.wm.WindowManagerService.H.WINDOW_HIDE_TIMEOUT;
import static com.android.server.wm.WindowManagerService.LAYOUT_REPEAT_THRESHOLD;
import static com.android.server.wm.WindowManagerService.SEAMLESS_ROTATION_TIMEOUT_DURATION;
@@ -1005,7 +1004,7 @@
mDisplayPolicy.systemReady();
}
mWindowCornerRadius = mDisplayPolicy.getWindowCornerRadius();
- mDividerControllerLocked = new DockedStackDividerController(mWmService, this);
+ mDividerControllerLocked = new DockedStackDividerController(this);
mPinnedStackControllerLocked = new PinnedStackController(mWmService, this);
final SurfaceControl.Builder b = mWmService.makeSurfaceBuilder(mSession)
@@ -2232,12 +2231,6 @@
* for bounds calculations.
*/
void preOnConfigurationChanged() {
- final DockedStackDividerController dividerController = getDockedDividerController();
-
- if (dividerController != null) {
- getDockedDividerController().onConfigurationChanged();
- }
-
final PinnedStackController pinnedStackController = getPinnedStackController();
if (pinnedStackController != null) {
@@ -2621,10 +2614,11 @@
// We also remove the outside touch area for resizing for all freeform
// tasks (including the focused).
// We save the focused task region once we find it, and add it back at the end.
- // If the task is home stack and it is resizable in the minimized state, we want to
- // exclude the docked stack from touch so we need the entire screen area and not just a
+ // If the task is home stack and it is resizable and visible (top of its root task), we want
+ // to exclude the docked stack from touch so we need the entire screen area and not just a
// small portion which the home stack currently is resized to.
- if (task.isActivityTypeHome() && task.getStack().isMinimizedDockAndHomeStackResizable()) {
+ if (task.isActivityTypeHome() && task.isVisible() && task.getStack().getTile() != null
+ && task.isResizeable()) {
mDisplayContent.getBounds(mTmpRect);
} else {
task.getDimBounds(mTmpRect);
@@ -2633,6 +2627,8 @@
if (task == focusedTask) {
// Add the focused task rect back into the exclude region once we are done
// processing stacks.
+ // NOTE: this *looks* like a no-op, but this usage of mTmpRect2 is expected by
+ // updateTouchExcludeRegion.
mTmpRect2.set(mTmpRect);
}
@@ -2746,58 +2742,6 @@
return mDeferredRemoval;
}
- boolean animateForIme(float interpolatedValue, float animationTarget,
- float dividerAnimationTarget) {
- boolean updated = false;
-
- for (int i = mTaskContainers.getChildCount() - 1; i >= 0; --i) {
- final ActivityStack stack = mTaskContainers.getChildAt(i);
- if (stack == null || !stack.isAdjustedForIme()) {
- continue;
- }
-
- if (interpolatedValue >= 1f && animationTarget == 0f && dividerAnimationTarget == 0f) {
- stack.resetAdjustedForIme(true /* adjustBoundsNow */);
- updated = true;
- } else {
- mDividerControllerLocked.mLastAnimationProgress =
- mDividerControllerLocked.getInterpolatedAnimationValue(interpolatedValue);
- mDividerControllerLocked.mLastDividerProgress =
- mDividerControllerLocked.getInterpolatedDividerValue(interpolatedValue);
- updated |= stack.updateAdjustForIme(
- mDividerControllerLocked.mLastAnimationProgress,
- mDividerControllerLocked.mLastDividerProgress,
- false /* force */);
- }
- if (interpolatedValue >= 1f) {
- stack.endImeAdjustAnimation();
- }
- }
-
- return updated;
- }
-
- boolean clearImeAdjustAnimation() {
- boolean changed = false;
- for (int i = mTaskContainers.getChildCount() - 1; i >= 0; --i) {
- final ActivityStack stack = mTaskContainers.getChildAt(i);
- if (stack != null && stack.isAdjustedForIme()) {
- stack.resetAdjustedForIme(true /* adjustBoundsNow */);
- changed = true;
- }
- }
- return changed;
- }
-
- void beginImeAdjustAnimation() {
- for (int i = mTaskContainers.getChildCount() - 1; i >= 0; --i) {
- final ActivityStack stack = mTaskContainers.getChildAt(i);
- if (stack.isVisible() && stack.isAdjustedForIme()) {
- stack.beginImeAdjustAnimation();
- }
- }
- }
-
void adjustForImeIfNeeded() {
final WindowState imeWin = mInputMethodWindow;
final boolean imeVisible = imeWin != null && imeWin.isVisibleLw()
@@ -2892,7 +2836,6 @@
final ActivityStack stack = mTaskContainers.getChildAt(i);
stack.dumpDebug(proto, TASKS, logLevel);
}
- mDividerControllerLocked.dumpDebug(proto, DOCKED_STACK_DIVIDER_CONTROLLER);
for (int i = mOverlayContainers.getChildCount() - 1; i >= 0; --i) {
final WindowToken windowToken = mOverlayContainers.getChildAt(i);
windowToken.dumpDebug(proto, OVERLAY_WINDOWS, logLevel);
@@ -3062,8 +3005,6 @@
}
pw.println();
- mDividerControllerLocked.dump(prefix, pw);
- pw.println();
mPinnedStackControllerLocked.dump(prefix, pw);
pw.println();
@@ -4084,7 +4025,7 @@
mInputMonitor.updateInputWindowsLw(false /*force*/);
}
- mWmService.mH.sendEmptyMessage(UPDATE_DOCKED_STACK_DIVIDER);
+ mWmService.mH.sendEmptyMessage(UPDATE_MULTI_WINDOW_STACKS);
}
/**
@@ -4692,17 +4633,18 @@
@Override
int getOrientation(int candidate) {
if (isStackVisible(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY)) {
- // Apps and their containers are not allowed to specify an orientation while the
- // docked stack is visible...except for the home stack if the docked stack is
- // minimized and it actually set something and the bounds is different from the
- // display.
+ // Apps and their containers are not allowed to specify an orientation while using
+ // root tasks...except for the home stack if it is not resizable and currently
+ // visible (top of) its root task.
if (mRootHomeTask != null && mRootHomeTask.isVisible()
- && mDividerControllerLocked.isMinimizedDock()
- && !(mDividerControllerLocked.isHomeStackResizable()
- && mRootHomeTask.matchParentBounds())) {
- final int orientation = mRootHomeTask.getOrientation();
- if (orientation != SCREEN_ORIENTATION_UNSET) {
- return orientation;
+ && mRootHomeTask.getTile() != null) {
+ final Task topMost = mRootHomeTask.getTopMostTask();
+ final boolean resizable = topMost == null && topMost.isResizeable();
+ if (!(resizable && mRootHomeTask.matchParentBounds())) {
+ final int orientation = mRootHomeTask.getOrientation();
+ if (orientation != SCREEN_ORIENTATION_UNSET) {
+ return orientation;
+ }
}
}
return SCREEN_ORIENTATION_UNSPECIFIED;
@@ -6167,8 +6109,6 @@
t.removeAllChildren();
}
}
- mDividerControllerLocked.setMinimizedDockedStack(false /* minimized */,
- false /* animate */);
} finally {
final ActivityStack topFullscreenStack =
getTopStackInWindowingMode(WINDOWING_MODE_FULLSCREEN);
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index f02a9dd..497c473 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -1178,8 +1178,6 @@
return R.anim.dock_left_enter;
}
}
- } else if (win.getAttrs().type == TYPE_DOCK_DIVIDER) {
- return selectDockedDividerAnimation(win, transit);
}
if (transit == TRANSIT_PREVIEW_DONE) {
@@ -1204,36 +1202,6 @@
return ANIMATION_STYLEABLE;
}
- private int selectDockedDividerAnimation(WindowState win, int transit) {
- int insets = mDisplayContent.getDockedDividerController().getContentInsets();
-
- // If the divider is behind the navigation bar, don't animate.
- final Rect frame = win.getFrameLw();
- final boolean behindNavBar = mNavigationBar != null
- && ((mNavigationBarPosition == NAV_BAR_BOTTOM
- && frame.top + insets >= mNavigationBar.getFrameLw().top)
- || (mNavigationBarPosition == NAV_BAR_RIGHT
- && frame.left + insets >= mNavigationBar.getFrameLw().left)
- || (mNavigationBarPosition == NAV_BAR_LEFT
- && frame.right - insets <= mNavigationBar.getFrameLw().right));
- final boolean landscape = frame.height() > frame.width();
- final boolean offscreenLandscape = landscape && (frame.right - insets <= 0
- || frame.left + insets >= win.getDisplayFrameLw().right);
- final boolean offscreenPortrait = !landscape && (frame.top - insets <= 0
- || frame.bottom + insets >= win.getDisplayFrameLw().bottom);
- final boolean offscreen = offscreenLandscape || offscreenPortrait;
- if (behindNavBar || offscreen) {
- return ANIMATION_STYLEABLE;
- }
- if (transit == TRANSIT_ENTER || transit == TRANSIT_SHOW) {
- return R.anim.fade_in;
- } else if (transit == TRANSIT_EXIT) {
- return R.anim.fade_out;
- } else {
- return ANIMATION_STYLEABLE;
- }
- }
-
/**
* Called when a new system UI visibility is being reported, allowing
* the policy to adjust what is actually reported.
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index 958c8ae..20738ed 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -16,330 +16,26 @@
package com.android.server.wm;
-import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
-import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
-import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
-import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
-import static android.view.Surface.ROTATION_270;
-import static android.view.Surface.ROTATION_90;
-import static android.view.WindowManager.DOCKED_BOTTOM;
-import static android.view.WindowManager.DOCKED_INVALID;
-import static android.view.WindowManager.DOCKED_LEFT;
-import static android.view.WindowManager.DOCKED_RIGHT;
-import static android.view.WindowManager.DOCKED_TOP;
-import static android.view.WindowManager.TRANSIT_NONE;
-import static android.view.WindowManagerPolicyConstants.NAV_BAR_LEFT;
-import static android.view.WindowManagerPolicyConstants.NAV_BAR_RIGHT;
-
-import static com.android.server.wm.AppTransition.DEFAULT_APP_TRANSITION_DURATION;
-import static com.android.server.wm.AppTransition.TOUCH_RESPONSE_INTERPOLATOR;
-import static com.android.server.wm.DockedStackDividerControllerProto.MINIMIZED_DOCK;
-import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
-import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
-
-import android.content.Context;
-import android.content.res.Configuration;
import android.graphics.Rect;
-import android.os.RemoteCallbackList;
-import android.os.RemoteException;
-import android.util.ArraySet;
-import android.util.Slog;
-import android.util.proto.ProtoOutputStream;
-import android.view.DisplayCutout;
-import android.view.DisplayInfo;
-import android.view.IDockedStackListener;
-import android.view.animation.AnimationUtils;
-import android.view.animation.Interpolator;
-import android.view.animation.PathInterpolator;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.inputmethod.SoftInputShowHideReason;
-import com.android.internal.policy.DividerSnapAlgorithm;
-import com.android.internal.policy.DockedDividerUtils;
-import com.android.server.LocalServices;
-import com.android.server.inputmethod.InputMethodManagerInternal;
-import com.android.server.wm.WindowManagerService.H;
-
-import java.io.PrintWriter;
/**
* Keeps information about the docked stack divider.
*/
public class DockedStackDividerController {
- private static final String TAG = TAG_WITH_CLASS_NAME ? "DockedStackDividerController" : TAG_WM;
-
- /**
- * The fraction during the maximize/clip reveal animation the divider meets the edge of the clip
- * revealing surface at the earliest.
- */
- private static final float CLIP_REVEAL_MEET_EARLIEST = 0.6f;
-
- /**
- * The fraction during the maximize/clip reveal animation the divider meets the edge of the clip
- * revealing surface at the latest.
- */
- private static final float CLIP_REVEAL_MEET_LAST = 1f;
-
- /**
- * If the app translates at least CLIP_REVEAL_MEET_FRACTION_MIN * minimize distance, we start
- * meet somewhere between {@link #CLIP_REVEAL_MEET_LAST} and {@link #CLIP_REVEAL_MEET_EARLIEST}.
- */
- private static final float CLIP_REVEAL_MEET_FRACTION_MIN = 0.4f;
-
- /**
- * If the app translates equals or more than CLIP_REVEAL_MEET_FRACTION_MIN * minimize distance,
- * we meet at {@link #CLIP_REVEAL_MEET_EARLIEST}.
- */
- private static final float CLIP_REVEAL_MEET_FRACTION_MAX = 0.8f;
-
- private static final Interpolator IME_ADJUST_ENTRY_INTERPOLATOR =
- new PathInterpolator(0.2f, 0f, 0.1f, 1f);
-
- private static final long IME_ADJUST_ANIM_DURATION = 280;
-
- private static final long IME_ADJUST_DRAWN_TIMEOUT = 200;
-
- private static final int DIVIDER_WIDTH_INACTIVE_DP = 4;
-
- private final WindowManagerService mService;
private final DisplayContent mDisplayContent;
- private int mDividerWindowWidth;
- private int mDividerWindowWidthInactive;
- private int mDividerInsets;
- private int mTaskHeightInMinimizedMode;
private boolean mResizing;
- private WindowState mWindow;
- private final Rect mTmpRect = new Rect();
- private final Rect mTmpRect2 = new Rect();
- private final Rect mTmpRect3 = new Rect();
- private final Rect mLastRect = new Rect();
- private boolean mLastVisibility = false;
- private final RemoteCallbackList<IDockedStackListener> mDockedStackListeners
- = new RemoteCallbackList<>();
- private boolean mMinimizedDock;
- private int mOriginalDockedSide = DOCKED_INVALID;
- private boolean mAnimatingForMinimizedDockedStack;
- private boolean mAnimationStarted;
- private long mAnimationStartTime;
- private float mAnimationStart;
- private float mAnimationTarget;
- private long mAnimationDuration;
- private boolean mAnimationStartDelayed;
- private final Interpolator mMinimizedDockInterpolator;
- private float mMaximizeMeetFraction;
private final Rect mTouchRegion = new Rect();
- private boolean mAnimatingForIme;
- private boolean mAdjustedForIme;
- private int mImeHeight;
- private WindowState mDelayedImeWin;
- private boolean mAdjustedForDivider;
- private float mDividerAnimationStart;
- private float mDividerAnimationTarget;
- float mLastAnimationProgress;
- float mLastDividerProgress;
- private final DividerSnapAlgorithm[] mSnapAlgorithmForRotation = new DividerSnapAlgorithm[4];
- private boolean mImeHideRequested;
- private ActivityStack mDimmedStack;
- DockedStackDividerController(WindowManagerService service, DisplayContent displayContent) {
- mService = service;
+ DockedStackDividerController(DisplayContent displayContent) {
mDisplayContent = displayContent;
- final Context context = service.mContext;
- mMinimizedDockInterpolator = AnimationUtils.loadInterpolator(
- context, android.R.interpolator.fast_out_slow_in);
- loadDimens();
- }
-
- int getSmallestWidthDpForBounds(Rect bounds) {
- final DisplayInfo di = mDisplayContent.getDisplayInfo();
-
- final int baseDisplayWidth = mDisplayContent.mBaseDisplayWidth;
- final int baseDisplayHeight = mDisplayContent.mBaseDisplayHeight;
- int minWidth = Integer.MAX_VALUE;
-
- // Go through all screen orientations and find the orientation in which the task has the
- // smallest width.
- for (int rotation = 0; rotation < 4; rotation++) {
- mTmpRect.set(bounds);
- mDisplayContent.rotateBounds(di.rotation, rotation, mTmpRect);
- final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270);
- mTmpRect2.set(0, 0,
- rotated ? baseDisplayHeight : baseDisplayWidth,
- rotated ? baseDisplayWidth : baseDisplayHeight);
- final int orientation = mTmpRect2.width() <= mTmpRect2.height()
- ? ORIENTATION_PORTRAIT
- : ORIENTATION_LANDSCAPE;
- final int dockSide = getDockSide(mTmpRect, mTmpRect2, orientation, rotation);
- final int position = DockedDividerUtils.calculatePositionForBounds(mTmpRect, dockSide,
- getContentWidth());
-
- final DisplayCutout displayCutout = mDisplayContent.calculateDisplayCutoutForRotation(
- rotation).getDisplayCutout();
-
- // Since we only care about feasible states, snap to the closest snap target, like it
- // would happen when actually rotating the screen.
- final int snappedPosition = mSnapAlgorithmForRotation[rotation]
- .calculateNonDismissingSnapTarget(position).position;
- DockedDividerUtils.calculateBoundsForPosition(snappedPosition, dockSide, mTmpRect,
- mTmpRect2.width(), mTmpRect2.height(), getContentWidth());
- mDisplayContent.getDisplayPolicy().getStableInsetsLw(rotation, mTmpRect2.width(),
- mTmpRect2.height(), displayCutout, mTmpRect3);
- mService.intersectDisplayInsetBounds(mTmpRect2, mTmpRect3, mTmpRect);
- minWidth = Math.min(mTmpRect.width(), minWidth);
- }
- return (int) (minWidth / mDisplayContent.getDisplayMetrics().density);
- }
-
- /**
- * Get the current docked side. Determined by its location of {@param bounds} within
- * {@param displayRect} but if both are the same, it will try to dock to each side and determine
- * if allowed in its respected {@param orientation}.
- *
- * @param bounds bounds of the docked task to get which side is docked
- * @param displayRect bounds of the display that contains the docked task
- * @param orientation the origination of device
- * @return current docked side
- */
- int getDockSide(Rect bounds, Rect displayRect, int orientation, int rotation) {
- if (orientation == Configuration.ORIENTATION_PORTRAIT) {
- // Portrait mode, docked either at the top or the bottom.
- final int diff = (displayRect.bottom - bounds.bottom) - (bounds.top - displayRect.top);
- if (diff > 0) {
- return DOCKED_TOP;
- } else if (diff < 0) {
- return DOCKED_BOTTOM;
- }
- return canPrimaryStackDockTo(DOCKED_TOP, displayRect, rotation)
- ? DOCKED_TOP : DOCKED_BOTTOM;
- } else if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
- // Landscape mode, docked either on the left or on the right.
- final int diff = (displayRect.right - bounds.right) - (bounds.left - displayRect.left);
- if (diff > 0) {
- return DOCKED_LEFT;
- } else if (diff < 0) {
- return DOCKED_RIGHT;
- }
- return canPrimaryStackDockTo(DOCKED_LEFT, displayRect, rotation)
- ? DOCKED_LEFT : DOCKED_RIGHT;
- }
- return DOCKED_INVALID;
- }
-
- void getHomeStackBoundsInDockedMode(Configuration parentConfig, int dockSide, Rect outBounds) {
- final DisplayCutout displayCutout = mDisplayContent.getDisplayInfo().displayCutout;
- final int displayWidth = parentConfig.windowConfiguration.getBounds().width();
- final int displayHeight = parentConfig.windowConfiguration.getBounds().height();
- mDisplayContent.getDisplayPolicy().getStableInsetsLw(
- parentConfig.windowConfiguration.getRotation(), displayWidth, displayHeight,
- displayCutout, mTmpRect);
- int dividerSize = mDividerWindowWidth - 2 * mDividerInsets;
- // The offset in the left (landscape)/top (portrait) is calculated with the minimized
- // offset value with the divider size and any system insets in that direction.
- if (parentConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
- outBounds.set(0, mTaskHeightInMinimizedMode + dividerSize + mTmpRect.top,
- displayWidth, displayHeight);
- } else {
- // In landscape also inset the left/right side with the status bar height to match the
- // minimized size height in portrait mode.
- final int primaryTaskWidth = mTaskHeightInMinimizedMode + dividerSize + mTmpRect.top;
- int left = mTmpRect.left;
- int right = displayWidth - mTmpRect.right;
- if (dockSide == DOCKED_LEFT) {
- left += primaryTaskWidth;
- } else if (dockSide == DOCKED_RIGHT) {
- right -= primaryTaskWidth;
- }
- outBounds.set(left, 0, right, displayHeight);
- }
- }
-
- boolean isHomeStackResizable() {
- final ActivityStack homeStack = mDisplayContent.getRootHomeTask();
- if (homeStack == null) {
- return false;
- }
- final Task homeTask = homeStack.getTopMostTask();
- return homeTask != null && homeTask.isResizeable();
- }
-
- private void initSnapAlgorithmForRotations() {
- final Configuration baseConfig = mDisplayContent.getConfiguration();
-
- // Initialize the snap algorithms for all 4 screen orientations.
- final Configuration config = new Configuration();
- for (int rotation = 0; rotation < 4; rotation++) {
- final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270);
- final int dw = rotated
- ? mDisplayContent.mBaseDisplayHeight
- : mDisplayContent.mBaseDisplayWidth;
- final int dh = rotated
- ? mDisplayContent.mBaseDisplayWidth
- : mDisplayContent.mBaseDisplayHeight;
- final DisplayCutout displayCutout =
- mDisplayContent.calculateDisplayCutoutForRotation(rotation).getDisplayCutout();
- final DisplayPolicy displayPolicy = mDisplayContent.getDisplayPolicy();
- displayPolicy.getStableInsetsLw(rotation, dw, dh, displayCutout, mTmpRect);
- config.unset();
- config.orientation = (dw <= dh) ? ORIENTATION_PORTRAIT : ORIENTATION_LANDSCAPE;
-
- final int appWidth = displayPolicy.getNonDecorDisplayWidth(dw, dh, rotation,
- baseConfig.uiMode, displayCutout);
- final int appHeight = displayPolicy.getNonDecorDisplayHeight(dw, dh, rotation,
- baseConfig.uiMode, displayCutout);
- displayPolicy.getNonDecorInsetsLw(rotation, dw, dh, displayCutout, mTmpRect);
- final int leftInset = mTmpRect.left;
- final int topInset = mTmpRect.top;
-
- config.windowConfiguration.setAppBounds(leftInset /*left*/, topInset /*top*/,
- leftInset + appWidth /*right*/, topInset + appHeight /*bottom*/);
-
- final float density = mDisplayContent.getDisplayMetrics().density;
- config.screenWidthDp = (int) (displayPolicy.getConfigDisplayWidth(dw, dh, rotation,
- baseConfig.uiMode, displayCutout) / density);
- config.screenHeightDp = (int) (displayPolicy.getConfigDisplayHeight(dw, dh, rotation,
- baseConfig.uiMode, displayCutout) / density);
- final Context rotationContext = mService.mContext.createConfigurationContext(config);
- mSnapAlgorithmForRotation[rotation] = new DividerSnapAlgorithm(
- rotationContext.getResources(), dw, dh, getContentWidth(),
- config.orientation == ORIENTATION_PORTRAIT, mTmpRect);
- }
- }
-
- private void loadDimens() {
- final Context context = mService.mContext;
- mDividerWindowWidth = context.getResources().getDimensionPixelSize(
- com.android.internal.R.dimen.docked_stack_divider_thickness);
- mDividerInsets = context.getResources().getDimensionPixelSize(
- com.android.internal.R.dimen.docked_stack_divider_insets);
- mDividerWindowWidthInactive = WindowManagerService.dipToPixel(
- DIVIDER_WIDTH_INACTIVE_DP, mDisplayContent.getDisplayMetrics());
- mTaskHeightInMinimizedMode = context.getResources().getDimensionPixelSize(
- com.android.internal.R.dimen.task_height_of_minimized_mode);
- initSnapAlgorithmForRotations();
- }
-
- void onConfigurationChanged() {
- loadDimens();
}
boolean isResizing() {
return mResizing;
}
- int getContentWidth() {
- return mDividerWindowWidth - 2 * mDividerInsets;
- }
-
- int getContentInsets() {
- return mDividerInsets;
- }
-
- int getContentWidthInactive() {
- return mDividerWindowWidthInactive;
- }
-
void setResizing(boolean resizing) {
if (mResizing != resizing) {
mResizing = resizing;
@@ -353,676 +49,10 @@
void getTouchRegion(Rect outRegion) {
outRegion.set(mTouchRegion);
- if (mWindow != null) {
- outRegion.offset(mWindow.getFrameLw().left, mWindow.getFrameLw().top);
- }
}
private void resetDragResizingChangeReported() {
mDisplayContent.forAllWindows(WindowState::resetDragResizingChangeReported,
true /* traverseTopToBottom */ );
}
-
- void setWindow(WindowState window) {
- mWindow = window;
- reevaluateVisibility(false);
- }
-
- void reevaluateVisibility(boolean force) {
- if (mWindow == null) {
- return;
- }
- ActivityStack stack = mDisplayContent.getRootSplitScreenPrimaryTask();
-
- // If the stack is invisible, we policy force hide it in WindowAnimator.shouldForceHide
- final boolean visible = stack != null;
- if (mLastVisibility == visible && !force) {
- return;
- }
- mLastVisibility = visible;
- notifyDockedDividerVisibilityChanged(visible);
- if (!visible) {
- setResizeDimLayer(false, WINDOWING_MODE_UNDEFINED, 0f);
- }
- }
-
- private boolean wasVisible() {
- return mLastVisibility;
- }
-
- void setAdjustedForIme(
- boolean adjustedForIme, boolean adjustedForDivider,
- boolean animate, WindowState imeWin, int imeHeight) {
- if (mAdjustedForIme != adjustedForIme || (adjustedForIme && mImeHeight != imeHeight)
- || mAdjustedForDivider != adjustedForDivider) {
- if (animate && !mAnimatingForMinimizedDockedStack) {
- // Notify SystemUI to set the target docked stack size according current docked
- // state without animation when calling startImeAdjustAnimation.
- notifyDockedStackMinimizedChanged(mMinimizedDock, false /* animate */,
- isHomeStackResizable());
- startImeAdjustAnimation(adjustedForIme, adjustedForDivider, imeWin);
- } else {
- // Animation might be delayed, so only notify if we don't run an animation.
- notifyAdjustedForImeChanged(adjustedForIme || adjustedForDivider, 0 /* duration */);
- }
- mAdjustedForIme = adjustedForIme;
- mImeHeight = imeHeight;
- mAdjustedForDivider = adjustedForDivider;
- }
- }
-
- int getImeHeightAdjustedFor() {
- return mImeHeight;
- }
-
- void positionDockedStackedDivider(Rect frame) {
- ActivityStack stack = mDisplayContent.getRootSplitScreenPrimaryTask();
- if (stack == null) {
- // Unfortunately we might end up with still having a divider, even though the underlying
- // stack was already removed. This is because we are on AM thread and the removal of the
- // divider was deferred to WM thread and hasn't happened yet. In that case let's just
- // keep putting it in the same place it was before the stack was removed to have
- // continuity and prevent it from jumping to the center. It will get hidden soon.
- frame.set(mLastRect);
- return;
- } else {
- stack.getDimBounds(mTmpRect);
- }
- int side = stack.getDockSide();
- switch (side) {
- case DOCKED_LEFT:
- frame.set(mTmpRect.right - mDividerInsets, frame.top,
- mTmpRect.right + frame.width() - mDividerInsets, frame.bottom);
- break;
- case DOCKED_TOP:
- frame.set(frame.left, mTmpRect.bottom - mDividerInsets,
- mTmpRect.right, mTmpRect.bottom + frame.height() - mDividerInsets);
- break;
- case DOCKED_RIGHT:
- frame.set(mTmpRect.left - frame.width() + mDividerInsets, frame.top,
- mTmpRect.left + mDividerInsets, frame.bottom);
- break;
- case DOCKED_BOTTOM:
- frame.set(frame.left, mTmpRect.top - frame.height() + mDividerInsets,
- frame.right, mTmpRect.top + mDividerInsets);
- break;
- }
- mLastRect.set(frame);
- }
-
- private void notifyDockedDividerVisibilityChanged(boolean visible) {
- final int size = mDockedStackListeners.beginBroadcast();
- for (int i = 0; i < size; ++i) {
- final IDockedStackListener listener = mDockedStackListeners.getBroadcastItem(i);
- try {
- listener.onDividerVisibilityChanged(visible);
- } catch (RemoteException e) {
- Slog.e(TAG_WM, "Error delivering divider visibility changed event.", e);
- }
- }
- mDockedStackListeners.finishBroadcast();
- }
-
- /**
- * Checks if the primary stack is allowed to dock to a specific side based on its original dock
- * side.
- *
- * @param dockSide the side to see if it is valid
- * @return true if the side provided is valid
- */
- boolean canPrimaryStackDockTo(int dockSide, Rect parentRect, int rotation) {
- final DisplayPolicy policy = mDisplayContent.getDisplayPolicy();
- return isDockSideAllowed(dockSide, mOriginalDockedSide,
- policy.navigationBarPosition(parentRect.width(), parentRect.height(), rotation),
- policy.navigationBarCanMove());
- }
-
- @VisibleForTesting
- static boolean isDockSideAllowed(int dockSide, int originalDockSide, int navBarPosition,
- boolean navigationBarCanMove) {
- if (dockSide == DOCKED_TOP) {
- return true;
- }
-
- if (navigationBarCanMove) {
- // Only allow the dockside opposite to the nav bar position in landscape
- return dockSide == DOCKED_LEFT && navBarPosition == NAV_BAR_RIGHT
- || dockSide == DOCKED_RIGHT && navBarPosition == NAV_BAR_LEFT;
- }
-
- // Side is the same as original side
- if (dockSide == originalDockSide) {
- return true;
- }
-
- // Only if original docked side was top in portrait will allow left for landscape
- return dockSide == DOCKED_LEFT && originalDockSide == DOCKED_TOP;
- }
-
- void notifyDockedStackExistsChanged(boolean exists) {
- // TODO(multi-display): Perform all actions only for current display.
- final int size = mDockedStackListeners.beginBroadcast();
- for (int i = 0; i < size; ++i) {
- final IDockedStackListener listener = mDockedStackListeners.getBroadcastItem(i);
- try {
- listener.onDockedStackExistsChanged(exists);
- } catch (RemoteException e) {
- Slog.e(TAG_WM, "Error delivering docked stack exists changed event.", e);
- }
- }
- mDockedStackListeners.finishBroadcast();
- if (exists) {
- InputMethodManagerInternal inputMethodManagerInternal =
- LocalServices.getService(InputMethodManagerInternal.class);
- if (inputMethodManagerInternal != null) {
-
- // Hide the current IME to avoid problems with animations from IME adjustment when
- // attaching the docked stack.
- inputMethodManagerInternal.hideCurrentInputMethod(
- SoftInputShowHideReason.HIDE_DOCKED_STACK_ATTACHED);
- mImeHideRequested = true;
- }
-
- // If a primary stack was just created, it will not have access to display content at
- // this point so pass it from here to get a valid dock side.
- final ActivityStack stack =
- mDisplayContent.getRootSplitScreenPrimaryTask();
- mOriginalDockedSide = stack.getDockSideForDisplay(mDisplayContent);
- return;
- }
- mOriginalDockedSide = DOCKED_INVALID;
- setMinimizedDockedStack(false /* minimizedDock */, false /* animate */);
-
- if (mDimmedStack != null) {
- mDimmedStack.stopDimming();
- mDimmedStack = null;
- }
- }
-
- /**
- * Resets the state that IME hide has been requested. See {@link #isImeHideRequested}.
- */
- void resetImeHideRequested() {
- mImeHideRequested = false;
- }
-
- /**
- * The docked stack divider controller makes sure the IME gets hidden when attaching the docked
- * stack, to avoid animation problems. This flag indicates whether the request to hide the IME
- * has been sent in an asynchronous manner, and the IME should be treated as hidden already.
- *
- * @return whether IME hide request has been sent
- */
- boolean isImeHideRequested() {
- return mImeHideRequested;
- }
-
- private void notifyDockedStackMinimizedChanged(boolean minimizedDock, boolean animate,
- boolean isHomeStackResizable) {
- long animDuration = 0;
- if (animate) {
- final ActivityStack stack =
- mDisplayContent.getRootSplitScreenPrimaryTask();
- final long transitionDuration = isAnimationMaximizing()
- ? mDisplayContent.mAppTransition.getLastClipRevealTransitionDuration()
- : DEFAULT_APP_TRANSITION_DURATION;
- mAnimationDuration = (long)
- (transitionDuration * mService.getTransitionAnimationScaleLocked());
- mMaximizeMeetFraction = getClipRevealMeetFraction(stack);
- animDuration = (long) (mAnimationDuration * mMaximizeMeetFraction);
- }
- final int size = mDockedStackListeners.beginBroadcast();
- for (int i = 0; i < size; ++i) {
- final IDockedStackListener listener = mDockedStackListeners.getBroadcastItem(i);
- try {
- listener.onDockedStackMinimizedChanged(minimizedDock, animDuration,
- isHomeStackResizable);
- } catch (RemoteException e) {
- Slog.e(TAG_WM, "Error delivering minimized dock changed event.", e);
- }
- }
- mDockedStackListeners.finishBroadcast();
- // Only notify ATM after we update the remote listeners, otherwise it may trigger another
- // minimize change, which would lead to an inversion of states send to the listeners
- mService.mAtmInternal.notifyDockedStackMinimizedChanged(minimizedDock);
- }
-
- void notifyDockSideChanged(int newDockSide) {
- final int size = mDockedStackListeners.beginBroadcast();
- for (int i = 0; i < size; ++i) {
- final IDockedStackListener listener = mDockedStackListeners.getBroadcastItem(i);
- try {
- listener.onDockSideChanged(newDockSide);
- } catch (RemoteException e) {
- Slog.e(TAG_WM, "Error delivering dock side changed event.", e);
- }
- }
- mDockedStackListeners.finishBroadcast();
- }
-
- private void notifyAdjustedForImeChanged(boolean adjustedForIme, long animDuration) {
- final int size = mDockedStackListeners.beginBroadcast();
- for (int i = 0; i < size; ++i) {
- final IDockedStackListener listener = mDockedStackListeners.getBroadcastItem(i);
- try {
- listener.onAdjustedForImeChanged(adjustedForIme, animDuration);
- } catch (RemoteException e) {
- Slog.e(TAG_WM, "Error delivering adjusted for ime changed event.", e);
- }
- }
- mDockedStackListeners.finishBroadcast();
- }
-
- void registerDockedStackListener(IDockedStackListener listener) {
- mDockedStackListeners.register(listener);
- notifyDockedDividerVisibilityChanged(wasVisible());
- notifyDockedStackExistsChanged(
- mDisplayContent.getRootSplitScreenPrimaryTask() != null);
- notifyDockedStackMinimizedChanged(mMinimizedDock, false /* animate */,
- isHomeStackResizable());
- notifyAdjustedForImeChanged(mAdjustedForIme, 0 /* animDuration */);
-
- }
-
- /**
- * Shows a dim layer with {@param alpha} if {@param visible} is true and
- * {@param targetWindowingMode} isn't
- * {@link android.app.WindowConfiguration#WINDOWING_MODE_UNDEFINED} and there is a stack on the
- * display in that windowing mode.
- */
- void setResizeDimLayer(boolean visible, int targetWindowingMode, float alpha) {
- // TODO: Maybe only allow split-screen windowing modes?
- final ActivityStack stack = targetWindowingMode != WINDOWING_MODE_UNDEFINED
- ? mDisplayContent.getTopStackInWindowingMode(targetWindowingMode)
- : null;
- final ActivityStack dockedStack = mDisplayContent.getRootSplitScreenPrimaryTask();
- boolean visibleAndValid = visible && stack != null && dockedStack != null;
-
- // Ensure an old dim that was shown for the docked stack divider is removed so we don't end
- // up with dim layers that can no longer be removed.
- if (mDimmedStack != null && mDimmedStack != stack) {
- mDimmedStack.stopDimming();
- mDimmedStack = null;
- }
-
- if (visibleAndValid) {
- mDimmedStack = stack;
- stack.dim(alpha);
- }
- if (!visibleAndValid && stack != null) {
- mDimmedStack = null;
- stack.stopDimming();
- }
- }
-
- /**
- * Notifies the docked stack divider controller of a visibility change that happens without
- * an animation.
- */
- void notifyAppVisibilityChanged() {
- checkMinimizeChanged(false /* animate */);
- }
-
- void notifyAppTransitionStarting(ArraySet<ActivityRecord> openingApps, int appTransition) {
- final boolean wasMinimized = mMinimizedDock;
- checkMinimizeChanged(true /* animate */);
-
- // We were minimized, and now we are still minimized, but somebody is trying to launch an
- // app in docked stack, better show recent apps so we actually get unminimized! However do
- // not do this if keyguard is dismissed such as when the device is unlocking. This catches
- // any case that was missed in ActivityStarter.postStartActivityUncheckedProcessing because
- // we couldn't retrace the launch of the app in the docked stack to the launch from
- // homescreen.
- if (wasMinimized && mMinimizedDock && containsAppInDockedStack(openingApps)
- && appTransition != TRANSIT_NONE &&
- !AppTransition.isKeyguardGoingAwayTransit(appTransition)) {
- if (mService.mAtmInternal.isRecentsComponentHomeActivity(mService.mCurrentUserId)) {
- // When the home activity is the recents component and we are already minimized,
- // then there is nothing to do here since home is already visible
- } else {
- mService.showRecentApps();
- }
- }
- }
-
- /**
- * @return true if {@param apps} contains an activity in the docked stack, false otherwise.
- */
- private boolean containsAppInDockedStack(ArraySet<ActivityRecord> apps) {
- for (int i = apps.size() - 1; i >= 0; i--) {
- final ActivityRecord activity = apps.valueAt(i);
- if (activity.getTask() != null && activity.inSplitScreenPrimaryWindowingMode()) {
- return true;
- }
- }
- return false;
- }
-
- boolean isMinimizedDock() {
- return mMinimizedDock;
- }
-
- void checkMinimizeChanged(boolean animate) {
- if (mDisplayContent.getRootSplitScreenPrimaryTask() == null) {
- return;
- }
- final ActivityStack homeStack = mDisplayContent.getRootHomeTask();
- if (homeStack == null) {
- return;
- }
- final Task homeTask = homeStack.getTopMostTask();
- if (homeTask == null || !isWithinDisplay(homeTask)) {
- return;
- }
-
- // Do not minimize when dock is already minimized while keyguard is showing and not
- // occluded such as unlocking the screen
- if (mMinimizedDock && mService.mKeyguardOrAodShowingOnDefaultDisplay) {
- return;
- }
- final ActivityStack topSecondaryStack = mDisplayContent.getTopStackInWindowingMode(
- WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
- final RecentsAnimationController recentsAnim = mService.getRecentsAnimationController();
- final boolean minimizedForRecentsAnimation = recentsAnim != null &&
- recentsAnim.isSplitScreenMinimized();
- boolean homeVisible = homeTask.getTopVisibleActivity() != null;
- if (homeVisible && topSecondaryStack != null) {
- // Home should only be considered visible if it is greater or equal to the top secondary
- // stack in terms of z-order.
- homeVisible = homeStack.compareTo(topSecondaryStack) >= 0;
- }
- setMinimizedDockedStack(homeVisible || minimizedForRecentsAnimation, animate);
- }
-
- private boolean isWithinDisplay(Task task) {
- task.getBounds(mTmpRect);
- mDisplayContent.getBounds(mTmpRect2);
- return mTmpRect.intersect(mTmpRect2);
- }
-
- /**
- * Sets whether the docked stack is currently in a minimized state, i.e. all the tasks in the
- * docked stack are heavily clipped so you can only see a minimal peek state.
- *
- * @param minimizedDock Whether the docked stack is currently minimized.
- * @param animate Whether to animate the change.
- */
- void setMinimizedDockedStack(boolean minimizedDock, boolean animate) {
- final boolean wasMinimized = mMinimizedDock;
- mMinimizedDock = minimizedDock;
- if (minimizedDock == wasMinimized) {
- return;
- }
-
- final boolean imeChanged = clearImeAdjustAnimation();
- boolean minimizedChange = false;
- if (isHomeStackResizable()) {
- notifyDockedStackMinimizedChanged(minimizedDock, animate,
- true /* isHomeStackResizable */);
- minimizedChange = true;
- } else {
- if (minimizedDock) {
- if (animate) {
- startAdjustAnimation(0f, 1f);
- } else {
- minimizedChange |= setMinimizedDockedStack(true);
- }
- } else {
- if (animate) {
- startAdjustAnimation(1f, 0f);
- } else {
- minimizedChange |= setMinimizedDockedStack(false);
- }
- }
- }
- if (imeChanged || minimizedChange) {
- if (imeChanged && !minimizedChange) {
- Slog.d(TAG, "setMinimizedDockedStack: IME adjust changed due to minimizing,"
- + " minimizedDock=" + minimizedDock
- + " minimizedChange=" + minimizedChange);
- }
- mService.mWindowPlacerLocked.performSurfacePlacement();
- }
- }
-
- private boolean clearImeAdjustAnimation() {
- final boolean changed = mDisplayContent.clearImeAdjustAnimation();
- mAnimatingForIme = false;
- return changed;
- }
-
- private void startAdjustAnimation(float from, float to) {
- mAnimatingForMinimizedDockedStack = true;
- mAnimationStarted = false;
- mAnimationStart = from;
- mAnimationTarget = to;
- }
-
- private void startImeAdjustAnimation(
- boolean adjustedForIme, boolean adjustedForDivider, WindowState imeWin) {
-
- // If we're not in an animation, the starting point depends on whether we're adjusted
- // or not. If we're already in an animation, we start from where the current animation
- // left off, so that the motion doesn't look discontinuous.
- if (!mAnimatingForIme) {
- mAnimationStart = mAdjustedForIme ? 1 : 0;
- mDividerAnimationStart = mAdjustedForDivider ? 1 : 0;
- mLastAnimationProgress = mAnimationStart;
- mLastDividerProgress = mDividerAnimationStart;
- } else {
- mAnimationStart = mLastAnimationProgress;
- mDividerAnimationStart = mLastDividerProgress;
- }
- mAnimatingForIme = true;
- mAnimationStarted = false;
- mAnimationTarget = adjustedForIme ? 1 : 0;
- mDividerAnimationTarget = adjustedForDivider ? 1 : 0;
-
- mDisplayContent.beginImeAdjustAnimation();
-
- // We put all tasks into drag resizing mode - wait until all of them have completed the
- // drag resizing switch.
- final Runnable existingWaitingForDrwanCallback =
- mService.mWaitingForDrawnCallbacks.get(mService.mRoot);
- if (existingWaitingForDrwanCallback != null) {
- mService.mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT, mService.mRoot);
- mService.mH.sendMessageDelayed(mService.mH.obtainMessage(H.WAITING_FOR_DRAWN_TIMEOUT,
- mService.mRoot),
- IME_ADJUST_DRAWN_TIMEOUT);
- mAnimationStartDelayed = true;
- if (imeWin != null) {
-
- // There might be an old window delaying the animation start - clear it.
- if (mDelayedImeWin != null) {
- mDelayedImeWin.endDelayingAnimationStart();
- }
- mDelayedImeWin = imeWin;
- imeWin.startDelayingAnimationStart();
- }
-
- // If we are already waiting for something to be drawn, clear out the old one so it
- // still gets executed.
- // TODO: Have a real system where we can wait on different windows to be drawn with
- // different callbacks.
- existingWaitingForDrwanCallback.run();
- mService.mWaitingForDrawnCallbacks.put(mService.mRoot, () -> {
- synchronized (mService.mGlobalLock) {
- mAnimationStartDelayed = false;
- if (mDelayedImeWin != null) {
- mDelayedImeWin.endDelayingAnimationStart();
- }
- // If the adjust status changed since this was posted, only notify
- // the new states and don't animate.
- long duration = 0;
- if (mAdjustedForIme == adjustedForIme
- && mAdjustedForDivider == adjustedForDivider) {
- duration = IME_ADJUST_ANIM_DURATION;
- } else {
- Slog.w(TAG, "IME adjust changed while waiting for drawn:"
- + " adjustedForIme=" + adjustedForIme
- + " adjustedForDivider=" + adjustedForDivider
- + " mAdjustedForIme=" + mAdjustedForIme
- + " mAdjustedForDivider=" + mAdjustedForDivider);
- }
- notifyAdjustedForImeChanged(
- mAdjustedForIme || mAdjustedForDivider, duration);
- }
- });
- } else {
- notifyAdjustedForImeChanged(
- adjustedForIme || adjustedForDivider, IME_ADJUST_ANIM_DURATION);
- }
- }
-
- private boolean setMinimizedDockedStack(boolean minimized) {
- final ActivityStack stack = mDisplayContent.getRootSplitScreenPrimaryTask();
- notifyDockedStackMinimizedChanged(minimized, false /* animate */, isHomeStackResizable());
- return stack != null && stack.setAdjustedForMinimizedDock(minimized ? 1f : 0f);
- }
-
- private boolean isAnimationMaximizing() {
- return mAnimationTarget == 0f;
- }
-
- public boolean animate(long now) {
- if (mWindow == null) {
- return false;
- }
- if (mAnimatingForMinimizedDockedStack) {
- return animateForMinimizedDockedStack(now);
- } else if (mAnimatingForIme && !mDisplayContent.mAppTransition.isRunning()) {
- // To prevent task stack resize animation may flicking when playing app transition
- // animation & IME window enter animation in parallel, make sure app transition is done
- // and then start to animate for IME.
- return animateForIme(now);
- }
- return false;
- }
-
- private boolean animateForIme(long now) {
- if (!mAnimationStarted || mAnimationStartDelayed) {
- mAnimationStarted = true;
- mAnimationStartTime = now;
- mAnimationDuration = (long)
- (IME_ADJUST_ANIM_DURATION * mService.getWindowAnimationScaleLocked());
- }
- float t = Math.min(1f, (float) (now - mAnimationStartTime) / mAnimationDuration);
- t = (mAnimationTarget == 1f ? IME_ADJUST_ENTRY_INTERPOLATOR : TOUCH_RESPONSE_INTERPOLATOR)
- .getInterpolation(t);
- final boolean updated =
- mDisplayContent.animateForIme(t, mAnimationTarget, mDividerAnimationTarget);
- if (updated) {
- mService.mWindowPlacerLocked.performSurfacePlacement();
- }
- if (t >= 1.0f) {
- mLastAnimationProgress = mAnimationTarget;
- mLastDividerProgress = mDividerAnimationTarget;
- mAnimatingForIme = false;
- return false;
- } else {
- return true;
- }
- }
-
- private boolean animateForMinimizedDockedStack(long now) {
- final ActivityStack stack = mDisplayContent.getRootSplitScreenPrimaryTask();
- if (!mAnimationStarted) {
- mAnimationStarted = true;
- mAnimationStartTime = now;
- notifyDockedStackMinimizedChanged(mMinimizedDock, true /* animate */,
- isHomeStackResizable() /* isHomeStackResizable */);
- }
- float t = Math.min(1f, (float) (now - mAnimationStartTime) / mAnimationDuration);
- t = (isAnimationMaximizing() ? TOUCH_RESPONSE_INTERPOLATOR : mMinimizedDockInterpolator)
- .getInterpolation(t);
- if (stack != null) {
- if (stack.setAdjustedForMinimizedDock(getMinimizeAmount(stack, t))) {
- mService.mWindowPlacerLocked.performSurfacePlacement();
- }
- }
- if (t >= 1.0f) {
- mAnimatingForMinimizedDockedStack = false;
- return false;
- } else {
- return true;
- }
- }
-
- float getInterpolatedAnimationValue(float t) {
- return t * mAnimationTarget + (1 - t) * mAnimationStart;
- }
-
- float getInterpolatedDividerValue(float t) {
- return t * mDividerAnimationTarget + (1 - t) * mDividerAnimationStart;
- }
-
- /**
- * Gets the amount how much to minimize a stack depending on the interpolated fraction t.
- */
- private float getMinimizeAmount(ActivityStack stack, float t) {
- final float naturalAmount = getInterpolatedAnimationValue(t);
- if (isAnimationMaximizing()) {
- return adjustMaximizeAmount(stack, t, naturalAmount);
- } else {
- return naturalAmount;
- }
- }
-
- /**
- * When maximizing the stack during a clip reveal transition, this adjusts the minimize amount
- * during the transition such that the edge of the clip reveal rect is met earlier in the
- * transition so we don't create a visible "hole", but only if both the clip reveal and the
- * docked stack divider start from about the same portion on the screen.
- */
- private float adjustMaximizeAmount(ActivityStack stack, float t, float naturalAmount) {
- if (mMaximizeMeetFraction == 1f) {
- return naturalAmount;
- }
- final int minimizeDistance = stack.getMinimizeDistance();
- final float startPrime = mDisplayContent.mAppTransition.getLastClipRevealMaxTranslation()
- / (float) minimizeDistance;
- final float amountPrime = t * mAnimationTarget + (1 - t) * startPrime;
- final float t2 = Math.min(t / mMaximizeMeetFraction, 1);
- return amountPrime * t2 + naturalAmount * (1 - t2);
- }
-
- /**
- * Retrieves the animation fraction at which the docked stack has to meet the clip reveal
- * edge. See {@link #adjustMaximizeAmount}.
- */
- private float getClipRevealMeetFraction(ActivityStack stack) {
- if (!isAnimationMaximizing() || stack == null ||
- !mDisplayContent.mAppTransition.hadClipRevealAnimation()) {
- return 1f;
- }
- final int minimizeDistance = stack.getMinimizeDistance();
- final float fraction = Math.abs(mDisplayContent.mAppTransition
- .getLastClipRevealMaxTranslation()) / (float) minimizeDistance;
- final float t = Math.max(0, Math.min(1, (fraction - CLIP_REVEAL_MEET_FRACTION_MIN)
- / (CLIP_REVEAL_MEET_FRACTION_MAX - CLIP_REVEAL_MEET_FRACTION_MIN)));
- return CLIP_REVEAL_MEET_EARLIEST
- + (1 - t) * (CLIP_REVEAL_MEET_LAST - CLIP_REVEAL_MEET_EARLIEST);
- }
-
- public String toShortString() {
- return TAG;
- }
-
- WindowState getWindow() {
- return mWindow;
- }
-
- void dump(String prefix, PrintWriter pw) {
- pw.println(prefix + "DockedStackDividerController");
- pw.println(prefix + " mLastVisibility=" + mLastVisibility);
- pw.println(prefix + " mMinimizedDock=" + mMinimizedDock);
- pw.println(prefix + " mAdjustedForIme=" + mAdjustedForIme);
- pw.println(prefix + " mAdjustedForDivider=" + mAdjustedForDivider);
- }
-
- void dumpDebug(ProtoOutputStream proto, long fieldId) {
- final long token = proto.start(fieldId);
- proto.write(MINIMIZED_DOCK, mMinimizedDock);
- proto.end(token);
- }
}
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index 9468bff..54cea93 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -125,10 +125,6 @@
// enabled for it to start intercepting touch events.
private boolean mInputConsumerEnabled;
- // Whether or not the recents animation should cause the primary split-screen stack to be
- // minimized
- private boolean mSplitScreenMinimized;
-
private final Rect mTmpRect = new Rect();
private boolean mLinkedToDeathOfRunner;
@@ -277,23 +273,6 @@
}
@Override
- public void setSplitScreenMinimized(boolean minimized) {
- final long token = Binder.clearCallingIdentity();
- try {
- synchronized (mService.getWindowManagerLock()) {
- if (mCanceled) {
- return;
- }
-
- mSplitScreenMinimized = minimized;
- mService.checkSplitScreenMinimizedChanged(true /* animate */);
- }
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- @Override
public void hideCurrentInputMethod() {
final long token = Binder.clearCallingIdentity();
try {
@@ -738,10 +717,6 @@
}
}
- boolean isSplitScreenMinimized() {
- return mSplitScreenMinimized;
- }
-
boolean isWallpaperVisible(WindowState w) {
return w != null && w.mAttrs.type == TYPE_BASE_APPLICATION &&
((w.mActivityRecord != null && mTargetActivityRecord == w.mActivityRecord)
@@ -944,7 +919,6 @@
pw.print(innerPrefix); pw.println("mPendingAnimations=" + mPendingAnimations.size());
pw.print(innerPrefix); pw.println("mCanceled=" + mCanceled);
pw.print(innerPrefix); pw.println("mInputConsumerEnabled=" + mInputConsumerEnabled);
- pw.print(innerPrefix); pw.println("mSplitScreenMinimized=" + mSplitScreenMinimized);
pw.print(innerPrefix); pw.println("mTargetActivityRecord=" + mTargetActivityRecord);
pw.print(innerPrefix); pw.println("isTargetOverWallpaper=" + isTargetOverWallpaper());
pw.print(innerPrefix); pw.println("mRequestDeferCancelUntilNextTransition="
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 64d7db2..ada5685 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -258,9 +258,6 @@
*/
final ArrayList<ActivityTaskManagerInternal.SleepToken> mSleepTokens = new ArrayList<>();
- /** Is dock currently minimized. */
- boolean mIsDockMinimized;
-
/** Set when a power hint has started, but not ended. */
private boolean mPowerHintSent;
@@ -1011,9 +1008,7 @@
// Send any pending task-info changes that were queued-up during a layout deferment
mWmService.mAtmService.mTaskOrganizerController.dispatchPendingTaskInfoChanges();
- if (DEBUG_WINDOW_TRACE) Slog.e(TAG,
- "performSurfacePlacementInner exit: animating="
- + mWmService.mAnimator.isAnimating());
+ if (DEBUG_WINDOW_TRACE) Slog.e(TAG, "performSurfacePlacementInner exit");
}
private void checkAppTransitionReady(WindowSurfacePlacer surfacePlacer) {
@@ -1989,8 +1984,7 @@
// We dismiss the docked stack whenever we switch users.
final ActivityStack dockedStack = getDefaultDisplay().getRootSplitScreenPrimaryTask();
if (dockedStack != null) {
- mStackSupervisor.moveTasksToFullscreenStackLocked(
- dockedStack, dockedStack.isFocusedStackOnDisplay());
+ getDefaultDisplay().onSplitScreenModeDismissed();
}
// Also dismiss the pinned stack whenever we switch users. Removing the pinned stack will
// also cause all tasks to be moved to the fullscreen stack at a position that is
@@ -2167,21 +2161,6 @@
}
}
- void setDockedStackMinimized(boolean minimized) {
- // Get currently focused stack before setting mIsDockMinimized. We do this because if
- // split-screen is active, primary stack will not be focusable (see #isFocusable) while
- // still occluding other stacks. This will cause getTopDisplayFocusedStack() to return null.
- final ActivityStack current = getTopDisplayFocusedStack();
- mIsDockMinimized = minimized;
- if (mIsDockMinimized) {
- if (current.inSplitScreenPrimaryWindowingMode()) {
- // The primary split-screen stack can't be focused while it is minimize, so move
- // focus to something else.
- current.adjustFocusToNextFocusableStack("setDockedStackMinimized");
- }
- }
- }
-
ActivityRecord findTask(ActivityRecord r, int preferredDisplayId) {
if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + r);
mTmpFindTaskResult.clear();
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 07e17e8..27acb23 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -2108,18 +2108,6 @@
intersectWithInsetsIfFits(outStableBounds, mTmpBounds, mTmpInsets);
}
- /**
- * Asks docked-divider controller for the smallestwidthdp given bounds.
- * @param bounds bounds to calculate smallestwidthdp for.
- */
- private int getSmallestScreenWidthDpForDockedBounds(Rect bounds) {
- DisplayContent dc = getDisplayContent();
- if (dc != null) {
- return dc.getDockedDividerController().getSmallestWidthDpForBounds(bounds);
- }
- return Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED;
- }
-
void computeConfigResourceOverrides(@NonNull Configuration inOutConfig,
@NonNull Configuration parentConfig) {
computeConfigResourceOverrides(inOutConfig, parentConfig, null /* compatInsets */);
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index fd91bc5..b6be386 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -50,7 +50,6 @@
final WindowManagerPolicy mPolicy;
/** Is any window animating? */
- private boolean mAnimating;
private boolean mLastRootAnimating;
final Choreographer.FrameCallback mAnimationFrameCallback;
@@ -135,7 +134,6 @@
synchronized (mService.mGlobalLock) {
mCurrentTime = frameTimeNs / TimeUtils.NANOS_PER_MS;
mBulkUpdateParams = SET_ORIENTATION_CHANGE_COMPLETE;
- mAnimating = false;
if (DEBUG_WINDOW_TRACE) {
Slog.i(TAG, "!!! animate: entry time=" + mCurrentTime);
}
@@ -160,17 +158,12 @@
final DisplayContent dc = mService.mRoot.getDisplayContent(displayId);
dc.checkAppWindowsReadyToShow();
- orAnimating(dc.getDockedDividerController().animate(mCurrentTime));
if (accessibilityController != null) {
accessibilityController.drawMagnifiedRegionBorderIfNeededLocked(displayId,
mTransaction);
}
}
- if (!mAnimating) {
- cancelAnimation();
- }
-
if (mService.mWatermark != null) {
mService.mWatermark.drawIfNeeded();
}
@@ -220,7 +213,7 @@
executeAfterPrepareSurfacesRunnables();
if (DEBUG_WINDOW_TRACE) {
- Slog.i(TAG, "!!! animate: exit mAnimating=" + mAnimating
+ Slog.i(TAG, "!!! animate: exit"
+ " mBulkUpdateParams=" + Integer.toHexString(mBulkUpdateParams)
+ " hasPendingLayoutChanges=" + hasPendingLayoutChanges);
}
@@ -302,10 +295,6 @@
private class DisplayContentsAnimator {
}
- boolean isAnimating() {
- return mAnimating;
- }
-
boolean isAnimationScheduled() {
return mAnimationFrameCallbackScheduled;
}
@@ -314,14 +303,6 @@
return mChoreographer;
}
- void setAnimating(boolean animating) {
- mAnimating = animating;
- }
-
- void orAnimating(boolean animating) {
- mAnimating |= animating;
- }
-
/**
* Adds a runnable to be executed after {@link WindowContainer#prepareSurfaces} is called and
* the corresponding transaction is closed and applied.
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index e0f8f0e..a59eab5 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -42,7 +42,6 @@
import static android.provider.Settings.Global.DEVELOPMENT_RENDER_SHADOWS_IN_COMPOSITOR;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
-import static android.view.WindowManager.DOCKED_INVALID;
import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
@@ -59,7 +58,6 @@
import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
-import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
@@ -214,7 +212,6 @@
import android.view.IDisplayWindowInsetsController;
import android.view.IDisplayWindowListener;
import android.view.IDisplayWindowRotationController;
-import android.view.IDockedStackListener;
import android.view.IInputFilter;
import android.view.IOnKeyguardExitResult;
import android.view.IPinnedStackListener;
@@ -1636,14 +1633,6 @@
}
}
- // If the window is being added to a stack that's currently adjusted for IME,
- // make sure to apply the same adjust to this new window.
- win.applyAdjustForImeIfNeeded();
-
- if (type == TYPE_DOCK_DIVIDER) {
- mRoot.getDisplayContent(displayId).getDockedDividerController().setWindow(win);
- }
-
final WindowStateAnimator winAnimator = win.mWinAnimator;
winAnimator.mEnterAnimationPending = true;
winAnimator.mEnteringAnimation = true;
@@ -2816,16 +2805,6 @@
}
}
- void setDockedStackCreateStateLocked(int mode, Rect bounds) {
- mDockedStackCreateMode = mode;
- mDockedStackCreateBounds = bounds;
- }
-
- void checkSplitScreenMinimizedChanged(boolean animate) {
- final DisplayContent displayContent = getDefaultDisplayContentLocked();
- displayContent.getDockedDividerController().checkMinimizeChanged(animate);
- }
-
boolean isValidPictureInPictureAspectRatio(DisplayContent displayContent, float aspectRatio) {
return displayContent.getPinnedStackController().isValidPictureInPictureAspectRatio(
aspectRatio);
@@ -3295,10 +3274,6 @@
// Notify whether the docked stack exists for the current user
final DisplayContent displayContent = getDefaultDisplayContentLocked();
- final ActivityStack stack =
- displayContent.getRootSplitScreenPrimaryTask();
- displayContent.mDividerControllerLocked.notifyDockedStackExistsChanged(
- stack != null && stack.hasTaskForUser(newUserId));
mRoot.forAllDisplays(dc -> dc.mAppTransition.setCurrentUser(newUserId));
@@ -4687,7 +4662,7 @@
public static final int RESET_ANR_MESSAGE = 38;
public static final int WALLPAPER_DRAW_PENDING_TIMEOUT = 39;
- public static final int UPDATE_DOCKED_STACK_DIVIDER = 41;
+ public static final int UPDATE_MULTI_WINDOW_STACKS = 41;
public static final int WINDOW_REPLACEMENT_TIMEOUT = 46;
@@ -4832,7 +4807,7 @@
synchronized (mGlobalLock) {
// Since we're holding both mWindowMap and mAnimator we don't need to
// hold mAnimator.mLayoutToAnim.
- if (mAnimator.isAnimating() || mAnimator.isAnimationScheduled()) {
+ if (mAnimator.isAnimationScheduled()) {
// If we are animating, don't do the gc now but
// delay a bit so we don't interrupt the animation.
sendEmptyMessageDelayed(H.FORCE_GC, 2000);
@@ -4994,11 +4969,10 @@
}
break;
}
- case UPDATE_DOCKED_STACK_DIVIDER: {
+ case UPDATE_MULTI_WINDOW_STACKS: {
synchronized (mGlobalLock) {
final DisplayContent displayContent = getDefaultDisplayContentLocked();
if (displayContent != null) {
- displayContent.getDockedDividerController().reevaluateVisibility(false);
displayContent.adjustForImeIfNeeded();
}
}
@@ -6551,11 +6525,7 @@
@Override
public int getDockedStackSide() {
- synchronized (mGlobalLock) {
- final ActivityStack dockedStack = getDefaultDisplayContentLocked()
- .getRootSplitScreenPrimaryTask();
- return dockedStack == null ? DOCKED_INVALID : dockedStack.getDockSide();
- }
+ return 0;
}
void setDockedStackResizing(boolean resizing) {
@@ -6572,14 +6542,6 @@
}
}
- @Override
- public void setResizeDimLayer(boolean visible, int targetWindowingMode, float alpha) {
- synchronized (mGlobalLock) {
- getDefaultDisplayContentLocked().getDockedDividerController().setResizeDimLayer(
- visible, targetWindowingMode, alpha);
- }
- }
-
void setForceDesktopModeOnExternalDisplays(boolean forceDesktopModeOnExternalDisplays) {
synchronized (mGlobalLock) {
mForceDesktopModeOnExternalDisplays = forceDesktopModeOnExternalDisplays;
@@ -6598,17 +6560,6 @@
}
@Override
- public void registerDockedStackListener(IDockedStackListener listener) {
- mAtmInternal.enforceCallerIsRecentsOrHasPermission(REGISTER_WINDOW_MANAGER_LISTENERS,
- "registerDockedStackListener()");
- synchronized (mGlobalLock) {
- // TODO(multi-display): The listener is registered on the default display only.
- getDefaultDisplayContentLocked().mDividerControllerLocked.registerDockedStackListener(
- listener);
- }
- }
-
- @Override
public void registerPinnedStackListener(int displayId, IPinnedStackListener listener) {
if (!checkCallingPermission(REGISTER_WINDOW_MANAGER_LISTENERS,
"registerPinnedStackListener()")) {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 37597fb..e452c4a 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -1128,7 +1128,6 @@
}
}
} else if (mAttrs.type == TYPE_DOCK_DIVIDER) {
- dc.getDockedDividerController().positionDockedStackedDivider(windowFrames.mFrame);
windowFrames.mContentFrame.set(windowFrames.mFrame);
if (!windowFrames.mFrame.equals(windowFrames.mLastFrame)) {
mMovedByResize = true;
@@ -1937,13 +1936,9 @@
// animating... let's do something.
final int left = mWindowFrames.mFrame.left;
final int top = mWindowFrames.mFrame.top;
- final Task task = getTask();
- final boolean adjustedForMinimizedDockOrIme = task != null
- && (task.getStack().isAdjustedForMinimizedDockedStack()
- || task.getStack().isAdjustedForIme());
if (mToken.okToAnimate()
&& (mAttrs.privateFlags & PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0
- && !isDragResizing() && !adjustedForMinimizedDockOrIme
+ && !isDragResizing()
&& getWindowConfiguration().hasMovementAnimations()
&& !mWinAnimator.mLastHidden
&& !mSeamlesslyRotated) {
@@ -2250,15 +2245,15 @@
}
final ActivityStack stack = getRootTask();
- if (stack != null && stack.shouldIgnoreInput()) {
+ if (stack != null && !stack.isFocusable()) {
// Ignore when the stack shouldn't receive input event.
// (i.e. the minimized stack in split screen mode.)
return false;
}
- if (PixelFormat.formatHasAlpha(mAttrs.format)) {
- // Support legacy use cases where transparent windows can still be ime target with
- // FLAG_NOT_FOCUSABLE and ALT_FOCUSABLE_IM set.
+ if (PixelFormat.formatHasAlpha(mAttrs.format) && mAttrs.alpha == 0) {
+ // Support legacy use cases where completely transparent windows can still be ime target
+ // with FLAG_NOT_FOCUSABLE and ALT_FOCUSABLE_IM set.
// Certain apps listen for IME insets using transparent windows and ADJUST_NOTHING to
// manually synchronize app content to IME animation b/144619551.
// TODO(b/145812508): remove this once new focus management is complete b/141738570
@@ -2412,13 +2407,6 @@
}
}
- void applyAdjustForImeIfNeeded() {
- final Task task = getTask();
- if (task != null && task.getStack() != null && task.getStack().isAdjustedForIme()) {
- task.getStack().applyAdjustForImeIfNeeded(task);
- }
- }
-
@Override
void switchUser(int userId) {
super.switchUser(userId);
@@ -4308,10 +4296,6 @@
}
}
- if (mAttrs.type == TYPE_INPUT_METHOD) {
- getDisplayContent().mDividerControllerLocked.resetImeHideRequested();
- }
-
return true;
}
diff --git a/services/tests/uiservicestests/src/com/android/internal/logging/InstanceIdSequenceFake.java b/services/tests/uiservicestests/src/com/android/internal/logging/InstanceIdSequenceFake.java
index 1629ef0..6e7df05 100644
--- a/services/tests/uiservicestests/src/com/android/internal/logging/InstanceIdSequenceFake.java
+++ b/services/tests/uiservicestests/src/com/android/internal/logging/InstanceIdSequenceFake.java
@@ -17,7 +17,7 @@
package com.android.internal.logging;
/**
- * A fake implementation of InstanceIdSequence that returns 0, 1, 2, ...
+ * A fake implementation of InstanceIdSequence that returns 1, 2, ...
*/
public class InstanceIdSequenceFake extends InstanceIdSequence {
@@ -25,13 +25,13 @@
super(instanceIdMax);
}
- private int mNextId = 0;
+ private int mNextId = 1;
@Override
public InstanceId newInstanceId() {
synchronized (this) {
if (mNextId >= mInstanceIdMax) {
- mNextId = 0;
+ mNextId = 1;
}
return newInstanceIdInternal(mNextId++);
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 29b0df5..b6cdbfb 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -1163,7 +1163,7 @@
assertEquals(PKG, call.r.getSbn().getPackageName());
assertEquals(0, call.r.getSbn().getId());
assertEquals(tag, call.r.getSbn().getTag());
- assertEquals(0, call.getInstanceId()); // Fake instance IDs are assigned in order
+ assertEquals(1, call.getInstanceId()); // Fake instance IDs are assigned in order
}
@Test
@@ -1185,14 +1185,14 @@
assertEquals(
NotificationRecordLogger.NotificationReportedEvent.NOTIFICATION_POSTED,
mNotificationRecordLogger.get(0).event);
- assertEquals(0, mNotificationRecordLogger.get(0).getInstanceId());
+ assertEquals(1, mNotificationRecordLogger.get(0).getInstanceId());
assertTrue(mNotificationRecordLogger.get(1).shouldLogReported);
assertEquals(
NotificationRecordLogger.NotificationReportedEvent.NOTIFICATION_UPDATED,
mNotificationRecordLogger.get(1).event);
// Instance ID doesn't change on update of an active notification
- assertEquals(0, mNotificationRecordLogger.get(1).getInstanceId());
+ assertEquals(1, mNotificationRecordLogger.get(1).getInstanceId());
}
@Test
@@ -1247,19 +1247,19 @@
NotificationRecordLogger.NotificationReportedEvent.NOTIFICATION_POSTED,
mNotificationRecordLogger.get(0).event);
assertTrue(mNotificationRecordLogger.get(0).shouldLogReported);
- assertEquals(0, mNotificationRecordLogger.get(0).getInstanceId());
+ assertEquals(1, mNotificationRecordLogger.get(0).getInstanceId());
assertEquals(
NotificationRecordLogger.NotificationCancelledEvent.NOTIFICATION_CANCEL_APP_CANCEL,
mNotificationRecordLogger.get(1).event);
- assertEquals(0, mNotificationRecordLogger.get(1).getInstanceId());
+ assertEquals(1, mNotificationRecordLogger.get(1).getInstanceId());
assertEquals(
NotificationRecordLogger.NotificationReportedEvent.NOTIFICATION_POSTED,
mNotificationRecordLogger.get(2).event);
assertTrue(mNotificationRecordLogger.get(2).shouldLogReported);
// New instance ID because notification was canceled before re-post
- assertEquals(1, mNotificationRecordLogger.get(2).getInstanceId());
+ assertEquals(2, mNotificationRecordLogger.get(2).getInstanceId());
}
@Test
@@ -3452,6 +3452,7 @@
@Test
public void testStats_dismissalSurface() throws Exception {
final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
+ r.getSbn().setInstanceId(mNotificationInstanceIdSequence.newInstanceId());
mService.addNotification(r);
final NotificationVisibility nv = NotificationVisibility.obtain(r.getKey(), 0, 1, true);
@@ -3469,7 +3470,7 @@
assertEquals(
NotificationRecordLogger.NotificationCancelledEvent.NOTIFICATION_CANCEL_USER_AOD,
mNotificationRecordLogger.get(0).event);
- assertEquals(0, mNotificationRecordLogger.get(0).getInstanceId());
+ assertEquals(1, mNotificationRecordLogger.get(0).getInstanceId());
}
@Test
@@ -4343,6 +4344,7 @@
final NotificationRecord r = generateNotificationRecord(
mTestNotificationChannel, 1, null, true);
r.setTextChanged(true);
+ r.getSbn().setInstanceId(mNotificationInstanceIdSequence.newInstanceId());
mService.addNotification(r);
mService.mNotificationDelegate.onNotificationVisibilityChanged(new NotificationVisibility[]
@@ -4352,7 +4354,7 @@
assertEquals(1, mNotificationRecordLogger.getCalls().size());
assertEquals(NotificationRecordLogger.NotificationEvent.NOTIFICATION_OPEN,
mNotificationRecordLogger.get(0).event);
- assertEquals(0, mNotificationRecordLogger.get(0).getInstanceId());
+ assertEquals(1, mNotificationRecordLogger.get(0).getInstanceId());
mService.mNotificationDelegate.onNotificationVisibilityChanged(
new NotificationVisibility[]{},
@@ -4363,7 +4365,7 @@
assertEquals(2, mNotificationRecordLogger.getCalls().size());
assertEquals(NotificationRecordLogger.NotificationEvent.NOTIFICATION_CLOSE,
mNotificationRecordLogger.get(1).event);
- assertEquals(0, mNotificationRecordLogger.get(1).getInstanceId());
+ assertEquals(1, mNotificationRecordLogger.get(1).getInstanceId());
}
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/DockedStackDividerControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/DockedStackDividerControllerTests.java
deleted file mode 100644
index 3206208..0000000
--- a/services/tests/wmtests/src/com/android/server/wm/DockedStackDividerControllerTests.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wm;
-
-import static android.view.WindowManager.DOCKED_BOTTOM;
-import static android.view.WindowManager.DOCKED_LEFT;
-import static android.view.WindowManager.DOCKED_RIGHT;
-import static android.view.WindowManager.DOCKED_TOP;
-import static android.view.WindowManagerPolicyConstants.NAV_BAR_BOTTOM;
-import static android.view.WindowManagerPolicyConstants.NAV_BAR_LEFT;
-import static android.view.WindowManagerPolicyConstants.NAV_BAR_RIGHT;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.platform.test.annotations.Presubmit;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-@SmallTest
-@Presubmit
-public class DockedStackDividerControllerTests {
-
- @Test
- public void testIsDockSideAllowedDockTop() {
- // Docked top is always allowed
- assertTrue(DockedStackDividerController.isDockSideAllowed(DOCKED_TOP, DOCKED_LEFT,
- NAV_BAR_BOTTOM, true /* navigationBarCanMove */));
- assertTrue(DockedStackDividerController.isDockSideAllowed(DOCKED_TOP, DOCKED_LEFT,
- NAV_BAR_BOTTOM, false /* navigationBarCanMove */));
- }
-
- @Test
- public void testIsDockSideAllowedDockBottom() {
- // Cannot dock bottom
- assertFalse(DockedStackDividerController.isDockSideAllowed(DOCKED_BOTTOM, DOCKED_LEFT,
- NAV_BAR_BOTTOM, true /* navigationBarCanMove */));
- }
-
- @Test
- public void testIsDockSideAllowedNavigationBarMovable() {
- assertFalse(DockedStackDividerController.isDockSideAllowed(DOCKED_LEFT, DOCKED_LEFT,
- NAV_BAR_BOTTOM, true /* navigationBarCanMove */));
- assertFalse(DockedStackDividerController.isDockSideAllowed(DOCKED_LEFT, DOCKED_LEFT,
- NAV_BAR_LEFT, true /* navigationBarCanMove */));
- assertTrue(DockedStackDividerController.isDockSideAllowed(DOCKED_LEFT, DOCKED_LEFT,
- NAV_BAR_RIGHT, true /* navigationBarCanMove */));
- assertFalse(DockedStackDividerController.isDockSideAllowed(DOCKED_RIGHT, DOCKED_LEFT,
- NAV_BAR_BOTTOM, true /* navigationBarCanMove */));
- assertFalse(DockedStackDividerController.isDockSideAllowed(DOCKED_RIGHT, DOCKED_LEFT,
- NAV_BAR_RIGHT, true /* navigationBarCanMove */));
- assertTrue(DockedStackDividerController.isDockSideAllowed(DOCKED_RIGHT, DOCKED_LEFT,
- NAV_BAR_LEFT, true /* navigationBarCanMove */));
- }
-
- @Test
- public void testIsDockSideAllowedNavigationBarNotMovable() {
- // Navigation bar is not movable such as tablets
- assertTrue(DockedStackDividerController.isDockSideAllowed(DOCKED_LEFT, DOCKED_LEFT,
- NAV_BAR_BOTTOM, false /* navigationBarCanMove */));
- assertTrue(DockedStackDividerController.isDockSideAllowed(DOCKED_LEFT, DOCKED_TOP,
- NAV_BAR_BOTTOM, false /* navigationBarCanMove */));
- assertFalse(DockedStackDividerController.isDockSideAllowed(DOCKED_LEFT, DOCKED_RIGHT,
- NAV_BAR_BOTTOM, false /* navigationBarCanMove */));
- assertFalse(DockedStackDividerController.isDockSideAllowed(DOCKED_RIGHT, DOCKED_LEFT,
- NAV_BAR_BOTTOM, false /* navigationBarCanMove */));
- assertFalse(DockedStackDividerController.isDockSideAllowed(DOCKED_RIGHT, DOCKED_TOP,
- NAV_BAR_BOTTOM, false /* navigationBarCanMove */));
- assertTrue(DockedStackDividerController.isDockSideAllowed(DOCKED_RIGHT, DOCKED_RIGHT,
- NAV_BAR_BOTTOM, false /* navigationBarCanMove */));
- }
-}
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
index d9c5c4c..9a898fd 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
@@ -17,7 +17,6 @@
package com.android.server.wm;
import static android.app.ActivityManager.RECENT_WITH_EXCLUDED;
-import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
@@ -978,10 +977,7 @@
() -> mService.setTaskWindowingMode(taskId, WINDOWING_MODE_FULLSCREEN,
false/* toTop */));
assertNotRestoreTask(
- () -> mService.setTaskWindowingModeSplitScreenPrimary(taskId,
- SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT,
- false /* toTop */, false /* animate */, null /* initialBounds */,
- true /* showRecents */));
+ () -> mService.setTaskWindowingModeSplitScreenPrimary(taskId, false /* toTop */));
}
@Test
@@ -1096,14 +1092,10 @@
assertSecurityException(expectCallable,
() -> mService.moveTaskToStack(0, INVALID_STACK_ID, true));
assertSecurityException(expectCallable,
- () -> mService.setTaskWindowingModeSplitScreenPrimary(0,
- SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, true, true, new Rect(), true));
+ () -> mService.setTaskWindowingModeSplitScreenPrimary(0, true));
assertSecurityException(expectCallable, () -> mService.dismissPip(true, 0));
assertSecurityException(expectCallable,
() -> mService.moveTopActivityToPinnedStack(INVALID_STACK_ID, new Rect()));
- assertSecurityException(expectCallable,
- () -> mService.resizeDockedStack(new Rect(), new Rect(), new Rect(), new Rect(),
- new Rect()));
assertSecurityException(expectCallable, () -> mService.getAllStackInfos());
assertSecurityException(expectCallable,
() -> mService.getStackInfo(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_UNDEFINED));
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
index 71d3194..0ef2582 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
@@ -250,13 +250,12 @@
final ActivityRecord activity = new ActivityBuilder(mService).setCreateTask(true)
.setStack(stack).build();
- // Under split screen primary we should be focusable when not minimized
- mRootWindowContainer.setDockedStackMinimized(false);
+ // Created stacks are focusable by default.
assertTrue(stack.isTopActivityFocusable());
assertTrue(activity.isFocusable());
- // Under split screen primary we should not be focusable when minimized
- mRootWindowContainer.setDockedStackMinimized(true);
+ // If the stack is made unfocusable, its activities should inherit that.
+ stack.setFocusable(false);
assertFalse(stack.isTopActivityFocusable());
assertFalse(activity.isFocusable());
@@ -307,33 +306,6 @@
}
/**
- * Verify split-screen primary stack & task can resized by
- * {@link android.app.IActivityTaskManager#resizeDockedStack} as expect.
- */
- @Test
- public void testResizeDockedStackForSplitScreenPrimary() {
- final Rect configSize = new Rect(0, 0, 1000, 1000);
- final Rect displayedSize = new Rect(0, 0, 300, 300);
-
- // Create primary split-screen stack with a task.
- final ActivityStack primaryStack = new StackBuilder(mRootWindowContainer)
- .setActivityType(ACTIVITY_TYPE_STANDARD)
- .setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY)
- .setOnTop(true)
- .build();
- final Task task = primaryStack.getTopMostTask();
-
- // Resize dock stack.
- mService.resizeDockedStack(displayedSize, configSize, null, null, null);
-
- // Verify dock stack & its task bounds if is equal as resized result.
- assertEquals(displayedSize, primaryStack.getDisplayedBounds());
- assertEquals(displayedSize, primaryStack.getDisplayedBounds());
- assertEquals(configSize, primaryStack.getBounds());
- assertEquals(configSize, task.getBounds());
- }
-
- /**
* Verify that home stack would be moved to front when the top activity is Recents.
*/
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
index 2c68cc7..85e4a16 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -251,9 +251,11 @@
// b/145812508: special legacy use-case for transparent/translucent windows.
appWindow.mAttrs.format = PixelFormat.TRANSPARENT;
+ appWindow.mAttrs.alpha = 0;
assertTrue(appWindow.canBeImeTarget());
appWindow.mAttrs.format = PixelFormat.OPAQUE;
+ appWindow.mAttrs.alpha = 1;
appWindow.mAttrs.flags &= ~FLAG_ALT_FOCUSABLE_IM;
assertFalse(appWindow.canBeImeTarget());
appWindow.mAttrs.flags &= ~FLAG_NOT_FOCUSABLE;
@@ -276,8 +278,7 @@
spyOn(appWindow);
spyOn(controller);
spyOn(stack);
- doReturn(true).when(controller).isMinimizedDock();
- doReturn(true).when(controller).isHomeStackResizable();
+ stack.setFocusable(false);
doReturn(stack).when(appWindow).getRootTask();
// Make sure canBeImeTarget is false due to shouldIgnoreInput is true;
@@ -619,9 +620,10 @@
}
@Test
- public void testCantReceiveTouchWhenShouldIgnoreInput() {
+ public void testCantReceiveTouchWhenNotFocusable() {
final WindowState win0 = createWindow(null, TYPE_APPLICATION, "win0");
- win0.mActivityRecord.getStack().setAdjustedForMinimizedDock(1 /* Any non 0 value works */);
+ win0.mActivityRecord.getStack().setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
+ win0.mActivityRecord.getStack().setFocusable(false);
assertTrue(win0.cantReceiveTouchInput());
}
}
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 07cc2d4..8e85bb2 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -1917,7 +1917,19 @@
return;
}
try {
- // Adbd will be started by AdbService once Global.ADB_ENABLED is set.
+ if ((config & UsbManager.FUNCTION_ADB) != 0) {
+ /**
+ * Start adbd if ADB function is included in the configuration.
+ */
+ LocalServices.getService(AdbManagerInternal.class)
+ .startAdbdForTransport(AdbTransportType.USB);
+ } else {
+ /**
+ * Stop adbd otherwise
+ */
+ LocalServices.getService(AdbManagerInternal.class)
+ .stopAdbdForTransport(AdbTransportType.USB);
+ }
UsbGadgetCallback usbGadgetCallback = new UsbGadgetCallback(mCurrentRequest,
config, chargingFunctions);
mGadgetProxy.setCurrentUsbFunctions(config, usbGadgetCallback,
diff --git a/startop/scripts/app_startup/parse_metrics b/startop/scripts/app_startup/parse_metrics
index 036609f..3fa1462 100755
--- a/startop/scripts/app_startup/parse_metrics
+++ b/startop/scripts/app_startup/parse_metrics
@@ -42,12 +42,14 @@
-h, --help usage information (this)
-v, --verbose enable extra verbose printing
-t, --timeout <sec> how many seconds to timeout when trying to wait for logcat to change
+ -rfd, --reportfullydrawn wait for report fully drawn (default: off)
EOF
}
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
source "$DIR/lib/common"
+report_fully_drawn="n"
package=""
activity=""
timeout=5
@@ -81,6 +83,11 @@
-s|--simulate)
simulate="y"
;;
+ -rfd|--reportfullydrawn)
+ report_fully_drawn="y"
+ ;;
+
+
*)
echo "Invalid argument: $1" >&2
exit 1
@@ -190,12 +197,15 @@
parse_metric_from_logcat "Displayed_ms" "$pattern" "$re_pattern"
-# 01-16 17:31:44.550 11172 11204 I ActivityTaskManager: Fully drawn com.google.android.GoogleCamera/com.android.camera.CameraLauncher: +10s897ms
-pattern="ActivityTaskManager: Fully drawn ${package}"
-#re_pattern='.*Fully drawn[[:blank:]]\+'"${package}"'[/][^[:blank:]]\+[[:blank:]]+\([[:digit:]]\+\).*'
-re_pattern='.*Fully drawn[[:blank:]]\+'"${package}"'[/][^[:blank:]]\+[[:blank:]]+\([[:digit:]]\+ms\|[[:digit:]]\+s[[:digit:]]\+ms\).*'
+# Only track ReportFullyDrawn with --reportfullydrawn/-rfd flags
+if [[ $report_fully_drawn == y ]]; then
+ # 01-16 17:31:44.550 11172 11204 I ActivityTaskManager: Fully drawn com.google.android.GoogleCamera/com.android.camera.CameraLauncher: +10s897ms
+ pattern="ActivityTaskManager: Fully drawn ${package}"
+ #re_pattern='.*Fully drawn[[:blank:]]\+'"${package}"'[/][^[:blank:]]\+[[:blank:]]+\([[:digit:]]\+\).*'
+ re_pattern='.*Fully drawn[[:blank:]]\+'"${package}"'[/][^[:blank:]]\+[[:blank:]]+\([[:digit:]]\+ms\|[[:digit:]]\+s[[:digit:]]\+ms\).*'
-parse_metric_from_logcat "Fully_drawn_ms" "$pattern" "$re_pattern"
+ parse_metric_from_logcat "Fully_drawn_ms" "$pattern" "$re_pattern"
+fi
# also call into package-specific scripts if there are additional metrics
if [[ -x "$DIR/metrics/$package" ]]; then
diff --git a/startop/scripts/app_startup/run_app_with_prefetch b/startop/scripts/app_startup/run_app_with_prefetch
index 92a31c3..31f6253 100755
--- a/startop/scripts/app_startup/run_app_with_prefetch
+++ b/startop/scripts/app_startup/run_app_with_prefetch
@@ -35,6 +35,7 @@
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
source "$DIR/../iorap/common"
+report_fully_drawn="n"
needs_trace_file="n"
input_file=""
package=""
@@ -70,6 +71,10 @@
mode="$2"
shift
;;
+ -rfd|--reportfullydrawn)
+ report_fully_drawn="y"
+ shift
+ ;;
-c|--count)
count="$2"
((count+=1))
@@ -403,7 +408,11 @@
join_by ',' "${all_metrics[@]}"
}
-metrics_header="$("$DIR/parse_metrics" --package "$package" --activity "$activity" --simulate | parse_metrics_header)"
+if [[ $report_fully_drawn == y ]]; then
+ metrics_header="$("$DIR/parse_metrics" --package "$package" --activity "$activity" --simulate --reportfullydrawn | parse_metrics_header)"
+else
+ metrics_header="$("$DIR/parse_metrics" --package "$package" --activity "$activity" --simulate | parse_metrics_header)"
+fi
# TODO: This loop logic could probably be moved into app_startup_runner.py
for ((i=0;i<count;++i)) do
@@ -411,6 +420,9 @@
verbose_print "==== ITERATION $i ===="
verbose_print "=========================================="
if [[ $mode != "warm" ]]; then
+ # The package must be killed **before** we drop caches, otherwise pages will stay resident.
+ verbose_print "Kill package for non-warm start."
+ remote_pkill "$package"
verbose_print "Drop caches for non-warm start."
# Drop all caches to get cold starts.
adb shell "echo 3 > /proc/sys/vm/drop_caches"
@@ -423,7 +435,12 @@
pre_launch_timestamp="$(logcat_save_timestamp)"
# TODO: multiple metrics output.
+
+if [[ $report_fully_drawn == y ]]; then
+ total_time="$(timeout $timeout "$DIR/launch_application" "$package" "$activity" | "$DIR/parse_metrics" --package "$package" --activity "$activity" --timestamp "$pre_launch_timestamp" --reportfullydrawn | parse_metrics_output)"
+else
total_time="$(timeout $timeout "$DIR/launch_application" "$package" "$activity" | "$DIR/parse_metrics" --package "$package" --activity "$activity" --timestamp "$pre_launch_timestamp" | parse_metrics_output)"
+fi
if [[ $? -ne 0 ]]; then
echo "WARNING: Skip bad result, try iteration again." >&2
diff --git a/startop/scripts/app_startup/run_app_with_prefetch.py b/startop/scripts/app_startup/run_app_with_prefetch.py
old mode 100644
new mode 100755
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index a36df49..31d9654 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -11071,7 +11071,6 @@
* @param enabled True if enabling the data, otherwise disabling.
* @hide
*/
- @SystemApi
@RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
public void setPolicyDataEnabled(boolean enabled) {
try {
@@ -11174,7 +11173,6 @@
* @param isEnabled {@code true} for enabling; {@code false} for disabling.
* @hide
*/
- @SystemApi
@RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
public void setAlwaysReportSignalStrength(boolean isEnabled) {
try {
diff --git a/wifi/Android.bp b/wifi/Android.bp
index e253d6d..91174d3 100644
--- a/wifi/Android.bp
+++ b/wifi/Android.bp
@@ -47,7 +47,7 @@
// framework-wifi.jar. This is not a good idea, should move WifiNetworkScoreCache
// to a separate package.
"java/android/net/wifi/WifiNetworkScoreCache.java",
- "java/android/net/wifi/WifiOemMigrationHook.java",
+ "java/android/net/wifi/WifiMigration.java",
"java/android/net/wifi/nl80211/*.java",
":libwificond_ipc_aidl",
],
diff --git a/wifi/java/android/net/wifi/IScoreChangeCallback.aidl b/wifi/java/android/net/wifi/IScoreChangeCallback.aidl
index 462a978..d691f41 100644
--- a/wifi/java/android/net/wifi/IScoreChangeCallback.aidl
+++ b/wifi/java/android/net/wifi/IScoreChangeCallback.aidl
@@ -16,16 +16,14 @@
package android.net.wifi;
-import android.net.NetworkScore;
-
/**
- * Interface for Wi-Fi network score callback.
+ * Interface for Wi-Fi score callback.
*
* @hide
*/
oneway interface IScoreChangeCallback
{
- void onScoreChange(int sessionId, in NetworkScore score);
+ void onScoreChange(int sessionId, int score);
void onTriggerUpdateOfWifiUsabilityStats(int sessionId);
}
diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java
index 51927af..9256c57 100644
--- a/wifi/java/android/net/wifi/ScanResult.java
+++ b/wifi/java/android/net/wifi/ScanResult.java
@@ -24,8 +24,6 @@
import android.os.Parcel;
import android.os.Parcelable;
-import com.android.internal.annotations.VisibleForTesting;
-
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.nio.ByteBuffer;
@@ -861,19 +859,7 @@
}
}
- /**
- * Construct an empty scan result.
- *
- * Test code has a need to construct a ScanResult in a specific state.
- * (Note that mocking using Mockito does not work if the object needs to be parceled and
- * unparceled.)
- * Export a @SystemApi default constructor to allow tests to construct an empty ScanResult
- * object. The test can then directly set the fields it cares about.
- *
- * @hide
- */
- @SystemApi
- @VisibleForTesting
+ /** Construct an empty scan result. */
public ScanResult() {
}
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index c48e895..0229b84 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -1713,7 +1713,7 @@
* @return network disable reason string, or null if the reason is invalid.
*/
@Nullable
- public static String getNetworkDisableReasonString(
+ public static String getNetworkSelectionDisableReasonString(
@NetworkSelectionDisableReason int reason) {
DisableReasonInfo info = DISABLE_REASON_INFOS.get(reason);
if (info == null) {
@@ -1727,8 +1727,8 @@
* @return current network disable reason in String (for debug purpose)
* @hide
*/
- public String getNetworkDisableReasonString() {
- return getNetworkDisableReasonString(mNetworkSelectionDisableReason);
+ public String getNetworkSelectionDisableReasonString() {
+ return getNetworkSelectionDisableReasonString(mNetworkSelectionDisableReason);
}
/**
@@ -2189,17 +2189,21 @@
sbuf.append(" NetworkSelectionStatus ")
- .append(mNetworkSelectionStatus.getNetworkStatusString() + "\n");
+ .append(mNetworkSelectionStatus.getNetworkStatusString())
+ .append("\n");
if (mNetworkSelectionStatus.getNetworkSelectionDisableReason() > 0) {
sbuf.append(" mNetworkSelectionDisableReason ")
- .append(mNetworkSelectionStatus.getNetworkDisableReasonString() + "\n");
+ .append(mNetworkSelectionStatus.getNetworkSelectionDisableReasonString())
+ .append("\n");
for (int index = NetworkSelectionStatus.DISABLED_NONE;
index < NetworkSelectionStatus.NETWORK_SELECTION_DISABLED_MAX; index++) {
if (mNetworkSelectionStatus.getDisableReasonCounter(index) != 0) {
- sbuf.append(NetworkSelectionStatus.getNetworkDisableReasonString(index)
- + " counter:" + mNetworkSelectionStatus.getDisableReasonCounter(index)
- + "\n");
+ sbuf.append(
+ NetworkSelectionStatus.getNetworkSelectionDisableReasonString(index))
+ .append(" counter:")
+ .append(mNetworkSelectionStatus.getDisableReasonCounter(index))
+ .append("\n");
}
}
}
diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java
index 0c306b4..142854a 100644
--- a/wifi/java/android/net/wifi/WifiInfo.java
+++ b/wifi/java/android/net/wifi/WifiInfo.java
@@ -28,8 +28,6 @@
import android.os.Parcelable;
import android.text.TextUtils;
-import com.android.internal.annotations.VisibleForTesting;
-
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
@@ -380,20 +378,7 @@
}
}
- /**
- * WifiInfo exports an immutable public API.
- * However, test code has a need to construct a WifiInfo in a specific state.
- * (Note that mocking using Mockito does not work if the object needs to be parceled and
- * unparceled.)
- * Export a @SystemApi Builder to allow tests to construct a WifiInfo object
- * in the desired state, without sacrificing WifiInfo's immutability.
- *
- * @hide
- */
- // This builder was not made public to reduce confusion for external developers as there are
- // no legitimate uses for this builder except for testing.
- @SystemApi
- @VisibleForTesting
+ /** Builder for WifiInfo */
public static final class Builder {
private final WifiInfo mWifiInfo = new WifiInfo();
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index b1a4cac..dece855 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -39,7 +39,6 @@
import android.net.DhcpInfo;
import android.net.MacAddress;
import android.net.Network;
-import android.net.NetworkScore;
import android.net.NetworkStack;
import android.net.wifi.hotspot2.IProvisioningCallback;
import android.net.wifi.hotspot2.OsuProvider;
@@ -5994,11 +5993,10 @@
*
* @param sessionId The ID to indicate current Wi-Fi network connection obtained from
* {@link WifiConnectedNetworkScorer#start(int)}.
- * @param score The {@link android.net.NetworkScore} object representing the
- * characteristics of current Wi-Fi network. Populated by connected network
- * scorer in applications.
+ * @param score The score representing link quality of current Wi-Fi network connection.
+ * Populated by connected network scorer in applications..
*/
- void onScoreChange(int sessionId, @NonNull NetworkScore score);
+ void onScoreChange(int sessionId, int score);
/**
* Called by applications to trigger an update of {@link WifiUsabilityStatsEntry}.
@@ -6024,7 +6022,7 @@
}
@Override
- public void onScoreChange(int sessionId, @NonNull NetworkScore score) {
+ public void onScoreChange(int sessionId, int score) {
try {
mScoreChangeCallback.onScoreChange(sessionId, score);
} catch (RemoteException e) {
diff --git a/wifi/java/android/net/wifi/WifiOemMigrationHook.java b/wifi/java/android/net/wifi/WifiMigration.java
similarity index 93%
rename from wifi/java/android/net/wifi/WifiOemMigrationHook.java
rename to wifi/java/android/net/wifi/WifiMigration.java
index 5301dd0..a3482d7 100755
--- a/wifi/java/android/net/wifi/WifiOemMigrationHook.java
+++ b/wifi/java/android/net/wifi/WifiMigration.java
@@ -34,9 +34,9 @@
* @hide
*/
@SystemApi
-public final class WifiOemMigrationHook {
+public final class WifiMigration {
- private WifiOemMigrationHook() { }
+ private WifiMigration() { }
/**
* Container for all the wifi config data to migrate.
@@ -161,16 +161,16 @@
* Load data from OEM's config store.
* <p>
* Note:
- * <li> OEM's need to implement {@link #loadFromConfigStore()} ()} only if their
- * existing config store format or file locations differs from the vanilla AOSP implementation (
- * which is what the wifi mainline module understands).
+ * <li>OEMs need to implement {@link #loadFromConfigStore()} ()} only if their
+ * existing config store format or file locations differs from the vanilla AOSP implementation.
* </li>
- * <li> The wifi mainline module will invoke {@link #loadFromConfigStore()} method on every
+ * <li>The wifi mainline module will invoke {@link #loadFromConfigStore()} method on every
* bootup, its the responsibility of the OEM implementation to ensure that this method returns
* non-null data only on the first bootup. Once the migration is done, the OEM can safely delete
- * their config store files and then return null on any subsequent reboots. The first & only
- * relevant invocation of {@link #loadFromConfigStore()} occurs when a previously released
- * device upgrades to the wifi mainline module from an OEM implementation of the wifi stack.
+ * their config store files when {@link #removeConfigStore()} is invoked.
+ * <li>The first & only relevant invocation of {@link #loadFromConfigStore()} occurs when a
+ * previously released device upgrades to the wifi mainline module from an OEM implementation
+ * of the wifi stack.
* </li>
*
* @return Instance of {@link ConfigStoreMigrationData} for migrating data, null if no
@@ -178,11 +178,27 @@
*/
@Nullable
public static ConfigStoreMigrationData loadFromConfigStore() {
- // Note: OEM's should add code to parse data from their config store format here!
+ // Note: OEMs should add code to parse data from their config store format here!
return null;
}
/**
+ * Remove OEM's config store.
+ * <p>
+ * Note:
+ * <li>OEMs need to implement {@link #removeConfigStore()} only if their
+ * existing config store format or file locations differs from the vanilla AOSP implementation (
+ * which is what the wifi mainline module understands).
+ * </li>
+ * <li> The wifi mainline module will invoke {@link #removeConfigStore()} after it migrates
+ * all the existing data retrieved from {@link #loadFromConfigStore()}.
+ * </li>
+ */
+ public static void removeConfigStore() {
+ // Note: OEMs should remove their custom config store files here!
+ }
+
+ /**
* Container for all the wifi settings data to migrate.
*/
public static final class SettingsMigrationData implements Parcelable {
diff --git a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
index a854a4b..6dbb0bd 100644
--- a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
+++ b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
@@ -753,7 +753,7 @@
boolean isUserInteractionRequired,
boolean isUserAllowedToManuallyConnect,
boolean isInitialAutoJoinEnabled,
- boolean isNetworkUntrusted) {
+ boolean isNetworkUntrusted) {
checkNotNull(networkConfiguration);
this.wifiConfiguration = networkConfiguration;
this.passpointConfiguration = passpointConfiguration;
@@ -858,13 +858,106 @@
}
/**
+ * Get the BSSID, or null if unset.
+ * @see Builder#setBssid(MacAddress)
+ */
+ @Nullable
+ public MacAddress getBssid() {
+ if (wifiConfiguration.BSSID == null) {
+ return null;
+ }
+ return MacAddress.fromString(wifiConfiguration.BSSID);
+ }
+
+ /** @see Builder#setCredentialSharedWithUser(boolean) */
+ public boolean isCredentialSharedWithUser() {
+ return isUserAllowedToManuallyConnect;
+ }
+
+ /** @see Builder#setIsAppInteractionRequired(boolean) */
+ public boolean isAppInteractionRequired() {
+ return isAppInteractionRequired;
+ }
+
+ /** @see Builder#setIsEnhancedOpen(boolean) */
+ public boolean isEnhancedOpen() {
+ return wifiConfiguration.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.OWE);
+ }
+
+ /** @see Builder#setIsHiddenSsid(boolean) */
+ public boolean isHiddenSsid() {
+ return wifiConfiguration.hiddenSSID;
+ }
+
+ /** @see Builder#setIsInitialAutojoinEnabled(boolean) */
+ public boolean isInitialAutojoinEnabled() {
+ return isInitialAutoJoinEnabled;
+ }
+
+ /** @see Builder#setIsMetered(boolean) */
+ public boolean isMetered() {
+ return wifiConfiguration.meteredOverride == WifiConfiguration.METERED_OVERRIDE_METERED;
+ }
+
+ /** @see Builder#setIsUserInteractionRequired(boolean) */
+ public boolean isUserInteractionRequired() {
+ return isUserInteractionRequired;
+ }
+
+ /**
* Get the {@link PasspointConfiguration} associated with this Suggestion, or null if this
* Suggestion is not for a Passpoint network.
- * @hide
*/
- @SystemApi
@Nullable
- public PasspointConfiguration getPasspointConfiguration() {
+ public PasspointConfiguration getPasspointConfig() {
return passpointConfiguration;
}
+
+ /** @see Builder#setPriority(int) */
+ @IntRange(from = 0)
+ public int getPriority() {
+ return wifiConfiguration.priority;
+ }
+
+ /**
+ * Return the SSID of the network, or null if this is a Passpoint network.
+ * @see Builder#setSsid(String)
+ */
+ @Nullable
+ public String getSsid() {
+ if (wifiConfiguration.SSID == null) {
+ return null;
+ }
+ return WifiInfo.sanitizeSsid(wifiConfiguration.SSID);
+ }
+
+ /** @see Builder#setUntrusted(boolean) */
+ public boolean isUntrusted() {
+ return isNetworkUntrusted;
+ }
+
+ /**
+ * Get the WifiEnterpriseConfig, or null if unset.
+ * @see Builder#setWapiEnterpriseConfig(WifiEnterpriseConfig)
+ * @see Builder#setWpa2EnterpriseConfig(WifiEnterpriseConfig)
+ * @see Builder#setWpa3EnterpriseConfig(WifiEnterpriseConfig)
+ */
+ @Nullable
+ public WifiEnterpriseConfig getEnterpriseConfig() {
+ return wifiConfiguration.enterpriseConfig;
+ }
+
+ /**
+ * Get the passphrase, or null if unset.
+ * @see Builder#setWapiPassphrase(String)
+ * @see Builder#setWpa2Passphrase(String)
+ * @see Builder#setWpa3Passphrase(String)
+ */
+ @Nullable
+ public String getPassphrase() {
+ if (wifiConfiguration.preSharedKey == null) {
+ return null;
+ }
+ return WifiInfo.removeDoubleQuotes(wifiConfiguration.preSharedKey);
+ }
}