Merge changes from topic "simplify"
* changes:
Make rollback-app support --staged-ready-timeout flag
Simplify flags used to wait for staged session ready
diff --git a/apct-tests/perftests/utils/src/android/perftests/utils/BenchmarkState.java b/apct-tests/perftests/utils/src/android/perftests/utils/BenchmarkState.java
index 93bf541..e192861 100644
--- a/apct-tests/perftests/utils/src/android/perftests/utils/BenchmarkState.java
+++ b/apct-tests/perftests/utils/src/android/perftests/utils/BenchmarkState.java
@@ -53,7 +53,8 @@
private static final int NOT_STARTED = 0; // The benchmark has not started yet.
private static final int WARMUP = 1; // The benchmark is warming up.
private static final int RUNNING = 2; // The benchmark is running.
- private static final int FINISHED = 3; // The benchmark has stopped.
+ private static final int RUNNING_CUSTOMIZED = 3; // Running for customized measurement.
+ private static final int FINISHED = 4; // The benchmark has stopped.
private int mState = NOT_STARTED; // Current benchmark state.
@@ -76,6 +77,14 @@
private int mRepeatCount = 0;
+ /**
+ * Additional iteration that used to apply customized measurement. The result during these
+ * iterations won't be counted into {@link #mStats}.
+ */
+ private int mMaxCustomizedIterations;
+ private int mCustomizedIterations;
+ private CustomizedIterationListener mCustomizedIterationListener;
+
// Statistics. These values will be filled when the benchmark has finished.
// The computation needs double precision, but long int is fine for final reporting.
private Stats mStats;
@@ -110,6 +119,15 @@
mPaused = false;
}
+ /**
+ * This is used to run the benchmark with more information by enabling some debug mechanism but
+ * we don't want to account the special runs (slower) in the stats report.
+ */
+ public void setCustomizedIterations(int iterations, CustomizedIterationListener listener) {
+ mMaxCustomizedIterations = iterations;
+ mCustomizedIterationListener = listener;
+ }
+
private void beginWarmup() {
mStartTimeNs = System.nanoTime();
mIteration = 0;
@@ -141,6 +159,11 @@
Debug.stopMethodTracing();
}
mStats = new Stats(mResults);
+ if (mMaxCustomizedIterations > 0 && mCustomizedIterationListener != null) {
+ mState = RUNNING_CUSTOMIZED;
+ mCustomizedIterationListener.onStart(mCustomizedIterations);
+ return true;
+ }
mState = FINISHED;
return false;
}
@@ -180,6 +203,15 @@
"Resume the benchmark before finishing each step.");
}
return true;
+ case RUNNING_CUSTOMIZED:
+ mCustomizedIterationListener.onFinished(mCustomizedIterations);
+ mCustomizedIterations++;
+ if (mCustomizedIterations >= mMaxCustomizedIterations) {
+ mState = FINISHED;
+ return false;
+ }
+ mCustomizedIterationListener.onStart(mCustomizedIterations);
+ return true;
case FINISHED:
throw new IllegalStateException("The benchmark has finished.");
default:
@@ -240,4 +272,13 @@
status.putLong(key + "_standardDeviation", standardDeviation());
instrumentation.sendStatus(Activity.RESULT_OK, status);
}
+
+ /** The interface to receive the events of customized iteration. */
+ public interface CustomizedIterationListener {
+ /** The customized iteration starts. */
+ void onStart(int iteration);
+
+ /** The customized iteration finished. */
+ void onFinished(int iteration);
+ }
}
diff --git a/apct-tests/perftests/windowmanager/AndroidManifest.xml b/apct-tests/perftests/windowmanager/AndroidManifest.xml
index 85fd7176c..95ede34 100644
--- a/apct-tests/perftests/windowmanager/AndroidManifest.xml
+++ b/apct-tests/perftests/windowmanager/AndroidManifest.xml
@@ -29,5 +29,7 @@
</application>
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="com.android.perftests.wm"/>
+ android:targetPackage="com.android.perftests.wm">
+ <meta-data android:name="listener" android:value="android.wm.WmPerfRunListener" />
+ </instrumentation>
</manifest>
diff --git a/apct-tests/perftests/windowmanager/AndroidTest.xml b/apct-tests/perftests/windowmanager/AndroidTest.xml
index aee02c7a..6ac9f93 100644
--- a/apct-tests/perftests/windowmanager/AndroidTest.xml
+++ b/apct-tests/perftests/windowmanager/AndroidTest.xml
@@ -42,7 +42,7 @@
<option name="hidden-api-checks" value="false"/>
<!-- Listener related args for collecting the traces and waiting for the device to stabilize. -->
- <option name="device-listeners" value="android.wm.WmPerfRunListener,android.device.collectors.ProcLoadListener,android.device.collectors.PerfettoListener" />
+ <option name="device-listeners" value="android.device.collectors.ProcLoadListener,android.device.collectors.PerfettoListener" />
<!-- Guarantee that user defined RunListeners will be running before any of the default listeners defined in this runner. -->
<option name="instrumentation-arg" key="newRunListenerMode" value="true" />
@@ -57,8 +57,6 @@
<!-- PerfettoListener related arguments -->
<option name="instrumentation-arg" key="perfetto_config_text_proto" value="true" />
<option name="instrumentation-arg" key="perfetto_config_file" value="trace_config.textproto" />
-
- <option name="instrumentation-arg" key="newRunListenerMode" value="true" />
</test>
<metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
diff --git a/apct-tests/perftests/windowmanager/README.md b/apct-tests/perftests/windowmanager/README.md
index 05fa627..8b5292f 100644
--- a/apct-tests/perftests/windowmanager/README.md
+++ b/apct-tests/perftests/windowmanager/README.md
@@ -25,3 +25,11 @@
com.android.perftests.wm/androidx.test.runner.AndroidJUnitRunner
```
* `kill-bg` is optional.
+
+Test arguments
+ - kill-bg
+ * boolean: Kill background process before running test.
+ - profiling-iterations
+ * int: Run the extra iterations with enabling method profiling.
+ - profiling-sampling
+ * int: The interval (0=trace each method, default is 10) of sample profiling in microseconds.
diff --git a/apct-tests/perftests/windowmanager/src/android/wm/InternalWindowOperationPerfTest.java b/apct-tests/perftests/windowmanager/src/android/wm/InternalWindowOperationPerfTest.java
index 4ed3b4e..5c09ec2 100644
--- a/apct-tests/perftests/windowmanager/src/android/wm/InternalWindowOperationPerfTest.java
+++ b/apct-tests/perftests/windowmanager/src/android/wm/InternalWindowOperationPerfTest.java
@@ -41,7 +41,8 @@
/** Measure the performance of internal methods in window manager service by trace tag. */
@LargeTest
-public class InternalWindowOperationPerfTest extends WindowManagerPerfTestBase {
+public class InternalWindowOperationPerfTest extends WindowManagerPerfTestBase
+ implements ManualBenchmarkState.CustomizedIterationListener {
private static final String TAG = InternalWindowOperationPerfTest.class.getSimpleName();
@Rule
@@ -68,6 +69,9 @@
"finishActivity",
"startActivityInner");
+ private boolean mIsProfiling;
+ private boolean mIsTraceStarted;
+
@Test
@ManualBenchmarkTest(
targetTestDurationNs = 20 * TIME_1_S_IN_NS,
@@ -76,13 +80,13 @@
| StatsReport.FLAG_MAX | StatsReport.FLAG_COEFFICIENT_VAR))
public void testLaunchAndFinishActivity() throws Throwable {
final ManualBenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ state.setCustomizedIterations(getProfilingIterations(), this);
long measuredTimeNs = 0;
- boolean isTraceStarted = false;
while (state.keepRunning(measuredTimeNs)) {
- if (!isTraceStarted && !state.isWarmingUp()) {
+ if (!mIsTraceStarted && !mIsProfiling && !state.isWarmingUp()) {
startAsyncAtrace();
- isTraceStarted = true;
+ mIsTraceStarted = true;
}
final long startTime = SystemClock.elapsedRealtimeNanos();
mActivityRule.launchActivity();
@@ -91,7 +95,9 @@
measuredTimeNs = SystemClock.elapsedRealtimeNanos() - startTime;
}
- stopAsyncAtrace();
+ if (mIsTraceStarted) {
+ stopAsyncAtrace();
+ }
mTraceMarkParser.forAllSlices((key, slices) -> {
for (TraceMarkSlice slice : slices) {
@@ -108,7 +114,7 @@
SystemClock.sleep(TimeUnit.NANOSECONDS.toMillis(TIME_1_S_IN_NS));
}
- private void stopAsyncAtrace() throws IOException {
+ private void stopAsyncAtrace() {
final ParcelFileDescriptor pfd = sUiAutomation.executeShellCommand("atrace --async_stop");
final InputStream inputStream = new ParcelFileDescriptor.AutoCloseInputStream(pfd);
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
@@ -116,6 +122,28 @@
while ((line = reader.readLine()) != null) {
mTraceMarkParser.visit(line);
}
+ } catch (IOException e) {
+ Log.w(TAG, "Failed to read the result of stopped atrace", e);
+ }
+ }
+
+ @Override
+ public void onStart(int iteration) {
+ if (mIsTraceStarted) {
+ // Do not capture trace when profiling because the result will be much slower.
+ stopAsyncAtrace();
+ mIsTraceStarted = false;
+ }
+ mIsProfiling = true;
+ startProfiling(InternalWindowOperationPerfTest.class.getSimpleName()
+ + "_MethodTracing_" + iteration + ".trace");
+ }
+
+ @Override
+ public void onFinished(int iteration) {
+ stopProfiling();
+ if (iteration >= getProfilingIterations() - 1) {
+ mIsProfiling = false;
}
}
}
diff --git a/apct-tests/perftests/windowmanager/src/android/wm/RecentsAnimationPerfTest.java b/apct-tests/perftests/windowmanager/src/android/wm/RecentsAnimationPerfTest.java
index 6122ef2..efcabd8 100644
--- a/apct-tests/perftests/windowmanager/src/android/wm/RecentsAnimationPerfTest.java
+++ b/apct-tests/perftests/windowmanager/src/android/wm/RecentsAnimationPerfTest.java
@@ -62,7 +62,8 @@
@RunWith(Parameterized.class)
@LargeTest
-public class RecentsAnimationPerfTest extends WindowManagerPerfTestBase {
+public class RecentsAnimationPerfTest extends WindowManagerPerfTestBase
+ implements ManualBenchmarkState.CustomizedIterationListener {
private static Intent sRecentsIntent;
@Rule
@@ -162,6 +163,7 @@
| StatsReport.FLAG_COEFFICIENT_VAR))
public void testRecentsAnimation() throws Throwable {
final ManualBenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ state.setCustomizedIterations(getProfilingIterations(), this);
final IActivityTaskManager atm = ActivityTaskManager.getService();
final ArrayList<Pair<String, Boolean>> finishCases = new ArrayList<>();
@@ -230,7 +232,21 @@
state.addExtraResult("start", elapsedTimeNsOfStart);
// Ensure the animation callback is done.
- Assume.assumeTrue(recentsSemaphore.tryAcquire(TIME_5_S_IN_NS, TimeUnit.NANOSECONDS));
+ Assume.assumeTrue(recentsSemaphore.tryAcquire(
+ sIsProfilingMethod ? 10 * TIME_5_S_IN_NS : TIME_5_S_IN_NS,
+ TimeUnit.NANOSECONDS));
}
}
+
+ @Override
+ public void onStart(int iteration) {
+ startProfiling(RecentsAnimationPerfTest.class.getSimpleName()
+ + "_interval_" + intervalBetweenOperations
+ + "_MethodTracing_" + iteration + ".trace");
+ }
+
+ @Override
+ public void onFinished(int iteration) {
+ stopProfiling();
+ }
}
diff --git a/apct-tests/perftests/windowmanager/src/android/wm/RelayoutPerfTest.java b/apct-tests/perftests/windowmanager/src/android/wm/RelayoutPerfTest.java
index cff5663..2697428 100644
--- a/apct-tests/perftests/windowmanager/src/android/wm/RelayoutPerfTest.java
+++ b/apct-tests/perftests/windowmanager/src/android/wm/RelayoutPerfTest.java
@@ -54,7 +54,8 @@
@RunWith(Parameterized.class)
@LargeTest
@Presubmit
-public class RelayoutPerfTest extends WindowManagerPerfTestBase {
+public class RelayoutPerfTest extends WindowManagerPerfTestBase
+ implements BenchmarkState.CustomizedIterationListener {
private int mIteration;
@Rule
@@ -93,9 +94,22 @@
mActivityRule.runOnUiThread(() -> activity.setContentView(contentView));
getInstrumentation().waitForIdleSync();
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ state.setCustomizedIterations(getProfilingIterations(), this);
final RelayoutRunner relayoutRunner = new RelayoutRunner(activity, contentView.getWindow(),
() -> visibilities[mIteration++ % visibilities.length]);
- relayoutRunner.runBenchmark(mPerfStatusReporter.getBenchmarkState());
+ relayoutRunner.runBenchmark(state);
+ }
+
+ @Override
+ public void onStart(int iteration) {
+ startProfiling(RelayoutPerfTest.class.getSimpleName() + "_" + testName
+ + "_MethodTracing_" + iteration + ".trace");
+ }
+
+ @Override
+ public void onFinished(int iteration) {
+ stopProfiling();
}
/** A dummy view to get IWindow. */
diff --git a/apct-tests/perftests/windowmanager/src/android/wm/WindowAddRemovePerfTest.java b/apct-tests/perftests/windowmanager/src/android/wm/WindowAddRemovePerfTest.java
index c72cc9d..c52b130 100644
--- a/apct-tests/perftests/windowmanager/src/android/wm/WindowAddRemovePerfTest.java
+++ b/apct-tests/perftests/windowmanager/src/android/wm/WindowAddRemovePerfTest.java
@@ -48,8 +48,6 @@
public class WindowAddRemovePerfTest extends WindowManagerPerfTestBase
implements ManualBenchmarkState.CustomizedIterationListener {
- private static final int PROFILED_ITERATIONS = 2;
-
@Rule
public final PerfManualStatusReporter mPerfStatusReporter = new PerfManualStatusReporter();
@@ -64,7 +62,7 @@
sUiAutomation.dropShellPermissionIdentity();
}
- /** The last {@link #PROFILED_ITERATIONS} will provide the information of method profiling. */
+ /** The last customized iterations will provide the information of method profiling. */
@Override
public void onStart(int iteration) {
startProfiling(WindowAddRemovePerfTest.class.getSimpleName()
@@ -80,7 +78,7 @@
@ManualBenchmarkTest(warmupDurationNs = TIME_1_S_IN_NS, targetTestDurationNs = TIME_5_S_IN_NS)
public void testAddRemoveWindow() throws Throwable {
final ManualBenchmarkState state = mPerfStatusReporter.getBenchmarkState();
- state.setCustomizedIterations(PROFILED_ITERATIONS, this);
+ state.setCustomizedIterations(getProfilingIterations(), this);
new TestWindow().runBenchmark(state);
}
diff --git a/apct-tests/perftests/windowmanager/src/android/wm/WindowManagerPerfTestBase.java b/apct-tests/perftests/windowmanager/src/android/wm/WindowManagerPerfTestBase.java
index cc0e939a..b51a9a8 100644
--- a/apct-tests/perftests/windowmanager/src/android/wm/WindowManagerPerfTestBase.java
+++ b/apct-tests/perftests/windowmanager/src/android/wm/WindowManagerPerfTestBase.java
@@ -32,6 +32,7 @@
import androidx.test.runner.lifecycle.ActivityLifecycleMonitorRegistry;
import androidx.test.runner.lifecycle.Stage;
+import org.junit.After;
import org.junit.BeforeClass;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
@@ -52,18 +53,17 @@
/**
* The out directory matching the directory-keys of collector in AndroidTest.xml. The directory
- * is in /data because while enabling method profling of system server, it cannot write the
+ * is in /data because while enabling method profiling of system server, it cannot write the
* trace to external storage.
*/
static final File BASE_OUT_PATH = new File("/data/local/tmp/WmPerfTests");
+ static boolean sIsProfilingMethod;
+
@BeforeClass
public static void setUpOnce() {
final Context context = getInstrumentation().getContext();
- if (!BASE_OUT_PATH.exists()) {
- executeShellCommand("mkdir -p " + BASE_OUT_PATH);
- }
if (!context.getSystemService(PowerManager.class).isInteractive()
|| context.getSystemService(KeyguardManager.class).isKeyguardLocked()) {
executeShellCommand("input keyevent KEYCODE_WAKEUP");
@@ -73,6 +73,14 @@
.addCategory(Intent.CATEGORY_HOME).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
}
+ @After
+ public void tearDown() {
+ // Make sure that profiling is stopped if test fails.
+ if (sIsProfilingMethod) {
+ stopProfiling();
+ }
+ }
+
/**
* Executes shell command with reading the output. It may also used to block until the current
* command is completed.
@@ -93,12 +101,26 @@
}
/** Starts method tracing on system server. */
- void startProfiling(String subPath) {
- executeShellCommand("am profile start system " + new File(BASE_OUT_PATH, subPath));
+ static void startProfiling(String subPath) {
+ if (!BASE_OUT_PATH.exists()) {
+ executeShellCommand("mkdir -p " + BASE_OUT_PATH);
+ }
+ final String samplingArg = WmPerfRunListener.sSamplingIntervalUs > 0
+ ? ("--sampling " + WmPerfRunListener.sSamplingIntervalUs)
+ : "";
+ executeShellCommand("am profile start " + samplingArg + " system "
+ + new File(BASE_OUT_PATH, subPath));
+ sIsProfilingMethod = true;
}
- void stopProfiling() {
+ static void stopProfiling() {
executeShellCommand("am profile stop system");
+ sIsProfilingMethod = false;
+ }
+
+ /** Returns how many iterations should run with method tracing. */
+ static int getProfilingIterations() {
+ return WmPerfRunListener.sProfilingIterations;
}
static void runWithShellPermissionIdentity(Runnable runnable) {
diff --git a/apct-tests/perftests/windowmanager/src/android/wm/WmPerfRunListener.java b/apct-tests/perftests/windowmanager/src/android/wm/WmPerfRunListener.java
index 6eb85aa..d955289 100644
--- a/apct-tests/perftests/windowmanager/src/android/wm/WmPerfRunListener.java
+++ b/apct-tests/perftests/windowmanager/src/android/wm/WmPerfRunListener.java
@@ -31,6 +31,7 @@
import android.os.Bundle;
import android.os.SystemClock;
import android.provider.Settings;
+import android.util.Log;
import android.view.WindowManagerPolicyConstants;
import android.wm.WindowManagerPerfTestBase.SettingsSession;
@@ -46,10 +47,22 @@
/** Prepare the preconditions before running performance test. */
public class WmPerfRunListener extends RunListener {
+ private static final String TAG = WmPerfRunListener.class.getSimpleName();
- private static final String OPTION_KILL_BACKGROUND = "kill-bg";
+ private static final String ARGUMENT_LOG_ONLY = "log";
+ private static final String ARGUMENT_KILL_BACKGROUND = "kill-bg";
+ private static final String ARGUMENT_PROFILING_ITERATIONS = "profiling-iterations";
+ private static final String ARGUMENT_PROFILING_SAMPLING = "profiling-sampling";
+ private static final String DEFAULT_PROFILING_ITERATIONS = "0";
+ private static final String DEFAULT_PROFILING_SAMPLING_US = "10";
private static final long KILL_BACKGROUND_WAIT_MS = 3000;
+ /** The requested iterations to run with method profiling. */
+ static int sProfilingIterations;
+
+ /** The interval of sample profiling in microseconds. */
+ static int sSamplingIntervalUs;
+
private final Context mContext = InstrumentationRegistry.getInstrumentation().getContext();
private long mWaitPreconditionDoneMs = 500;
@@ -83,6 +96,16 @@
@Override
public void testRunStarted(Description description) {
final Bundle arguments = InstrumentationRegistry.getArguments();
+ // If true, it only logs the method names without running.
+ final boolean skip = Boolean.parseBoolean(arguments.getString(ARGUMENT_LOG_ONLY, "false"));
+ Log.i(TAG, "arguments=" + arguments);
+ if (skip) {
+ return;
+ }
+ sProfilingIterations = Integer.parseInt(
+ arguments.getString(ARGUMENT_PROFILING_ITERATIONS, DEFAULT_PROFILING_ITERATIONS));
+ sSamplingIntervalUs = Integer.parseInt(
+ arguments.getString(ARGUMENT_PROFILING_SAMPLING, DEFAULT_PROFILING_SAMPLING_US));
// Use gesture navigation for consistency.
mNavigationModeSetting.set(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL);
@@ -97,7 +120,7 @@
});
PhoneWindow.sendCloseSystemWindows(mContext, "WmPerfTests");
- if (Boolean.parseBoolean(arguments.getString(OPTION_KILL_BACKGROUND))) {
+ if (Boolean.parseBoolean(arguments.getString(ARGUMENT_KILL_BACKGROUND))) {
runWithShellPermissionIdentity(this::killBackgroundProcesses);
mWaitPreconditionDoneMs = KILL_BACKGROUND_WAIT_MS;
}
diff --git a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
index 6bc95bf..c033138 100644
--- a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
+++ b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
@@ -2131,7 +2131,7 @@
}
public List<UserHandle> getValidCrossProfileTargets(String pkg, int userId) {
- final int uid = mPackageManagerInternal.getPackageUidInternal(pkg, 0, userId);
+ final int uid = mPackageManagerInternal.getPackageUid(pkg, /* flags= */ 0, userId);
final AndroidPackage aPkg = mPackageManagerInternal.getPackage(uid);
if (uid < 0
|| aPkg == null
diff --git a/api/current.txt b/api/current.txt
index 36c67f2..c6af6be 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -31624,6 +31624,7 @@
method @Nullable public String getPassphrase();
method @Nullable public android.net.wifi.hotspot2.PasspointConfiguration getPasspointConfig();
method @IntRange(from=0) public int getPriority();
+ method public int getPriorityGroup();
method @Nullable public String getSsid();
method public boolean isAppInteractionRequired();
method public boolean isCredentialSharedWithUser();
@@ -31650,6 +31651,7 @@
method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setIsUserInteractionRequired(boolean);
method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setPasspointConfig(@NonNull android.net.wifi.hotspot2.PasspointConfiguration);
method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setPriority(@IntRange(from=0) int);
+ method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setPriorityGroup(int);
method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setSsid(@NonNull String);
method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setUntrusted(boolean);
method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setWapiEnterpriseConfig(@NonNull android.net.wifi.WifiEnterpriseConfig);
@@ -47842,6 +47844,7 @@
method public void onDataConnectionStateChanged(int);
method public void onDataConnectionStateChanged(int, int);
method @RequiresPermission("android.permission.READ_PHONE_STATE") public void onDisplayInfoChanged(@NonNull android.telephony.TelephonyDisplayInfo);
+ method public void onEmergencyNumberListChanged(@NonNull java.util.Map<java.lang.Integer,java.util.List<android.telephony.emergency.EmergencyNumber>>);
method @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public void onImsCallDisconnectCauseChanged(@NonNull android.telephony.ims.ImsReasonInfo);
method public void onMessageWaitingIndicatorChanged(boolean);
method @RequiresPermission("android.permission.MODIFY_PHONE_STATE") public void onPreciseDataConnectionStateChanged(@NonNull android.telephony.PreciseDataConnectionState);
diff --git a/api/system-current.txt b/api/system-current.txt
index 28c1eaf..41e8593 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -10817,7 +10817,8 @@
public class PhoneStateListener {
method public void onCallAttributesChanged(@NonNull android.telephony.CallAttributes);
- method public void onOutgoingEmergencyCall(@NonNull android.telephony.emergency.EmergencyNumber);
+ method @Deprecated public void onOutgoingEmergencyCall(@NonNull android.telephony.emergency.EmergencyNumber);
+ method public void onOutgoingEmergencyCall(@NonNull android.telephony.emergency.EmergencyNumber, int);
method public void onOutgoingEmergencySms(@NonNull android.telephony.emergency.EmergencyNumber);
method @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public void onPreciseCallStateChanged(@NonNull android.telephony.PreciseCallState);
method public void onRadioPowerStateChanged(int);
diff --git a/api/test-current.txt b/api/test-current.txt
index a97a9e8..529dcf7 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -4076,7 +4076,8 @@
}
public class PhoneStateListener {
- method public void onOutgoingEmergencyCall(@NonNull android.telephony.emergency.EmergencyNumber);
+ method @Deprecated public void onOutgoingEmergencyCall(@NonNull android.telephony.emergency.EmergencyNumber);
+ method public void onOutgoingEmergencyCall(@NonNull android.telephony.emergency.EmergencyNumber, int);
method public void onOutgoingEmergencySms(@NonNull android.telephony.emergency.EmergencyNumber);
field @RequiresPermission("android.permission.READ_ACTIVE_EMERGENCY_SESSION") public static final int LISTEN_OUTGOING_EMERGENCY_CALL = 268435456; // 0x10000000
field @RequiresPermission("android.permission.READ_ACTIVE_EMERGENCY_SESSION") public static final int LISTEN_OUTGOING_EMERGENCY_SMS = 536870912; // 0x20000000
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index d67b986..caca05a 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -2242,9 +2242,9 @@
* Resources if one has already been created.
*/
Resources getTopLevelResources(String resDir, String[] splitResDirs, String[] overlayDirs,
- String[] libDirs, int displayId, LoadedApk pkgInfo) {
+ String[] libDirs, LoadedApk pkgInfo) {
return mResourcesManager.getResources(null, resDir, splitResDirs, overlayDirs, libDirs,
- displayId, null, pkgInfo.getCompatibilityInfo(), pkgInfo.getClassLoader(), null);
+ null, null, pkgInfo.getCompatibilityInfo(), pkgInfo.getClassLoader(), null);
}
@UnsupportedAppUsage
@@ -5656,6 +5656,11 @@
throw new IllegalArgumentException("Activity token not set. Is the activity attached?");
}
+ // WindowConfiguration differences aren't considered as public, check it separately.
+ // multi-window / pip mode changes, if any, should be sent before the configuration
+ // change callback, see also PinnedStackTests#testConfigurationChangeOrderDuringTransition
+ handleWindowingModeChangeIfNeeded(activity, newConfig);
+
final boolean movedToDifferentDisplay = isDifferentDisplay(activity, displayId);
boolean shouldReportChange = false;
if (activity.mCurrentConfig == null) {
@@ -5692,8 +5697,7 @@
// many places.
final Configuration finalOverrideConfig = createNewConfigAndUpdateIfNotNull(
amOverrideConfig, contextThemeWrapperOverrideConfig);
- mResourcesManager.updateResourcesForActivity(activityToken, finalOverrideConfig,
- displayId, movedToDifferentDisplay);
+ mResourcesManager.updateResourcesForActivity(activityToken, finalOverrideConfig, displayId);
activity.mConfigChangeFlags = 0;
activity.mCurrentConfig = new Configuration(newConfig);
@@ -5709,11 +5713,6 @@
}
if (shouldReportChange) {
- // multi-window / pip mode changes, if any, should be sent before the configuration
- // change callback, see also
- // PinnedStackTests#testConfigurationChangeOrderDuringTransition
- handleWindowingModeChangeIfNeeded(activity, newConfig);
-
activity.mCalled = false;
activity.onConfigurationChanged(configToReport);
if (!activity.mCalled) {
@@ -6014,6 +6013,11 @@
r.mPendingOverrideConfig = null;
}
+ if (displayId == INVALID_DISPLAY) {
+ // If INVALID_DISPLAY is passed assume that the activity should keep its current
+ // display.
+ displayId = r.activity.getDisplayId();
+ }
final boolean movedToDifferentDisplay = isDifferentDisplay(r.activity, displayId);
if (r.overrideConfig != null && !r.overrideConfig.isOtherSeqNewer(overrideConfig)
&& !movedToDifferentDisplay) {
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 676c6c0..340d5a1 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -96,7 +96,6 @@
import android.util.DebugUtils;
import android.util.LauncherIcons;
import android.util.Log;
-import android.view.Display;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.Immutable;
@@ -1748,7 +1747,7 @@
final Resources r = mContext.mMainThread.getTopLevelResources(
sameUid ? app.sourceDir : app.publicSourceDir,
sameUid ? app.splitSourceDirs : app.splitPublicSourceDirs,
- app.resourceDirs, app.sharedLibraryFiles, Display.DEFAULT_DISPLAY,
+ app.resourceDirs, app.sharedLibraryFiles,
mContext.mPackageInfo);
if (r != null) {
return r;
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 1b3e865..cee607f 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -237,6 +237,15 @@
private @NonNull Resources mResources;
private @Nullable Display mDisplay; // may be null if invalid display or not initialized yet.
+ /**
+ * If set to {@code true} the resources for this context will be configured for mDisplay which
+ * will override the display configuration inherited from {@link #mToken} (or the global
+ * configuration if mToken is null). Typically set for display contexts and contexts derived
+ * from display contexts where changes to the activity display and the global configuration
+ * display should not impact their resources.
+ */
+ private boolean mForceDisplayOverrideInResources;
+
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
private final int mFlags;
@@ -2259,8 +2268,8 @@
}
private static Resources createResources(IBinder activityToken, LoadedApk pi, String splitName,
- int displayId, Configuration overrideConfig, CompatibilityInfo compatInfo,
- List<ResourcesLoader> resourcesLoader) {
+ @Nullable Integer overrideDisplayId, Configuration overrideConfig,
+ CompatibilityInfo compatInfo, List<ResourcesLoader> resourcesLoader) {
final String[] splitResDirs;
final ClassLoader classLoader;
try {
@@ -2274,7 +2283,7 @@
splitResDirs,
pi.getOverlayDirs(),
pi.getApplicationInfo().sharedLibraryFiles,
- displayId,
+ overrideDisplayId,
overrideConfig,
compatInfo,
classLoader,
@@ -2291,8 +2300,10 @@
new UserHandle(UserHandle.getUserId(application.uid)), flags, null, null);
final int displayId = getDisplayId();
+ final Integer overrideDisplayId = mForceDisplayOverrideInResources
+ ? displayId : null;
- c.setResources(createResources(mToken, pi, null, displayId, null,
+ c.setResources(createResources(mToken, pi, null, overrideDisplayId, null,
getDisplayAdjustments(displayId).getCompatibilityInfo(), null));
if (c.mResources != null) {
return c;
@@ -2326,8 +2337,10 @@
mToken, user, flags, null, null);
final int displayId = getDisplayId();
+ final Integer overrideDisplayId = mForceDisplayOverrideInResources
+ ? displayId : null;
- c.setResources(createResources(mToken, pi, null, displayId, null,
+ c.setResources(createResources(mToken, pi, null, overrideDisplayId, null,
getDisplayAdjustments(displayId).getCompatibilityInfo(), null));
if (c.mResources != null) {
return c;
@@ -2361,15 +2374,13 @@
final ContextImpl context = new ContextImpl(this, mMainThread, mPackageInfo,
mAttributionTag, splitName, mToken, mUser, mFlags, classLoader, null);
- final int displayId = getDisplayId();
-
context.setResources(ResourcesManager.getInstance().getResources(
mToken,
mPackageInfo.getResDir(),
paths,
mPackageInfo.getOverlayDirs(),
mPackageInfo.getApplicationInfo().sharedLibraryFiles,
- displayId,
+ mForceDisplayOverrideInResources ? getDisplayId() : null,
null,
mPackageInfo.getCompatibilityInfo(),
classLoader,
@@ -2383,12 +2394,23 @@
throw new IllegalArgumentException("overrideConfiguration must not be null");
}
+ if (mForceDisplayOverrideInResources) {
+ // Ensure the resources display metrics are adjusted to match the display this context
+ // is based on.
+ Configuration displayAdjustedConfig = new Configuration();
+ displayAdjustedConfig.setTo(mDisplay.getDisplayAdjustments().getConfiguration(),
+ ActivityInfo.CONFIG_WINDOW_CONFIGURATION, 1);
+ displayAdjustedConfig.updateFrom(overrideConfiguration);
+ overrideConfiguration = displayAdjustedConfig;
+ }
+
ContextImpl context = new ContextImpl(this, mMainThread, mPackageInfo, mAttributionTag,
mSplitName, mToken, mUser, mFlags, mClassLoader, null);
final int displayId = getDisplayId();
-
- context.setResources(createResources(mToken, mPackageInfo, mSplitName, displayId,
+ final Integer overrideDisplayId = mForceDisplayOverrideInResources
+ ? displayId : null;
+ context.setResources(createResources(mToken, mPackageInfo, mSplitName, overrideDisplayId,
overrideConfiguration, getDisplayAdjustments(displayId).getCompatibilityInfo(),
mResources.getLoaders()));
context.mIsUiContext = isUiContext() || isOuterUiContext();
@@ -2406,11 +2428,20 @@
final int displayId = display.getDisplayId();
+ // Ensure the resources display metrics are adjusted to match the provided display.
+ Configuration overrideConfig = new Configuration();
+ overrideConfig.setTo(display.getDisplayAdjustments().getConfiguration(),
+ ActivityInfo.CONFIG_WINDOW_CONFIGURATION, 1);
+
context.setResources(createResources(mToken, mPackageInfo, mSplitName, displayId,
- null, getDisplayAdjustments(displayId).getCompatibilityInfo(),
+ overrideConfig, display.getDisplayAdjustments().getCompatibilityInfo(),
mResources.getLoaders()));
context.mDisplay = display;
context.mIsAssociatedWithDisplay = true;
+ // Display contexts and any context derived from a display context should always override
+ // the display that would otherwise be inherited from mToken (or the global configuration if
+ // mToken is null).
+ context.mForceDisplayOverrideInResources = true;
return context;
}
@@ -2428,8 +2459,10 @@
ContextImpl context = new ContextImpl(this, mMainThread, mPackageInfo, mAttributionTag,
mSplitName, token, mUser, mFlags, mClassLoader, null);
context.mIsUiContext = true;
-
context.mIsAssociatedWithDisplay = true;
+ // Window contexts receive configurations directly from the server and as such do not
+ // need to override their display in ResourcesManager.
+ context.mForceDisplayOverrideInResources = false;
return context;
}
@@ -2772,6 +2805,7 @@
mDisplay = container.mDisplay;
mIsAssociatedWithDisplay = container.mIsAssociatedWithDisplay;
mIsSystemOrSystemUiContext = container.mIsSystemOrSystemUiContext;
+ mForceDisplayOverrideInResources = container.mForceDisplayOverrideInResources;
} else {
mBasePackageName = packageInfo.mPackageName;
ApplicationInfo ainfo = packageInfo.getApplicationInfo();
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index aa6a08b..202b615 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -56,7 +56,6 @@
import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;
-import android.view.Display;
import android.view.DisplayAdjustments;
import com.android.internal.util.ArrayUtils;
@@ -367,7 +366,7 @@
mResources = ResourcesManager.getInstance().getResources(null, mResDir,
splitPaths, mOverlayDirs, mApplicationInfo.sharedLibraryFiles,
- Display.DEFAULT_DISPLAY, null, getCompatibilityInfo(),
+ null, null, getCompatibilityInfo(),
getClassLoader(), mApplication == null ? null
: mApplication.getResources().getLoaders());
}
@@ -1231,7 +1230,7 @@
mResources = ResourcesManager.getInstance().getResources(null, mResDir,
splitPaths, mOverlayDirs, mApplicationInfo.sharedLibraryFiles,
- Display.DEFAULT_DISPLAY, null, getCompatibilityInfo(),
+ null, null, getCompatibilityInfo(),
getClassLoader(), null);
}
return mResources;
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index 1aafe2c..7cd3fca 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -17,6 +17,8 @@
package android.app;
import static android.app.ActivityThread.DEBUG_CONFIGURATION;
+import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.Display.INVALID_DISPLAY;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -61,6 +63,7 @@
import java.util.Objects;
import java.util.WeakHashMap;
import java.util.function.Consumer;
+import java.util.function.Function;
/** @hide */
public class ResourcesManager {
@@ -82,6 +85,12 @@
private final Configuration mResConfiguration = new Configuration();
/**
+ * The display upon which all Resources are based. Activity, window token, and display context
+ * resources apply their overrides to this display id.
+ */
+ private int mResDisplayId = DEFAULT_DISPLAY;
+
+ /**
* A mapping of ResourceImpls and their configurations. These are heavy weight objects
* which should be reused as much as possible.
*/
@@ -155,20 +164,79 @@
private final ArrayMap<ApkKey, WeakReference<ApkAssets>> mCachedApkAssets = new ArrayMap<>();
/**
- * Resources and base configuration override associated with an Activity.
+ * Class containing the base configuration override and set of resources associated with an
+ * Activity or {@link WindowContext}.
*/
private static class ActivityResources {
- @UnsupportedAppUsage
- private ActivityResources() {
- }
+ /**
+ * Override config to apply to all resources associated with the token this instance is
+ * based on.
+ *
+ * @see #activityResources
+ * @see #getResources(IBinder, String, String[], String[], String[], Integer, Configuration,
+ * CompatibilityInfo, ClassLoader, List)
+ */
public final Configuration overrideConfig = new Configuration();
- public final ArrayList<WeakReference<Resources>> activityResources = new ArrayList<>();
- final ReferenceQueue<Resources> activityResourcesQueue = new ReferenceQueue<>();
+
+ /**
+ * The display to apply to all resources associated with the token this instance is based
+ * on.
+ */
+ public int overrideDisplayId;
+
+ /** List of {@link ActivityResource} associated with the token this instance is based on. */
+ public final ArrayList<ActivityResource> activityResources = new ArrayList<>();
+
+ public final ReferenceQueue<Resources> activityResourcesQueue = new ReferenceQueue<>();
+
+ @UnsupportedAppUsage
+ private ActivityResources() {}
+
+ /** Returns the number of live resource references within {@code activityResources}. */
+ public int countLiveReferences() {
+ int count = 0;
+ for (int i = 0; i < activityResources.size(); i++) {
+ WeakReference<Resources> resources = activityResources.get(i).resources;
+ if (resources != null && resources.get() != null) {
+ count++;
+ }
+ }
+ return count;
+ }
}
/**
- * Each Activity may has a base override configuration that is applied to each Resources object,
- * which in turn may have their own override configuration specified.
+ * Contains a resource derived from an {@link Activity} or {@link WindowContext} and information
+ * about how this resource expects its configuration to differ from the token's.
+ *
+ * @see ActivityResources
+ */
+ // TODO: Ideally this class should be called something token related, like TokenBasedResource.
+ private static class ActivityResource {
+ /**
+ * The override configuration applied on top of the token's override config for this
+ * resource.
+ */
+ public final Configuration overrideConfig = new Configuration();
+
+ /**
+ * If non-null this resource expects its configuration to override the display from the
+ * token's configuration.
+ *
+ * @see #applyDisplayMetricsToConfiguration(DisplayMetrics, Configuration)
+ */
+ @Nullable
+ public Integer overrideDisplayId;
+
+ @Nullable
+ public WeakReference<Resources> resources;
+
+ private ActivityResource() {}
+ }
+
+ /**
+ * Each Activity or WindowToken may has a base override configuration that is applied to each
+ * Resources object, which in turn may have their own override configuration specified.
*/
@UnsupportedAppUsage
private final WeakHashMap<IBinder, ActivityResources> mActivityResourceReferences =
@@ -241,8 +309,7 @@
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
public DisplayMetrics getDisplayMetrics() {
- return getDisplayMetrics(Display.DEFAULT_DISPLAY,
- DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
+ return getDisplayMetrics(mResDisplayId, DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
}
/**
@@ -260,8 +327,8 @@
return dm;
}
- private static void applyNonDefaultDisplayMetricsToConfiguration(
- @NonNull DisplayMetrics dm, @NonNull Configuration config) {
+ private static void applyDisplayMetricsToConfiguration(@NonNull DisplayMetrics dm,
+ @NonNull Configuration config) {
config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
config.densityDpi = dm.densityDpi;
config.screenWidthDp = (int) (dm.widthPixels / dm.density);
@@ -502,7 +569,7 @@
int references = countLiveReferences(mResourceReferences);
for (ActivityResources activityResources : mActivityResourceReferences.values()) {
- references += countLiveReferences(activityResources.activityResources);
+ references += activityResources.countLiveReferences();
}
pw.println(references);
@@ -511,38 +578,36 @@
}
}
- private Configuration generateConfig(@NonNull ResourcesKey key, @NonNull DisplayMetrics dm) {
+ private Configuration generateConfig(@NonNull ResourcesKey key) {
Configuration config;
- final boolean isDefaultDisplay = (key.mDisplayId == Display.DEFAULT_DISPLAY);
final boolean hasOverrideConfig = key.hasOverrideConfiguration();
- if (!isDefaultDisplay || hasOverrideConfig) {
+ if (hasOverrideConfig) {
config = new Configuration(getConfiguration());
- if (!isDefaultDisplay) {
- applyNonDefaultDisplayMetricsToConfiguration(dm, config);
- }
- if (hasOverrideConfig) {
- config.updateFrom(key.mOverrideConfiguration);
- if (DEBUG) Slog.v(TAG, "Applied overrideConfig=" + key.mOverrideConfiguration);
- }
+ config.updateFrom(key.mOverrideConfiguration);
+ if (DEBUG) Slog.v(TAG, "Applied overrideConfig=" + key.mOverrideConfiguration);
} else {
config = getConfiguration();
}
return config;
}
+ private int generateDisplayId(@NonNull ResourcesKey key) {
+ return key.mDisplayId != INVALID_DISPLAY ? key.mDisplayId : mResDisplayId;
+ }
+
private @Nullable ResourcesImpl createResourcesImpl(@NonNull ResourcesKey key,
@Nullable ApkAssetsSupplier apkSupplier) {
- final DisplayAdjustments daj = new DisplayAdjustments(key.mOverrideConfiguration);
- daj.setCompatibilityInfo(key.mCompatInfo);
-
final AssetManager assets = createAssetManager(key, apkSupplier);
if (assets == null) {
return null;
}
- final DisplayMetrics dm = getDisplayMetrics(key.mDisplayId, daj);
- final Configuration config = generateConfig(key, dm);
- final ResourcesImpl impl = new ResourcesImpl(assets, dm, config, daj);
+ final DisplayAdjustments daj = new DisplayAdjustments(key.mOverrideConfiguration);
+ daj.setCompatibilityInfo(key.mCompatInfo);
+
+ final Configuration config = generateConfig(key);
+ final DisplayMetrics displayMetrics = getDisplayMetrics(generateDisplayId(key), daj);
+ final ResourcesImpl impl = new ResourcesImpl(assets, displayMetrics, config, daj);
if (DEBUG) {
Slog.d(TAG, "- creating impl=" + impl + " with key: " + key);
@@ -652,8 +717,8 @@
final int size = activityResources.activityResources.size();
for (int index = 0; index < size; index++) {
- WeakReference<Resources> ref = activityResources.activityResources.get(index);
- Resources resources = ref.get();
+ ActivityResource activityResource = activityResources.activityResources.get(index);
+ Resources resources = activityResource.resources.get();
ResourcesKey key = resources == null ? null : findKeyForResourceImplLocked(
resources.getImpl());
@@ -667,20 +732,28 @@
return null;
}
- private @NonNull Resources createResourcesForActivityLocked(@NonNull IBinder activityToken,
+ @NonNull
+ private Resources createResourcesForActivityLocked(@NonNull IBinder activityToken,
+ @NonNull Configuration initialOverrideConfig, @Nullable Integer overrideDisplayId,
@NonNull ClassLoader classLoader, @NonNull ResourcesImpl impl,
@NonNull CompatibilityInfo compatInfo) {
final ActivityResources activityResources = getOrCreateActivityResourcesStructLocked(
activityToken);
cleanupReferences(activityResources.activityResources,
- activityResources.activityResourcesQueue);
+ activityResources.activityResourcesQueue,
+ (r) -> r.resources);
Resources resources = compatInfo.needsCompatResources() ? new CompatResources(classLoader)
: new Resources(classLoader);
resources.setImpl(impl);
resources.setCallbacks(mUpdateCallbacks);
- activityResources.activityResources.add(
- new WeakReference<>(resources, activityResources.activityResourcesQueue));
+
+ ActivityResource activityResource = new ActivityResource();
+ activityResource.resources = new WeakReference<>(resources,
+ activityResources.activityResourcesQueue);
+ activityResource.overrideConfig.setTo(initialOverrideConfig);
+ activityResource.overrideDisplayId = overrideDisplayId;
+ activityResources.activityResources.add(activityResource);
if (DEBUG) {
Slog.d(TAG, "- creating new ref=" + resources);
Slog.d(TAG, "- setting ref=" + resources + " with impl=" + impl);
@@ -706,7 +779,7 @@
/**
* Creates base resources for a binder token. Calls to
- * {@link #getResources(IBinder, String, String[], String[], String[], int, Configuration,
+ * {@link #getResources(IBinder, String, String[], String[], String[], Integer, Configuration,
* CompatibilityInfo, ClassLoader, List)} with the same binder token will have their override
* configurations merged with the one specified here.
*
@@ -743,7 +816,7 @@
overlayDirs,
libDirs,
displayId,
- overrideConfig != null ? new Configuration(overrideConfig) : null, // Copy
+ overrideConfig,
compatInfo,
loaders == null ? null : loaders.toArray(new ResourcesLoader[0]));
classLoader = classLoader != null ? classLoader : ClassLoader.getSystemClassLoader();
@@ -759,10 +832,7 @@
}
// Update any existing Activity Resources references.
- updateResourcesForActivity(token, overrideConfig, displayId,
- false /* movedToDifferentDisplay */);
-
- rebaseKeyForActivity(token, key);
+ updateResourcesForActivity(token, overrideConfig, displayId);
synchronized (this) {
Resources resources = findResourcesForActivityLocked(token, key,
@@ -773,7 +843,9 @@
}
// Now request an actual Resources object.
- return createResources(token, key, classLoader, /* apkSupplier */ null);
+ return createResourcesForActivity(token, key,
+ /* initialOverrideConfig */ Configuration.EMPTY, /* overrideDisplayId */ null,
+ classLoader, /* apkSupplier */ null);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
}
@@ -781,39 +853,94 @@
/**
* Rebases a key's override config on top of the Activity's base override.
+ *
+ * @param activityToken the token the supplied {@code key} is derived from.
+ * @param key the key to rebase
+ * @param overridesActivityDisplay whether this key is overriding the display from the token
*/
- private void rebaseKeyForActivity(IBinder activityToken, ResourcesKey key) {
+ private void rebaseKeyForActivity(IBinder activityToken, ResourcesKey key,
+ boolean overridesActivityDisplay) {
synchronized (this) {
final ActivityResources activityResources =
getOrCreateActivityResourcesStructLocked(activityToken);
- // Rebase the key's override config on top of the Activity's base override.
- if (key.hasOverrideConfiguration()
- && !activityResources.overrideConfig.equals(Configuration.EMPTY)) {
- final Configuration temp = new Configuration(activityResources.overrideConfig);
- temp.updateFrom(key.mOverrideConfiguration);
- key.mOverrideConfiguration.setTo(temp);
+ if (key.mDisplayId == INVALID_DISPLAY) {
+ key.mDisplayId = activityResources.overrideDisplayId;
}
+
+ Configuration config;
+ if (key.hasOverrideConfiguration()) {
+ config = new Configuration(activityResources.overrideConfig);
+ config.updateFrom(key.mOverrideConfiguration);
+ } else {
+ config = activityResources.overrideConfig;
+ }
+
+ if (overridesActivityDisplay
+ && key.mOverrideConfiguration.windowConfiguration.getAppBounds() == null) {
+ if (!key.hasOverrideConfiguration()) {
+ // Make a copy to handle the case where the override config is set to defaults.
+ config = new Configuration(config);
+ }
+
+ // If this key is overriding the display from the token and the key's
+ // window config app bounds is null we need to explicitly override this to
+ // ensure the display adjustments are as expected.
+ config.windowConfiguration.setAppBounds(null);
+ }
+
+ key.mOverrideConfiguration.setTo(config);
}
}
/**
+ * Rebases a key's override config with display metrics of the {@code overrideDisplay} paired
+ * with the {code displayAdjustments}.
+ *
+ * @see #applyDisplayMetricsToConfiguration(DisplayMetrics, Configuration)
+ */
+ private void rebaseKeyForDisplay(ResourcesKey key, int overrideDisplay) {
+ final Configuration temp = new Configuration();
+
+ DisplayAdjustments daj = new DisplayAdjustments(key.mOverrideConfiguration);
+ daj.setCompatibilityInfo(key.mCompatInfo);
+
+ final DisplayMetrics dm = getDisplayMetrics(overrideDisplay, daj);
+ applyDisplayMetricsToConfiguration(dm, temp);
+
+ if (key.hasOverrideConfiguration()) {
+ temp.updateFrom(key.mOverrideConfiguration);
+ }
+ key.mOverrideConfiguration.setTo(temp);
+ }
+
+ /**
* Check WeakReferences and remove any dead references so they don't pile up.
*/
private static <T> void cleanupReferences(ArrayList<WeakReference<T>> references,
ReferenceQueue<T> referenceQueue) {
- Reference<? extends T> enduedRef = referenceQueue.poll();
- if (enduedRef == null) {
+ cleanupReferences(references, referenceQueue, Function.identity());
+ }
+
+ /**
+ * Check WeakReferences and remove any dead references so they don't pile up.
+ */
+ private static <C, T> void cleanupReferences(ArrayList<C> referenceContainers,
+ ReferenceQueue<T> referenceQueue, Function<C, WeakReference<T>> unwrappingFunction) {
+ Reference<? extends T> enqueuedRef = referenceQueue.poll();
+ if (enqueuedRef == null) {
return;
}
final HashSet<Reference<? extends T>> deadReferences = new HashSet<>();
- for (; enduedRef != null; enduedRef = referenceQueue.poll()) {
- deadReferences.add(enduedRef);
+ for (; enqueuedRef != null; enqueuedRef = referenceQueue.poll()) {
+ deadReferences.add(enqueuedRef);
}
- ArrayUtils.unstableRemoveIf(references,
- (ref) -> ref == null || deadReferences.contains(ref));
+ ArrayUtils.unstableRemoveIf(referenceContainers, (refContainer) -> {
+ WeakReference<T> ref = unwrappingFunction.apply(refContainer);
+ return ref == null || deadReferences.contains(ref);
+ });
}
/**
@@ -849,17 +976,36 @@
/**
* Creates a Resources object set with a ResourcesImpl object matching the given key.
*
- * @param activityToken The Activity this Resources object should be associated with.
* @param key The key describing the parameters of the ResourcesImpl object.
* @param classLoader The classloader to use for the Resources object.
* If null, {@link ClassLoader#getSystemClassLoader()} is used.
- * @param apkSupplier The apk assets supplier to use when creating a new ResourcesImpl object.
* @return A Resources object that gets updated when
* {@link #applyConfigurationToResourcesLocked(Configuration, CompatibilityInfo)}
* is called.
*/
- private @Nullable Resources createResources(@Nullable IBinder activityToken,
- @NonNull ResourcesKey key, @NonNull ClassLoader classLoader,
+ @Nullable
+ private Resources createResources(@NonNull ResourcesKey key, @NonNull ClassLoader classLoader,
+ @Nullable ApkAssetsSupplier apkSupplier) {
+ synchronized (this) {
+ if (DEBUG) {
+ Throwable here = new Throwable();
+ here.fillInStackTrace();
+ Slog.w(TAG, "!! Create resources for key=" + key, here);
+ }
+
+ ResourcesImpl resourcesImpl = findOrCreateResourcesImplForKeyLocked(key, apkSupplier);
+ if (resourcesImpl == null) {
+ return null;
+ }
+
+ return createResourcesLocked(classLoader, resourcesImpl, key.mCompatInfo);
+ }
+ }
+
+ @Nullable
+ private Resources createResourcesForActivity(@NonNull IBinder activityToken,
+ @NonNull ResourcesKey key, @NonNull Configuration initialOverrideConfig,
+ @Nullable Integer overrideDisplayId, @NonNull ClassLoader classLoader,
@Nullable ApkAssetsSupplier apkSupplier) {
synchronized (this) {
if (DEBUG) {
@@ -873,12 +1019,8 @@
return null;
}
- if (activityToken != null) {
- return createResourcesForActivityLocked(activityToken, classLoader,
- resourcesImpl, key.mCompatInfo);
- } else {
- return createResourcesLocked(classLoader, resourcesImpl, key.mCompatInfo);
- }
+ return createResourcesForActivityLocked(activityToken, initialOverrideConfig,
+ overrideDisplayId, classLoader, resourcesImpl, key.mCompatInfo);
}
}
@@ -899,7 +1041,10 @@
* @param splitResDirs An array of split resource paths. Can be null.
* @param overlayDirs An array of overlay paths. Can be null.
* @param libDirs An array of resource library paths. Can be null.
- * @param displayId The ID of the display for which to create the resources.
+ * @param overrideDisplayId The ID of the display for which the returned Resources should be
+ * based. This will cause display-based configuration properties to override those of the base
+ * Resources for the {@code activityToken}, or the global configuration if {@code activityToken}
+ * is null.
* @param overrideConfig The configuration to apply on top of the base configuration. Can be
* null. Mostly used with Activities that are in multi-window which may override width and
* height properties from the base config.
@@ -909,13 +1054,14 @@
* {@link ClassLoader#getSystemClassLoader()} is used.
* @return a Resources object from which to access resources.
*/
- public @Nullable Resources getResources(
+ @Nullable
+ public Resources getResources(
@Nullable IBinder activityToken,
@Nullable String resDir,
@Nullable String[] splitResDirs,
@Nullable String[] overlayDirs,
@Nullable String[] libDirs,
- int displayId,
+ @Nullable Integer overrideDisplayId,
@Nullable Configuration overrideConfig,
@NonNull CompatibilityInfo compatInfo,
@Nullable ClassLoader classLoader,
@@ -927,20 +1073,30 @@
splitResDirs,
overlayDirs,
libDirs,
- displayId,
- overrideConfig != null ? new Configuration(overrideConfig) : null, // Copy
+ overrideDisplayId != null ? overrideDisplayId : INVALID_DISPLAY,
+ overrideConfig,
compatInfo,
loaders == null ? null : loaders.toArray(new ResourcesLoader[0]));
classLoader = classLoader != null ? classLoader : ClassLoader.getSystemClassLoader();
- if (activityToken != null) {
- rebaseKeyForActivity(activityToken, key);
- }
-
// Preload the ApkAssets required by the key to prevent performing heavy I/O while the
// ResourcesManager lock is held.
final ApkAssetsSupplier assetsSupplier = createApkAssetsSupplierNotLocked(key);
- return createResources(activityToken, key, classLoader, assetsSupplier);
+
+ if (overrideDisplayId != null) {
+ rebaseKeyForDisplay(key, overrideDisplayId);
+ }
+
+ Resources resources;
+ if (activityToken != null) {
+ Configuration initialOverrideConfig = new Configuration(key.mOverrideConfiguration);
+ rebaseKeyForActivity(activityToken, key, overrideDisplayId != null);
+ resources = createResourcesForActivity(activityToken, key, initialOverrideConfig,
+ overrideDisplayId, classLoader, assetsSupplier);
+ } else {
+ resources = createResources(key, classLoader, assetsSupplier);
+ }
+ return resources;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
}
@@ -949,24 +1105,26 @@
/**
* Updates an Activity's Resources object with overrideConfig. The Resources object
* that was previously returned by {@link #getResources(IBinder, String, String[], String[],
- * String[], int, Configuration, CompatibilityInfo, ClassLoader, List)} is still valid and will
- * have the updated configuration.
+ * String[], Integer, Configuration, CompatibilityInfo, ClassLoader, List)} is still valid and
+ * will have the updated configuration.
*
* @param activityToken The Activity token.
* @param overrideConfig The configuration override to update.
* @param displayId Id of the display where activity currently resides.
- * @param movedToDifferentDisplay Indicates if the activity was moved to different display.
*/
public void updateResourcesForActivity(@NonNull IBinder activityToken,
- @Nullable Configuration overrideConfig, int displayId,
- boolean movedToDifferentDisplay) {
+ @Nullable Configuration overrideConfig, int displayId) {
try {
Trace.traceBegin(Trace.TRACE_TAG_RESOURCES,
"ResourcesManager#updateResourcesForActivity");
+ if (displayId == INVALID_DISPLAY) {
+ throw new IllegalArgumentException("displayId can not be INVALID_DISPLAY");
+ }
synchronized (this) {
final ActivityResources activityResources =
getOrCreateActivityResourcesStructLocked(activityToken);
+ boolean movedToDifferentDisplay = activityResources.overrideDisplayId != displayId;
if (Objects.equals(activityResources.overrideConfig, overrideConfig)
&& !movedToDifferentDisplay) {
// They are the same and no change of display id, no work to do.
@@ -983,6 +1141,8 @@
} else {
activityResources.overrideConfig.unset();
}
+ // Update the Activity's override display id.
+ activityResources.overrideDisplayId = displayId;
if (DEBUG) {
Throwable here = new Throwable();
@@ -1000,24 +1160,26 @@
// Rebase each Resources associated with this Activity.
final int refCount = activityResources.activityResources.size();
for (int i = 0; i < refCount; i++) {
- final WeakReference<Resources> weakResRef =
+ final ActivityResource activityResource =
activityResources.activityResources.get(i);
- final Resources resources = weakResRef.get();
+ final Resources resources = activityResource.resources.get();
if (resources == null) {
continue;
}
- final ResourcesKey newKey = rebaseActivityOverrideConfig(resources, oldConfig,
+ final ResourcesKey newKey = rebaseActivityOverrideConfig(activityResource,
overrideConfig, displayId);
- if (newKey != null) {
- final ResourcesImpl resourcesImpl =
- findOrCreateResourcesImplForKeyLocked(newKey);
- if (resourcesImpl != null && resourcesImpl != resources.getImpl()) {
- // Set the ResourcesImpl, updating it for all users of this Resources
- // object.
- resources.setImpl(resourcesImpl);
- }
+ if (newKey == null) {
+ continue;
+ }
+
+ final ResourcesImpl resourcesImpl =
+ findOrCreateResourcesImplForKeyLocked(newKey);
+ if (resourcesImpl != null && resourcesImpl != resources.getImpl()) {
+ // Set the ResourcesImpl, updating it for all users of this Resources
+ // object.
+ resources.setImpl(resourcesImpl);
}
}
}
@@ -1031,9 +1193,13 @@
* that an Activity's Resources should be set to.
*/
@Nullable
- private ResourcesKey rebaseActivityOverrideConfig(@NonNull Resources resources,
- @NonNull Configuration oldOverrideConfig, @Nullable Configuration newOverrideConfig,
- int displayId) {
+ private ResourcesKey rebaseActivityOverrideConfig(@NonNull ActivityResource activityResource,
+ @Nullable Configuration newOverrideConfig, int displayId) {
+ final Resources resources = activityResource.resources.get();
+ if (resources == null) {
+ return null;
+ }
+
// Extract the ResourcesKey that was last used to create the Resources for this
// activity.
final ResourcesKey oldKey = findKeyForResourceImplLocked(resources.getImpl());
@@ -1049,16 +1215,33 @@
rebasedOverrideConfig.setTo(newOverrideConfig);
}
- final boolean hadOverrideConfig = !oldOverrideConfig.equals(Configuration.EMPTY);
- if (hadOverrideConfig && oldKey.hasOverrideConfiguration()) {
- // Generate a delta between the old base Activity override configuration and
- // the actual final override configuration that was used to figure out the
- // real delta this Resources object wanted.
- Configuration overrideOverrideConfig = Configuration.generateDelta(
- oldOverrideConfig, oldKey.mOverrideConfiguration);
- rebasedOverrideConfig.updateFrom(overrideOverrideConfig);
+ final Integer overrideDisplayId = activityResource.overrideDisplayId;
+ if (overrideDisplayId != null) {
+ DisplayAdjustments displayAdjustments = new DisplayAdjustments(rebasedOverrideConfig);
+ displayAdjustments.getConfiguration().setTo(activityResource.overrideConfig);
+ displayAdjustments.setCompatibilityInfo(oldKey.mCompatInfo);
+
+ DisplayMetrics dm = getDisplayMetrics(overrideDisplayId, displayAdjustments);
+ applyDisplayMetricsToConfiguration(dm, rebasedOverrideConfig);
}
+ final boolean hasOverrideConfig =
+ !activityResource.overrideConfig.equals(Configuration.EMPTY);
+ if (hasOverrideConfig) {
+ rebasedOverrideConfig.updateFrom(activityResource.overrideConfig);
+ }
+
+ if (activityResource.overrideDisplayId != null
+ && activityResource.overrideConfig.windowConfiguration.getAppBounds() == null) {
+ // If this activity resource is overriding the display from the token and the key's
+ // window config app bounds is null we need to explicitly override this to
+ // ensure the display adjustments are as expected.
+ rebasedOverrideConfig.windowConfiguration.setAppBounds(null);
+ }
+
+ // Ensure the new key keeps the expected override display instead of the new token display.
+ displayId = overrideDisplayId != null ? overrideDisplayId : displayId;
+
// Create the new ResourcesKey with the rebased override config.
final ResourcesKey newKey = new ResourcesKey(oldKey.mResDir,
oldKey.mSplitResDirs, oldKey.mOverlayDirs, oldKey.mLibDirs,
@@ -1090,12 +1273,11 @@
+ mResConfiguration.seq + ", newSeq=" + config.seq);
return false;
}
- int changes = mResConfiguration.updateFrom(config);
+
// Things might have changed in display manager, so clear the cached displays.
mAdjustedDisplays.clear();
- DisplayMetrics defaultDisplayMetrics = getDisplayMetrics();
-
+ int changes = mResConfiguration.updateFrom(config);
if (compat != null && (mResCompatibilityInfo == null ||
!mResCompatibilityInfo.equals(compat))) {
mResCompatibilityInfo = compat;
@@ -1104,10 +1286,10 @@
| ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
}
- Resources.updateSystemConfiguration(config, defaultDisplayMetrics, compat);
+ DisplayMetrics displayMetrics = getDisplayMetrics();
+ Resources.updateSystemConfiguration(config, displayMetrics, compat);
ApplicationPackageManager.configurationChanged();
- //Slog.i(TAG, "Configuration changed in " + currentPackageName());
Configuration tmpConfig = new Configuration();
@@ -1137,11 +1319,7 @@
}
tmpConfig.setTo(config);
-
- // Apply the override configuration before setting the display adjustments to ensure that
- // the process config does not override activity display adjustments.
- final boolean hasOverrideConfiguration = key.hasOverrideConfiguration();
- if (hasOverrideConfiguration) {
+ if (key.hasOverrideConfiguration()) {
tmpConfig.updateFrom(key.mOverrideConfiguration);
}
@@ -1153,22 +1331,8 @@
daj = new DisplayAdjustments(daj);
daj.setCompatibilityInfo(compat);
}
-
- final int displayId = key.mDisplayId;
- if (displayId == Display.DEFAULT_DISPLAY) {
- daj.setConfiguration(tmpConfig);
- }
- DisplayMetrics dm = getDisplayMetrics(displayId, daj);
- if (displayId != Display.DEFAULT_DISPLAY) {
- applyNonDefaultDisplayMetricsToConfiguration(dm, tmpConfig);
-
- // Re-apply the override configuration to ensure that configuration contexts based on
- // a display context (ex: createDisplayContext().createConfigurationContext()) have the
- // correct override.
- if (hasOverrideConfiguration) {
- tmpConfig.updateFrom(key.mOverrideConfiguration);
- }
- }
+ daj.setConfiguration(tmpConfig);
+ DisplayMetrics dm = getDisplayMetrics(generateDisplayId(key), daj);
resourcesImpl.updateConfiguration(tmpConfig, dm, compat);
}
@@ -1305,8 +1469,10 @@
for (ActivityResources activityResources : mActivityResourceReferences.values()) {
final int resCount = activityResources.activityResources.size();
for (int i = 0; i < resCount; i++) {
- final WeakReference<Resources> ref = activityResources.activityResources.get(i);
- final Resources r = ref != null ? ref.get() : null;
+ final ActivityResource activityResource =
+ activityResources.activityResources.get(i);
+ final Resources r = activityResource != null
+ ? activityResource.resources.get() : null;
if (r != null) {
final ResourcesKey key = updatedResourceKeys.get(r.getImpl());
if (key != null) {
@@ -1338,10 +1504,16 @@
if (tokenResources == null) {
return false;
}
- final ArrayList<WeakReference<Resources>> resourcesRefs =
- tokenResources.activityResources;
+ final ArrayList<ActivityResource> resourcesRefs = tokenResources.activityResources;
for (int i = resourcesRefs.size() - 1; i >= 0; i--) {
- final Resources res = resourcesRefs.get(i).get();
+ final ActivityResource activityResource = resourcesRefs.get(i);
+ if (activityResource.overrideDisplayId != null) {
+ // This resource overrides the display of the token so we should not be
+ // modifying its display adjustments here.
+ continue;
+ }
+
+ final Resources res = activityResource.resources.get();
if (res != null) {
res.overrideDisplayAdjustments(override);
handled = true;
diff --git a/core/java/android/app/WindowTokenClient.java b/core/java/android/app/WindowTokenClient.java
index b5d1039..9092ef36 100644
--- a/core/java/android/app/WindowTokenClient.java
+++ b/core/java/android/app/WindowTokenClient.java
@@ -71,8 +71,7 @@
final boolean configChanged = config.diff(newConfig) != 0;
if (displayChanged || configChanged) {
// TODO(ag/9789103): update resource manager logic to track non-activity tokens
- mResourcesManager.updateResourcesForActivity(this, newConfig, newDisplayId,
- displayChanged);
+ mResourcesManager.updateResourcesForActivity(this, newConfig, newDisplayId);
}
if (displayChanged) {
context.updateDisplay(newDisplayId);
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 2006048..0f1f276 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -88,7 +88,6 @@
import android.util.SparseArray;
import android.util.TypedValue;
import android.util.apk.ApkSignatureVerifier;
-import android.view.Display;
import android.view.Gravity;
import com.android.internal.R;
@@ -8536,7 +8535,7 @@
null,
androidAppInfo.resourceDirs,
androidAppInfo.sharedLibraryFiles,
- Display.DEFAULT_DISPLAY,
+ null,
null,
systemResources.getCompatibilityInfo(),
systemResources.getClassLoader(),
diff --git a/core/java/android/content/res/ResourcesKey.java b/core/java/android/content/res/ResourcesKey.java
index 9da0f20..fcb80aa 100644
--- a/core/java/android/content/res/ResourcesKey.java
+++ b/core/java/android/content/res/ResourcesKey.java
@@ -16,6 +16,8 @@
package android.content.res;
+import static android.os.Build.VERSION_CODES.O;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
@@ -41,8 +43,17 @@
@Nullable
public final String[] mLibDirs;
- public final int mDisplayId;
+ /**
+ * The display ID that overrides the global resources display to produce the Resources display.
+ * If set to something other than {@link android.view.Display#INVALID_DISPLAY} this will
+ * override the global resources display for this key.
+ */
+ @UnsupportedAppUsage(maxTargetSdk = O)
+ public int mDisplayId;
+ /**
+ * The configuration applied to the global configuration to produce the Resources configuration.
+ */
@NonNull
public final Configuration mOverrideConfiguration;
@@ -58,7 +69,7 @@
@Nullable String[] splitResDirs,
@Nullable String[] overlayDirs,
@Nullable String[] libDirs,
- int displayId,
+ int overrideDisplayId,
@Nullable Configuration overrideConfig,
@Nullable CompatibilityInfo compatInfo,
@Nullable ResourcesLoader[] loader) {
@@ -67,7 +78,7 @@
mOverlayDirs = overlayDirs;
mLibDirs = libDirs;
mLoaders = (loader != null && loader.length == 0) ? null : loader;
- mDisplayId = displayId;
+ mDisplayId = overrideDisplayId;
mOverrideConfiguration = new Configuration(overrideConfig != null
? overrideConfig : Configuration.EMPTY);
mCompatInfo = compatInfo != null ? compatInfo : CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
@@ -77,7 +88,7 @@
hash = 31 * hash + Arrays.hashCode(mSplitResDirs);
hash = 31 * hash + Arrays.hashCode(mOverlayDirs);
hash = 31 * hash + Arrays.hashCode(mLibDirs);
- hash = 31 * hash + mDisplayId;
+ hash = 31 * hash + Objects.hashCode(mDisplayId);
hash = 31 * hash + Objects.hashCode(mOverrideConfiguration);
hash = 31 * hash + Objects.hashCode(mCompatInfo);
hash = 31 * hash + Arrays.hashCode(mLoaders);
diff --git a/core/java/android/os/incremental/IIncrementalService.aidl b/core/java/android/os/incremental/IIncrementalService.aidl
index 61e6a05..be8b929 100644
--- a/core/java/android/os/incremental/IIncrementalService.aidl
+++ b/core/java/android/os/incremental/IIncrementalService.aidl
@@ -90,9 +90,10 @@
int unlink(int storageId, in @utf8InCpp String path);
/**
- * Checks if a file's certain range is loaded. File is specified by its path.
+ * Returns overall loading progress of all the files on a storage, progress value between [0,1].
+ * Returns a negative value on error.
*/
- boolean isFileRangeLoaded(int storageId, in @utf8InCpp String path, long start, long end);
+ float getLoadingProgress(int storageId);
/**
* Reads the metadata of a file. File is specified by either its path or 16 byte id.
diff --git a/core/java/android/os/incremental/IncrementalStorage.java b/core/java/android/os/incremental/IncrementalStorage.java
index ca6114f..b8dbfbb 100644
--- a/core/java/android/os/incremental/IncrementalStorage.java
+++ b/core/java/android/os/incremental/IncrementalStorage.java
@@ -304,29 +304,21 @@
}
/**
- * Checks whether a file under the current storage directory is fully loaded.
+ * Returns the loading progress of a storage
*
- * @param path The relative path of the file.
- * @return True if the file is fully loaded.
+ * @return progress value between [0, 1].
*/
- public boolean isFileFullyLoaded(@NonNull String path) {
- return isFileRangeLoaded(path, 0, -1);
- }
-
- /**
- * Checks whether a range in a file if loaded.
- *
- * @param path The relative path of the file.
- * @param start The starting offset of the range.
- * @param end The ending offset of the range.
- * @return True if the file is fully loaded.
- */
- public boolean isFileRangeLoaded(@NonNull String path, long start, long end) {
+ public float getLoadingProgress() throws IOException {
try {
- return mService.isFileRangeLoaded(mId, path, start, end);
+ final float res = mService.getLoadingProgress(mId);
+ if (res < 0) {
+ throw new IOException(
+ "getLoadingProgress() failed at querying loading progress, errno " + -res);
+ }
+ return res;
} catch (RemoteException e) {
e.rethrowFromSystemServer();
- return false;
+ return 0;
}
}
diff --git a/core/java/android/preference/DialogPreference.java b/core/java/android/preference/DialogPreference.java
index dfdb57c4..fb7b232 100644
--- a/core/java/android/preference/DialogPreference.java
+++ b/core/java/android/preference/DialogPreference.java
@@ -36,8 +36,6 @@
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
-import android.view.Window;
-import android.view.WindowManager;
import android.widget.TextView;
/**
@@ -337,9 +335,6 @@
if (state != null) {
dialog.onRestoreInstanceState(state);
}
- if (needInputMethod()) {
- requestInputMethod(dialog);
- }
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
@@ -380,24 +375,6 @@
}
/**
- * Returns whether the preference needs to display a soft input method when the dialog
- * is displayed. Default is false. Subclasses should override this method if they need
- * the soft input method brought up automatically.
- * @hide
- */
- protected boolean needInputMethod() {
- return false;
- }
-
- /**
- * Sets the required flags on the dialog window to enable input method window to show up.
- */
- private void requestInputMethod(Dialog dialog) {
- Window window = dialog.getWindow();
- window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
- }
-
- /**
* Creates the content view for the dialog (if a custom content view is
* required). By default, it inflates the dialog layout resource if it is
* set.
diff --git a/core/java/android/preference/EditTextPreference.java b/core/java/android/preference/EditTextPreference.java
index af6f184..75c5102 100644
--- a/core/java/android/preference/EditTextPreference.java
+++ b/core/java/android/preference/EditTextPreference.java
@@ -21,6 +21,7 @@
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.TypedArray;
+import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
@@ -28,6 +29,7 @@
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
+import android.view.WindowInsets;
import android.widget.EditText;
/**
@@ -123,7 +125,7 @@
EditText editText = mEditText;
editText.setText(getText());
-
+
ViewParent oldParent = editText.getParent();
if (oldParent != view) {
if (oldParent != null) {
@@ -133,6 +135,13 @@
}
}
+ @Override
+ protected void showDialog(Bundle state) {
+ super.showDialog(state);
+ mEditText.requestFocus();
+ mEditText.getWindowInsetsController().show(WindowInsets.Type.ime());
+ }
+
/**
* Adds the EditText widget of this preference to the dialog's view.
*
@@ -183,13 +192,6 @@
return mEditText;
}
- /** @hide */
- @Override
- protected boolean needInputMethod() {
- // We want the input method to show, if possible, when dialog is displayed
- return true;
- }
-
@Override
protected Parcelable onSaveInstanceState() {
final Parcelable superState = super.onSaveInstanceState();
diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java
index 3fcb361..3ed7f6c 100644
--- a/core/java/android/speech/tts/TextToSpeech.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -62,17 +62,17 @@
* to release the native resources used by the TextToSpeech engine.
*
* Apps targeting Android 11 that use text-to-speech should declare {@link
- * TextToSpeech.Engine#INTENT_ACTION_TTS_SERVICE} in the <code><queries></code> elements of their
+ * TextToSpeech.Engine#INTENT_ACTION_TTS_SERVICE} in the {@code queries} elements of their
* manifest:
*
- * <code>
- * <queries>
+ * <pre>
+ * <queries>
* ...
- * <intent>
- * <action android:name="android.intent.action.TTS_SERVICE" />
- * </intent>
- * </queries>
- * </code>
+ * <intent>
+ * <action android:name="android.intent.action.TTS_SERVICE" />
+ * </intent>
+ * </queries>
+ * </pre>
*/
public class TextToSpeech {
@@ -254,18 +254,17 @@
* </ul>
*
* Apps targeting Android 11 that use text-to-speech should declare {@link
- * #INTENT_ACTION_TTS_SERVICE} in the <code><queries></code> elements of their
+ * TextToSpeech.Engine#INTENT_ACTION_TTS_SERVICE} in the {@code queries} elements of their
* manifest:
*
- * <code>
- * <queries>
+ * <pre>
+ * <queries>
* ...
- * <intent>
- * <action android:name="android.intent.action.TTS_SERVICE" />
- * </intent>
- * </queries>
- * </code>
-
+ * <intent>
+ * <action android:name="android.intent.action.TTS_SERVICE" />
+ * </intent>
+ * </queries>
+ * </pre>
*/
public class Engine {
diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java
index a6e6d05..b807180 100644
--- a/core/java/android/telephony/PhoneStateListener.java
+++ b/core/java/android/telephony/PhoneStateListener.java
@@ -938,7 +938,6 @@
* {@link SubscriptionManager#getDefaultSubscriptionId})
* and the value as the list of {@link EmergencyNumber};
* null if this information is not available.
- * @hide
*/
public void onEmergencyNumberListChanged(
@NonNull Map<Integer, List<EmergencyNumber>> emergencyNumberList) {
@@ -948,17 +947,50 @@
/**
* Callback invoked when an outgoing call is placed to an emergency number.
*
- * @param placedEmergencyNumber the emergency number {@link EmergencyNumber} the call is placed
- * to.
+ * This method will be called when an emergency call is placed on any subscription (including
+ * the no-SIM case), regardless of which subscription this listener was registered on.
+ *
+ * This method is deprecated. Both this method and the new
+ * {@link #onOutgoingEmergencyCall(EmergencyNumber, int)} will be called when an outgoing
+ * emergency call is placed.
+ *
+ * @param placedEmergencyNumber The {@link EmergencyNumber} the emergency call was placed to.
+ *
+ * @deprecated Use {@link #onOutgoingEmergencyCall(EmergencyNumber, int)}.
* @hide
*/
@SystemApi
@TestApi
+ @Deprecated
public void onOutgoingEmergencyCall(@NonNull EmergencyNumber placedEmergencyNumber) {
// default implementation empty
}
/**
+ * Callback invoked when an outgoing call is placed to an emergency number.
+ *
+ * This method will be called when an emergency call is placed on any subscription (including
+ * the no-SIM case), regardless of which subscription this listener was registered on.
+ *
+ * Both this method and the deprecated {@link #onOutgoingEmergencyCall(EmergencyNumber)} will be
+ * called when an outgoing emergency call is placed. You should only implement one of these
+ * methods.
+ *
+ * @param placedEmergencyNumber The {@link EmergencyNumber} the emergency call was placed to.
+ * @param subscriptionId The subscription ID used to place the emergency call. If the
+ * emergency call was placed without a valid subscription (e.g. when there
+ * are no SIM cards in the device), this will be equal to
+ * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}.
+ *
+ * @hide
+ */
+ @SystemApi
+ @TestApi
+ public void onOutgoingEmergencyCall(@NonNull EmergencyNumber placedEmergencyNumber,
+ int subscriptionId) {
+ }
+
+ /**
* Callback invoked when an outgoing SMS is placed to an emergency number.
*
* @param sentEmergencyNumber the emergency number {@link EmergencyNumber} the SMS is sent to.
@@ -1336,13 +1368,19 @@
() -> psl.onEmergencyNumberListChanged(emergencyNumberList)));
}
- public void onOutgoingEmergencyCall(@NonNull EmergencyNumber placedEmergencyNumber) {
+ public void onOutgoingEmergencyCall(@NonNull EmergencyNumber placedEmergencyNumber,
+ int subscriptionId) {
PhoneStateListener psl = mPhoneStateListenerWeakRef.get();
if (psl == null) return;
Binder.withCleanCallingIdentity(
() -> mExecutor.execute(
() -> psl.onOutgoingEmergencyCall(placedEmergencyNumber)));
+
+ Binder.withCleanCallingIdentity(
+ () -> mExecutor.execute(
+ () -> psl.onOutgoingEmergencyCall(placedEmergencyNumber,
+ subscriptionId)));
}
public void onOutgoingEmergencySms(@NonNull EmergencyNumber sentEmergencyNumber) {
diff --git a/core/java/android/view/InputEventReceiver.java b/core/java/android/view/InputEventReceiver.java
index 25a4108..a06a0c6 100644
--- a/core/java/android/view/InputEventReceiver.java
+++ b/core/java/android/view/InputEventReceiver.java
@@ -25,6 +25,7 @@
import dalvik.system.CloseGuard;
+import java.io.PrintWriter;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
@@ -53,6 +54,7 @@
private static native void nativeFinishInputEvent(long receiverPtr, int seq, boolean handled);
private static native boolean nativeConsumeBatchedInputEvents(long receiverPtr,
long frameTimeNanos);
+ private static native String nativeDump(long receiverPtr, String prefix);
/**
* Creates an input event receiver bound to the specified input channel.
@@ -221,6 +223,18 @@
}
/**
+ * Dump the state of this InputEventReceiver to the writer.
+ * @param prefix the prefix (typically whitespace padding) to append in front of each line
+ * @param writer the writer where the dump should be written
+ */
+ public void dump(String prefix, PrintWriter writer) {
+ writer.println(prefix + getClass().getName());
+ writer.println(prefix + " mInputChannel: " + mInputChannel);
+ writer.println(prefix + " mSeqMap: " + mSeqMap);
+ writer.println(prefix + " mReceiverPtr:\n" + nativeDump(mReceiverPtr, prefix + " "));
+ }
+
+ /**
* Factory for InputEventReceiver
*/
public interface Factory {
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 5d20381..6e17ac9 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -7532,36 +7532,36 @@
public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
String innerPrefix = prefix + " ";
- writer.print(prefix); writer.println("ViewRoot:");
- writer.print(innerPrefix); writer.print("mAdded="); writer.print(mAdded);
- writer.print(" mRemoved="); writer.println(mRemoved);
- writer.print(innerPrefix); writer.print("mConsumeBatchedInputScheduled=");
- writer.println(mConsumeBatchedInputScheduled);
- writer.print(innerPrefix); writer.print("mConsumeBatchedInputImmediatelyScheduled=");
- writer.println(mConsumeBatchedInputImmediatelyScheduled);
- writer.print(innerPrefix); writer.print("mPendingInputEventCount=");
- writer.println(mPendingInputEventCount);
- writer.print(innerPrefix); writer.print("mProcessInputEventsScheduled=");
- writer.println(mProcessInputEventsScheduled);
- writer.print(innerPrefix); writer.print("mTraversalScheduled=");
- writer.print(mTraversalScheduled);
- writer.print(innerPrefix); writer.print("mIsAmbientMode=");
- writer.print(mIsAmbientMode);
- writer.print(innerPrefix); writer.print("mUnbufferedInputSource=");
- writer.print(Integer.toHexString(mUnbufferedInputSource));
-
+ writer.println(prefix + "ViewRoot:");
+ writer.println(innerPrefix + "mAdded=" + mAdded);
+ writer.println(innerPrefix + "mRemoved=" + mRemoved);
+ writer.println(innerPrefix + "mStopped=" + mStopped);
+ writer.println(innerPrefix + "mConsumeBatchedInputScheduled="
+ + mConsumeBatchedInputScheduled);
+ writer.println(innerPrefix + "mConsumeBatchedInputImmediatelyScheduled="
+ + mConsumeBatchedInputImmediatelyScheduled);
+ writer.println(innerPrefix + "mPendingInputEventCount=" + mPendingInputEventCount);
+ writer.println(innerPrefix + "mProcessInputEventsScheduled="
+ + mProcessInputEventsScheduled);
+ writer.println(innerPrefix + "mTraversalScheduled=" + mTraversalScheduled);
if (mTraversalScheduled) {
- writer.print(" (barrier="); writer.print(mTraversalBarrier); writer.println(")");
- } else {
- writer.println();
+ writer.println(innerPrefix + " (barrier=" + mTraversalBarrier + ")");
}
+ writer.println(innerPrefix + "mIsAmbientMode=" + mIsAmbientMode);
+ writer.println(innerPrefix + "mUnbufferedInputSource="
+ + Integer.toHexString(mUnbufferedInputSource));
+
mFirstInputStage.dump(innerPrefix, writer);
+ if (mInputEventReceiver != null) {
+ mInputEventReceiver.dump(innerPrefix, writer);
+ }
+
mChoreographer.dump(prefix, writer);
mInsetsController.dump(prefix, writer);
- writer.print(prefix); writer.println("View Hierarchy:");
+ writer.println(prefix + "View Hierarchy:");
dumpViewHierarchy(innerPrefix, writer, mView);
}
diff --git a/core/java/com/android/internal/os/TEST_MAPPING b/core/java/com/android/internal/os/TEST_MAPPING
index f44b9fb..9698f19 100644
--- a/core/java/com/android/internal/os/TEST_MAPPING
+++ b/core/java/com/android/internal/os/TEST_MAPPING
@@ -26,5 +26,20 @@
"KernelSingleUidTimeReader\\.java"
]
}
+ ],
+ "postsubmit": [
+ {
+ "name": "FrameworksCoreTests",
+ "options": [
+ {
+ "include-filter": "com.android.internal.os.BstatsCpuTimesValidationTest"
+ }
+ ],
+ "file_patterns": [
+ "BatteryStatsImpl\\.java",
+ "KernelCpuUidFreqTimeReader\\.java",
+ "KernelSingleUidTimeReader\\.java"
+ ]
+ }
]
}
diff --git a/core/java/com/android/internal/telephony/IPhoneStateListener.aidl b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl
index b2c5a99..d41d307 100644
--- a/core/java/com/android/internal/telephony/IPhoneStateListener.aidl
+++ b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl
@@ -61,7 +61,7 @@
void onRadioPowerStateChanged(in int state);
void onCallAttributesChanged(in CallAttributes callAttributes);
void onEmergencyNumberListChanged(in Map emergencyNumberList);
- void onOutgoingEmergencyCall(in EmergencyNumber placedEmergencyNumber);
+ void onOutgoingEmergencyCall(in EmergencyNumber placedEmergencyNumber, int subscriptionId);
void onOutgoingEmergencySms(in EmergencyNumber sentEmergencyNumber);
void onCallDisconnectCauseChanged(in int disconnectCause, in int preciseDisconnectCause);
void onImsCallDisconnectCauseChanged(in ImsReasonInfo imsReasonInfo);
diff --git a/core/java/com/android/internal/widget/LocalImageResolver.java b/core/java/com/android/internal/widget/LocalImageResolver.java
index 2302de2..b4e108f 100644
--- a/core/java/com/android/internal/widget/LocalImageResolver.java
+++ b/core/java/com/android/internal/widget/LocalImageResolver.java
@@ -23,6 +23,7 @@
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
+import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
@@ -31,6 +32,7 @@
* A class to extract Bitmaps from a MessagingStyle message.
*/
public class LocalImageResolver {
+ private static final String TAG = LocalImageResolver.class.getSimpleName();
private static final int MAX_SAFE_ICON_SIZE_PX = 480;
@@ -60,11 +62,18 @@
private static BitmapFactory.Options getBoundsOptionsForImage(Uri uri, Context context)
throws IOException {
- InputStream input = context.getContentResolver().openInputStream(uri);
BitmapFactory.Options onlyBoundsOptions = new BitmapFactory.Options();
- onlyBoundsOptions.inJustDecodeBounds = true;
- BitmapFactory.decodeStream(input, null, onlyBoundsOptions);
- input.close();
+ try (InputStream input = context.getContentResolver().openInputStream(uri)) {
+ if (input == null) {
+ throw new IllegalArgumentException();
+ }
+ onlyBoundsOptions.inJustDecodeBounds = true;
+ BitmapFactory.decodeStream(input, null, onlyBoundsOptions);
+ } catch (IllegalArgumentException iae) {
+ onlyBoundsOptions.outWidth = -1;
+ onlyBoundsOptions.outHeight = -1;
+ Log.e(TAG, "error loading image", iae);
+ }
return onlyBoundsOptions;
}
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 960c11f..08a9f48 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -680,7 +680,7 @@
*/
public boolean setLockCredential(@NonNull LockscreenCredential newCredential,
@NonNull LockscreenCredential savedCredential, int userHandle) {
- if (!hasSecureLockScreen()) {
+ if (!hasSecureLockScreen() && newCredential.getType() != CREDENTIAL_TYPE_NONE) {
throw new UnsupportedOperationException(
"This operation requires the lock screen feature.");
}
@@ -775,7 +775,7 @@
/** Update the encryption password if it is enabled **/
private void updateEncryptionPassword(final int type, final byte[] password) {
- if (!hasSecureLockScreen()) {
+ if (!hasSecureLockScreen() && password != null && password.length != 0) {
throw new UnsupportedOperationException(
"This operation requires the lock screen feature.");
}
@@ -1575,7 +1575,7 @@
*/
public boolean setLockCredentialWithToken(@NonNull LockscreenCredential credential,
long tokenHandle, byte[] token, int userHandle) {
- if (!hasSecureLockScreen()) {
+ if (!hasSecureLockScreen() && credential.getType() != CREDENTIAL_TYPE_NONE) {
throw new UnsupportedOperationException(
"This operation requires the lock screen feature.");
}
diff --git a/core/jni/android_view_InputEventReceiver.cpp b/core/jni/android_view_InputEventReceiver.cpp
index 979a69a..9ed71ac0 100644
--- a/core/jni/android_view_InputEventReceiver.cpp
+++ b/core/jni/android_view_InputEventReceiver.cpp
@@ -22,11 +22,12 @@
#include <nativehelper/JNIHelp.h>
+#include <android-base/stringprintf.h>
#include <android_runtime/AndroidRuntime.h>
+#include <input/InputTransport.h>
#include <log/log.h>
#include <utils/Looper.h>
-#include <utils/Vector.h>
-#include <input/InputTransport.h>
+#include <vector>
#include "android_os_MessageQueue.h"
#include "android_view_InputChannel.h"
#include "android_view_KeyEvent.h"
@@ -52,6 +53,21 @@
jmethodID onBatchedInputEventPending;
} gInputEventReceiverClassInfo;
+// Add prefix to the beginning of each line in 'str'
+static std::string addPrefix(std::string str, std::string_view prefix) {
+ str.insert(0, prefix); // insert at the beginning of the first line
+ const size_t prefixLength = prefix.length();
+ size_t pos = prefixLength; // just inserted prefix. start at the end of it
+ while (true) { // process all newline characters in 'str'
+ pos = str.find('\n', pos);
+ if (pos == std::string::npos) {
+ break;
+ }
+ str.insert(pos + 1, prefix); // insert prefix just after the '\n' character
+ pos += prefixLength + 1; // advance the position past the newly inserted prefix
+ }
+ return str;
+}
class NativeInputEventReceiver : public LooperCallback {
public:
@@ -64,6 +80,7 @@
status_t finishInputEvent(uint32_t seq, bool handled);
status_t consumeEvents(JNIEnv* env, bool consumeBatches, nsecs_t frameTime,
bool* outConsumedBatch);
+ std::string dump(const char* prefix);
protected:
virtual ~NativeInputEventReceiver();
@@ -80,7 +97,7 @@
PreallocatedInputEventFactory mInputEventFactory;
bool mBatchedInputEventPending;
int mFdEvents;
- Vector<Finish> mFinishQueue;
+ std::vector<Finish> mFinishQueue;
void setFdEvents(int events);
@@ -128,7 +145,7 @@
}
status_t status = mInputConsumer.sendFinishedSignal(seq, handled);
- if (status) {
+ if (status != OK) {
if (status == WOULD_BLOCK) {
if (kDebugDispatchCycle) {
ALOGD("channel '%s' ~ Could not send finished signal immediately. "
@@ -137,7 +154,7 @@
Finish finish;
finish.seq = seq;
finish.handled = handled;
- mFinishQueue.add(finish);
+ mFinishQueue.push_back(finish);
if (mFinishQueue.size() == 1) {
setFdEvents(ALOOPER_EVENT_INPUT | ALOOPER_EVENT_OUTPUT);
}
@@ -162,6 +179,9 @@
}
int NativeInputEventReceiver::handleEvent(int receiveFd, int events, void* data) {
+ // Allowed return values of this function as documented in LooperCallback::handleEvent
+ constexpr int REMOVE_CALLBACK = 0;
+ constexpr int KEEP_CALLBACK = 1;
if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) {
// This error typically occurs when the publisher has closed the input channel
// as part of removing a window or finishing an IME session, in which case
@@ -170,41 +190,42 @@
ALOGD("channel '%s' ~ Publisher closed input channel or an error occurred. "
"events=0x%x", getInputChannelName().c_str(), events);
}
- return 0; // remove the callback
+ return REMOVE_CALLBACK;
}
if (events & ALOOPER_EVENT_INPUT) {
JNIEnv* env = AndroidRuntime::getJNIEnv();
status_t status = consumeEvents(env, false /*consumeBatches*/, -1, nullptr);
mMessageQueue->raiseAndClearException(env, "handleReceiveCallback");
- return status == OK || status == NO_MEMORY ? 1 : 0;
+ return status == OK || status == NO_MEMORY ? KEEP_CALLBACK : REMOVE_CALLBACK;
}
if (events & ALOOPER_EVENT_OUTPUT) {
for (size_t i = 0; i < mFinishQueue.size(); i++) {
- const Finish& finish = mFinishQueue.itemAt(i);
+ const Finish& finish = mFinishQueue[i];
status_t status = mInputConsumer.sendFinishedSignal(finish.seq, finish.handled);
- if (status) {
- mFinishQueue.removeItemsAt(0, i);
+ if (status != OK) {
+ mFinishQueue.erase(mFinishQueue.begin(), mFinishQueue.begin() + i);
if (status == WOULD_BLOCK) {
if (kDebugDispatchCycle) {
ALOGD("channel '%s' ~ Sent %zu queued finish events; %zu left.",
- getInputChannelName().c_str(), i, mFinishQueue.size());
+ getInputChannelName().c_str(), i, mFinishQueue.size());
}
- return 1; // keep the callback, try again later
+ return KEEP_CALLBACK; // try again later
}
ALOGW("Failed to send finished signal on channel '%s'. status=%d",
getInputChannelName().c_str(), status);
if (status != DEAD_OBJECT) {
JNIEnv* env = AndroidRuntime::getJNIEnv();
- String8 message;
- message.appendFormat("Failed to finish input event. status=%d", status);
- jniThrowRuntimeException(env, message.string());
+ std::string message =
+ android::base::StringPrintf("Failed to finish input event. status=%d",
+ status);
+ jniThrowRuntimeException(env, message.c_str());
mMessageQueue->raiseAndClearException(env, "finishInputEvent");
}
- return 0; // remove the callback
+ return REMOVE_CALLBACK;
}
}
if (kDebugDispatchCycle) {
@@ -213,12 +234,12 @@
}
mFinishQueue.clear();
setFdEvents(ALOOPER_EVENT_INPUT);
- return 1;
+ return KEEP_CALLBACK;
}
ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
"events=0x%x", getInputChannelName().c_str(), events);
- return 1;
+ return KEEP_CALLBACK;
}
status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env,
@@ -354,6 +375,23 @@
}
}
+std::string NativeInputEventReceiver::dump(const char* prefix) {
+ std::string out;
+ std::string consumerDump = addPrefix(mInputConsumer.dump(), " ");
+ out = out + "mInputConsumer:\n" + consumerDump + "\n";
+
+ out += android::base::StringPrintf("mBatchedInputEventPending: %s\n",
+ toString(mBatchedInputEventPending));
+ out = out + "mFinishQueue:\n";
+ for (const Finish& finish : mFinishQueue) {
+ out += android::base::StringPrintf(" seq=%" PRIu32 " handled=%s\n", finish.seq,
+ toString(finish.handled));
+ }
+ if (mFinishQueue.empty()) {
+ out = out + " <empty>\n";
+ }
+ return addPrefix(out, prefix);
+}
static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak,
jobject inputChannelObj, jobject messageQueueObj) {
@@ -374,9 +412,10 @@
receiverWeak, inputChannel, messageQueue);
status_t status = receiver->initialize();
if (status) {
- String8 message;
- message.appendFormat("Failed to initialize input event receiver. status=%d", status);
- jniThrowRuntimeException(env, message.string());
+ std::string message =
+ android::base::StringPrintf("Failed to initialize input event receiver. status=%d",
+ status);
+ jniThrowRuntimeException(env, message.c_str());
return 0;
}
@@ -397,9 +436,9 @@
reinterpret_cast<NativeInputEventReceiver*>(receiverPtr);
status_t status = receiver->finishInputEvent(seq, handled);
if (status && status != DEAD_OBJECT) {
- String8 message;
- message.appendFormat("Failed to finish input event. status=%d", status);
- jniThrowRuntimeException(env, message.string());
+ std::string message =
+ android::base::StringPrintf("Failed to finish input event. status=%d", status);
+ jniThrowRuntimeException(env, message.c_str());
}
}
@@ -411,26 +450,31 @@
status_t status = receiver->consumeEvents(env, true /*consumeBatches*/, frameTimeNanos,
&consumedBatch);
if (status && status != DEAD_OBJECT && !env->ExceptionCheck()) {
- String8 message;
- message.appendFormat("Failed to consume batched input event. status=%d", status);
- jniThrowRuntimeException(env, message.string());
+ std::string message =
+ android::base::StringPrintf("Failed to consume batched input event. status=%d",
+ status);
+ jniThrowRuntimeException(env, message.c_str());
return JNI_FALSE;
}
return consumedBatch ? JNI_TRUE : JNI_FALSE;
}
+static jstring nativeDump(JNIEnv* env, jclass clazz, jlong receiverPtr, jstring prefix) {
+ sp<NativeInputEventReceiver> receiver =
+ reinterpret_cast<NativeInputEventReceiver*>(receiverPtr);
+ ScopedUtfChars prefixChars(env, prefix);
+ return env->NewStringUTF(receiver->dump(prefixChars.c_str()).c_str());
+}
static const JNINativeMethod gMethods[] = {
- /* name, signature, funcPtr */
- { "nativeInit",
- "(Ljava/lang/ref/WeakReference;Landroid/view/InputChannel;Landroid/os/MessageQueue;)J",
- (void*)nativeInit },
- { "nativeDispose", "(J)V",
- (void*)nativeDispose },
- { "nativeFinishInputEvent", "(JIZ)V",
- (void*)nativeFinishInputEvent },
- { "nativeConsumeBatchedInputEvents", "(JJ)Z",
- (void*)nativeConsumeBatchedInputEvents },
+ /* name, signature, funcPtr */
+ {"nativeInit",
+ "(Ljava/lang/ref/WeakReference;Landroid/view/InputChannel;Landroid/os/MessageQueue;)J",
+ (void*)nativeInit},
+ {"nativeDispose", "(J)V", (void*)nativeDispose},
+ {"nativeFinishInputEvent", "(JIZ)V", (void*)nativeFinishInputEvent},
+ {"nativeConsumeBatchedInputEvents", "(JJ)Z", (void*)nativeConsumeBatchedInputEvents},
+ {"nativeDump", "(JLjava/lang/String;)Ljava/lang/String;", (void*)nativeDump},
};
int register_android_view_InputEventReceiver(JNIEnv* env) {
diff --git a/core/proto/android/app/settings_enums.proto b/core/proto/android/app/settings_enums.proto
index 6eb8904..4aa5df2 100644
--- a/core/proto/android/app/settings_enums.proto
+++ b/core/proto/android/app/settings_enums.proto
@@ -2738,4 +2738,9 @@
// CATEGORY: SETTINGS
// OS: S
SETTINGS_COLUMBUS = 1848;
+
+ // OPEN: Settings > Accessibility > Magnification > Settings > Magnification area > Magnification switch shortcut dialog
+ // CATEGORY: SETTINGS
+ // OS: S
+ DIALOG_MAGNIFICATION_SWITCH_SHORTCUT = 1849;
}
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 26dac61..b6f6627 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -515,9 +515,9 @@
<string name="permdesc_changeWifiMulticastState" product="tv" msgid="1336952358450652595">"للسماح للتطبيق بتلقّي الحِزم التي يتم إرسالها إلى جميع الأجهزة على شبكة Wi-Fi باستخدام عناوين بث متعدد، وليس باستخدام جهاز Android TV فقط. ويؤدي ذلك إلى استخدام قدر أكبر من الطاقة يفوق ما يتم استهلاكه في وضع البث غير المتعدد."</string>
<string name="permdesc_changeWifiMulticastState" product="default" msgid="8296627590220222740">"للسماح للتطبيق بتلقي الحزم التي يتم إرسالها إلى جميع الأجهزة على شبكة Wi-Fi باستخدام عناوين بث متعدد، وليس باستخدام هاتفك فقط. ويؤدي ذلك إلى استخدام قدر أكبر من الطاقة يفوق وضع البث غير المتعدد."</string>
<string name="permlab_bluetoothAdmin" msgid="6490373569441946064">"الدخول إلى إعدادات بلوتوث"</string>
- <string name="permdesc_bluetoothAdmin" product="tablet" msgid="5370837055438574863">"للسماح للتطبيق بتهيئة لوحة البلوتوث المحلي، واكتشاف أجهزة التحكم عن بعد والاقتران بها."</string>
+ <string name="permdesc_bluetoothAdmin" product="tablet" msgid="5370837055438574863">"للسماح للتطبيق بإعداد لوحة البلوتوث المحلي، واكتشاف أجهزة التحكم عن بعد والاقتران بها."</string>
<string name="permdesc_bluetoothAdmin" product="tv" msgid="1623992984547014588">"للسماح للتطبيق بضبط البلوتوث على جهاز Android TV واكتشاف الأجهزة البعيدة والاقتران بها."</string>
- <string name="permdesc_bluetoothAdmin" product="default" msgid="7381341743021234863">"للسماح للتطبيق بتهيئة هاتف البلوتوث المحلي، واكتشاف أجهزة التحكم عن بعد والاقتران بها."</string>
+ <string name="permdesc_bluetoothAdmin" product="default" msgid="7381341743021234863">"للسماح للتطبيق بإعداد هاتف البلوتوث المحلي، واكتشاف أجهزة التحكم عن بعد والاقتران بها."</string>
<string name="permlab_accessWimaxState" msgid="7029563339012437434">"الاتصال بـشبكة WiMAX وقطع الاتصال بها"</string>
<string name="permdesc_accessWimaxState" msgid="5372734776802067708">"للسماح للتطبيق بتحديد ما إذا تم تفعيل WiMAX وتحديد معلومات حول أي شبكات WiMAX متصلة."</string>
<string name="permlab_changeWimaxState" msgid="6223305780806267462">"تغيير حالة WiMAX"</string>
@@ -1412,7 +1412,7 @@
<string name="select_input_method" msgid="3971267998568587025">"اختيار أسلوب الإدخال"</string>
<string name="show_ime" msgid="6406112007347443383">"استمرار عرضها على الشاشة أثناء نشاط لوحة المفاتيح الفعلية"</string>
<string name="hardware" msgid="1800597768237606953">"إظهار لوحة المفاتيح الافتراضية"</string>
- <string name="select_keyboard_layout_notification_title" msgid="4427643867639774118">"تهيئة لوحة المفاتيح الفعلية"</string>
+ <string name="select_keyboard_layout_notification_title" msgid="4427643867639774118">"إعداد لوحة المفاتيح الفعلية"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"انقر لاختيار لغة وتنسيق"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" أ ب ت ث ج ح خ د ذ ر ز س ش ص ض ط ظ ع غ ف ق ك ل م ن ه و ي"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789 أ ب ت ث ج ح خ د ذ ر ز س ش ص ض ط ظ ع غ ف ق ك ل م ن ه و ي"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 085df65..f9e3e2f 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -945,7 +945,7 @@
<string name="autofill_postal_code" msgid="7034789388968295591">"Kode pos"</string>
<string name="autofill_state" msgid="3341725337190434069">"Negara Bagian"</string>
<string name="autofill_zip_code" msgid="1315503730274962450">"Kode pos"</string>
- <string name="autofill_county" msgid="7781382735643492173">"Wilayah"</string>
+ <string name="autofill_county" msgid="7781382735643492173">"County"</string>
<string name="autofill_island" msgid="5367139008536593734">"Pulau"</string>
<string name="autofill_district" msgid="6428712062213557327">"Distrik"</string>
<string name="autofill_department" msgid="9047276226873531529">"Departemen"</string>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 8871293..df7781e 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -1773,7 +1773,7 @@
<string name="restr_pin_try_later" msgid="5897719962541636727">"Обиди се повторно подоцна"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Се прикажува на цел екран"</string>
<string name="immersive_cling_description" msgid="7092737175345204832">"За да излезете, повлечете одозгора надолу."</string>
- <string name="immersive_cling_positive" msgid="7047498036346489883">"Разбрав"</string>
+ <string name="immersive_cling_positive" msgid="7047498036346489883">"Сфатив"</string>
<string name="done_label" msgid="7283767013231718521">"Готово"</string>
<string name="hour_picker_description" msgid="5153757582093524635">"Приказ на часови во кружно движење"</string>
<string name="minute_picker_description" msgid="9029797023621927294">"Приказ на минути во кружно движење"</string>
diff --git a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
index 000e870..0a751dd 100644
--- a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
+++ b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
@@ -408,6 +408,9 @@
int originalVirtualDisplayOrientation = virtualDisplayContext.getResources()
.getConfiguration().orientation;
+
+ // Perform global config change and verify there is no config change in derived display
+ // context.
Configuration newAppConfig = new Configuration(originalAppConfig);
newAppConfig.seq++;
newAppConfig.orientation = newAppConfig.orientation == ORIENTATION_PORTRAIT
@@ -417,7 +420,7 @@
activityThread.handleConfigurationChanged(newAppConfig);
try {
- assertEquals("Virtual display orientation should not change when process"
+ assertEquals("Virtual display orientation must not change when process"
+ " configuration orientation changes.",
originalVirtualDisplayOrientation,
virtualDisplayContext.getResources().getConfiguration().orientation);
@@ -438,6 +441,50 @@
}
@Test
+ public void testActivityOrientationChanged_DoesntOverrideVirtualDisplayOrientation() {
+ final TestActivity activity = mActivityTestRule.launchActivity(new Intent());
+ final ActivityThread activityThread = activity.getActivityThread();
+
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
+ Configuration originalActivityConfig =
+ new Configuration(activity.getResources().getConfiguration());
+ DisplayManager dm = activity.getSystemService(DisplayManager.class);
+
+ int virtualDisplayWidth;
+ int virtualDisplayHeight;
+ if (originalActivityConfig.orientation == ORIENTATION_PORTRAIT) {
+ virtualDisplayWidth = 100;
+ virtualDisplayHeight = 200;
+ } else {
+ virtualDisplayWidth = 200;
+ virtualDisplayHeight = 100;
+ }
+ Display virtualDisplay = dm.createVirtualDisplay("virtual-display",
+ virtualDisplayWidth, virtualDisplayHeight, 200, null, 0).getDisplay();
+ Context virtualDisplayContext = activity.createDisplayContext(virtualDisplay);
+ int originalVirtualDisplayOrientation = virtualDisplayContext.getResources()
+ .getConfiguration().orientation;
+
+ // Perform activity config change and verify there is no config change in derived
+ // display context.
+ Configuration newActivityConfig = new Configuration(originalActivityConfig);
+ newActivityConfig.seq++;
+ newActivityConfig.orientation = newActivityConfig.orientation == ORIENTATION_PORTRAIT
+ ? ORIENTATION_LANDSCAPE : ORIENTATION_PORTRAIT;
+
+ activityThread.updatePendingActivityConfiguration(activity.getActivityToken(),
+ newActivityConfig);
+ activityThread.handleActivityConfigurationChanged(activity.getActivityToken(),
+ newActivityConfig, INVALID_DISPLAY);
+
+ assertEquals("Virtual display orientation must not change when activity"
+ + " configuration orientation changes.",
+ originalVirtualDisplayOrientation,
+ virtualDisplayContext.getResources().getConfiguration().orientation);
+ });
+ }
+
+ @Test
public void testHandleConfigurationChanged_DoesntOverrideActivityConfig() {
final TestActivity activity = mActivityTestRule.launchActivity(new Intent());
diff --git a/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java b/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java
index efcd458..45adf83 100644
--- a/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java
+++ b/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java
@@ -29,31 +29,50 @@
import junit.framework.TestCase;
+import java.util.HashMap;
+import java.util.Map;
+
public class ResourcesManagerTest extends TestCase {
+ private static final int SECONDARY_DISPLAY_ID = 1;
private static final String APP_ONE_RES_DIR = "app_one.apk";
private static final String APP_ONE_RES_SPLIT_DIR = "app_one_split.apk";
private static final String APP_TWO_RES_DIR = "app_two.apk";
private static final String LIB_RES_DIR = "lib.apk";
private ResourcesManager mResourcesManager;
- private DisplayMetrics mDisplayMetrics;
+ private Map<Integer, DisplayMetrics> mDisplayMetricsMap;
@Override
protected void setUp() throws Exception {
super.setUp();
- mDisplayMetrics = new DisplayMetrics();
- mDisplayMetrics.setToDefaults();
+ mDisplayMetricsMap = new HashMap<>();
+
+ DisplayMetrics defaultDisplayMetrics = new DisplayMetrics();
+ defaultDisplayMetrics.setToDefaults();
// Override defaults (which take device specific properties).
- mDisplayMetrics.density = 1.0f;
- mDisplayMetrics.densityDpi = DisplayMetrics.DENSITY_DEFAULT;
- mDisplayMetrics.xdpi = DisplayMetrics.DENSITY_DEFAULT;
- mDisplayMetrics.ydpi = DisplayMetrics.DENSITY_DEFAULT;
- mDisplayMetrics.noncompatDensity = mDisplayMetrics.density;
- mDisplayMetrics.noncompatDensityDpi = mDisplayMetrics.densityDpi;
- mDisplayMetrics.noncompatXdpi = DisplayMetrics.DENSITY_DEFAULT;
- mDisplayMetrics.noncompatYdpi = DisplayMetrics.DENSITY_DEFAULT;
+ defaultDisplayMetrics.density = 1.0f;
+ defaultDisplayMetrics.densityDpi = DisplayMetrics.DENSITY_DEFAULT;
+ defaultDisplayMetrics.xdpi = DisplayMetrics.DENSITY_DEFAULT;
+ defaultDisplayMetrics.ydpi = DisplayMetrics.DENSITY_DEFAULT;
+ defaultDisplayMetrics.widthPixels = 1440;
+ defaultDisplayMetrics.heightPixels = 2960;
+ defaultDisplayMetrics.noncompatDensity = defaultDisplayMetrics.density;
+ defaultDisplayMetrics.noncompatDensityDpi = defaultDisplayMetrics.densityDpi;
+ defaultDisplayMetrics.noncompatXdpi = DisplayMetrics.DENSITY_DEFAULT;
+ defaultDisplayMetrics.noncompatYdpi = DisplayMetrics.DENSITY_DEFAULT;
+ defaultDisplayMetrics.noncompatWidthPixels = defaultDisplayMetrics.widthPixels;
+ defaultDisplayMetrics.noncompatHeightPixels = defaultDisplayMetrics.heightPixels;
+ mDisplayMetricsMap.put(Display.DEFAULT_DISPLAY, defaultDisplayMetrics);
+
+ DisplayMetrics secondaryDisplayMetrics = new DisplayMetrics();
+ secondaryDisplayMetrics.setTo(defaultDisplayMetrics);
+ secondaryDisplayMetrics.widthPixels = 50;
+ secondaryDisplayMetrics.heightPixels = 100;
+ secondaryDisplayMetrics.noncompatWidthPixels = secondaryDisplayMetrics.widthPixels;
+ secondaryDisplayMetrics.noncompatHeightPixels = secondaryDisplayMetrics.heightPixels;
+ mDisplayMetricsMap.put(SECONDARY_DISPLAY_ID, secondaryDisplayMetrics);
mResourcesManager = new ResourcesManager() {
@Override
@@ -63,7 +82,7 @@
@Override
protected DisplayMetrics getDisplayMetrics(int displayId, DisplayAdjustments daj) {
- return mDisplayMetrics;
+ return mDisplayMetricsMap.get(displayId);
}
};
}
@@ -71,12 +90,12 @@
@SmallTest
public void testMultipleCallsWithIdenticalParametersCacheReference() {
Resources resources = mResourcesManager.getResources(
- null, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null,
+ null, APP_ONE_RES_DIR, null, null, null, null, null,
CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null, null);
assertNotNull(resources);
Resources newResources = mResourcesManager.getResources(
- null, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null,
+ null, APP_ONE_RES_DIR, null, null, null, null, null,
CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null, null);
assertNotNull(newResources);
assertSame(resources, newResources);
@@ -85,14 +104,14 @@
@SmallTest
public void testMultipleCallsWithDifferentParametersReturnDifferentReferences() {
Resources resources = mResourcesManager.getResources(
- null, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null,
+ null, APP_ONE_RES_DIR, null, null, null, null, null,
CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null, null);
assertNotNull(resources);
Configuration overrideConfig = new Configuration();
overrideConfig.smallestScreenWidthDp = 200;
Resources newResources = mResourcesManager.getResources(
- null, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, overrideConfig,
+ null, APP_ONE_RES_DIR, null, null, null, null, overrideConfig,
CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null, null);
assertNotNull(newResources);
assertNotSame(resources, newResources);
@@ -101,13 +120,13 @@
@SmallTest
public void testAddingASplitCreatesANewImpl() {
Resources resources1 = mResourcesManager.getResources(
- null, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null,
+ null, APP_ONE_RES_DIR, null, null, null, null, null,
CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null, null);
assertNotNull(resources1);
Resources resources2 = mResourcesManager.getResources(
null, APP_ONE_RES_DIR, new String[] { APP_ONE_RES_SPLIT_DIR }, null, null,
- Display.DEFAULT_DISPLAY, null, CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO,null,
+ null, null, CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null,
null);
assertNotNull(resources2);
@@ -118,12 +137,12 @@
@SmallTest
public void testUpdateConfigurationUpdatesAllAssetManagers() {
Resources resources1 = mResourcesManager.getResources(
- null, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null,
+ null, APP_ONE_RES_DIR, null, null, null, null, null,
CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null, null);
assertNotNull(resources1);
Resources resources2 = mResourcesManager.getResources(
- null, APP_TWO_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null,
+ null, APP_TWO_RES_DIR, null, null, null, null, null,
CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null, null);
assertNotNull(resources2);
@@ -131,7 +150,7 @@
final Configuration overrideConfig = new Configuration();
overrideConfig.orientation = Configuration.ORIENTATION_LANDSCAPE;
Resources resources3 = mResourcesManager.getResources(
- activity, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY,
+ activity, APP_ONE_RES_DIR, null, null, null, null,
overrideConfig, CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null, null);
assertNotNull(resources3);
@@ -152,7 +171,7 @@
final Configuration expectedConfig = new Configuration();
expectedConfig.setToDefaults();
expectedConfig.setLocales(LocaleList.getAdjustedDefault());
- expectedConfig.densityDpi = mDisplayMetrics.densityDpi;
+ expectedConfig.densityDpi = mDisplayMetricsMap.get(Display.DEFAULT_DISPLAY).densityDpi;
expectedConfig.orientation = Configuration.ORIENTATION_LANDSCAPE;
assertEquals(expectedConfig, resources1.getConfiguration());
@@ -164,13 +183,13 @@
public void testTwoActivitiesWithIdenticalParametersShareImpl() {
Binder activity1 = new Binder();
Resources resources1 = mResourcesManager.getResources(
- activity1, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null,
+ activity1, APP_ONE_RES_DIR, null, null, null, null, null,
CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null, null);
assertNotNull(resources1);
Binder activity2 = new Binder();
Resources resources2 = mResourcesManager.getResources(
- activity2, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null,
+ activity2, APP_ONE_RES_DIR, null, null, null, null, null,
CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null, null);
assertNotNull(resources1);
@@ -201,7 +220,7 @@
final Configuration overrideConfig = new Configuration();
overrideConfig.orientation = Configuration.ORIENTATION_LANDSCAPE;
mResourcesManager.updateResourcesForActivity(activity1, overrideConfig,
- Display.DEFAULT_DISPLAY, false /* movedToDifferentDisplay */);
+ Display.DEFAULT_DISPLAY);
assertSame(resources1, theme.getResources());
// Make sure we can still access the data.
@@ -226,7 +245,7 @@
Configuration config2 = new Configuration();
config2.screenLayout |= Configuration.SCREENLAYOUT_ROUND_YES;
Resources resources2 = mResourcesManager.getResources(
- activity1, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, config2,
+ activity1, APP_ONE_RES_DIR, null, null, null, null, config2,
CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null, null);
assertNotNull(resources2);
@@ -250,8 +269,7 @@
// Now update the Activity base override, and both resources should update.
config1.orientation = Configuration.ORIENTATION_LANDSCAPE;
- mResourcesManager.updateResourcesForActivity(activity1, config1, Display.DEFAULT_DISPLAY,
- false /* movedToDifferentDisplay */);
+ mResourcesManager.updateResourcesForActivity(activity1, config1, Display.DEFAULT_DISPLAY);
expectedConfig1.orientation = Configuration.ORIENTATION_LANDSCAPE;
assertEquals(expectedConfig1, resources1.getConfiguration());
@@ -290,4 +308,41 @@
assertEquals(originalOverrideDensity,
resources.getDisplayAdjustments().getConfiguration().densityDpi);
}
+
+ @SmallTest
+ public void testChangingActivityDisplayDoesntOverrideDisplayRequestedByResources() {
+ Binder activity = new Binder();
+
+ // Create a base token resources that are based on the default display.
+ Resources activityResources = mResourcesManager.createBaseTokenResources(
+ activity, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null,
+ CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null, null);
+ // Create another resources that explicitly override the display of the base token above
+ // and set it to DEFAULT_DISPLAY.
+ Resources defaultDisplayResources = mResourcesManager.getResources(
+ activity, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null,
+ CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null, null);
+
+ assertEquals(mDisplayMetricsMap.get(Display.DEFAULT_DISPLAY).widthPixels,
+ activityResources.getDisplayMetrics().widthPixels);
+ assertEquals(mDisplayMetricsMap.get(Display.DEFAULT_DISPLAY).heightPixels,
+ activityResources.getDisplayMetrics().heightPixels);
+ assertEquals(mDisplayMetricsMap.get(Display.DEFAULT_DISPLAY).widthPixels,
+ defaultDisplayResources.getDisplayMetrics().widthPixels);
+ assertEquals(mDisplayMetricsMap.get(Display.DEFAULT_DISPLAY).widthPixels,
+ defaultDisplayResources.getDisplayMetrics().widthPixels);
+
+ // Now change the display of the activity and ensure the activity's display metrics match
+ // the new display, but the other resources remain based on the default display.
+ mResourcesManager.updateResourcesForActivity(activity, null, SECONDARY_DISPLAY_ID);
+
+ assertEquals(mDisplayMetricsMap.get(SECONDARY_DISPLAY_ID).widthPixels,
+ activityResources.getDisplayMetrics().widthPixels);
+ assertEquals(mDisplayMetricsMap.get(SECONDARY_DISPLAY_ID).heightPixels,
+ activityResources.getDisplayMetrics().heightPixels);
+ assertEquals(mDisplayMetricsMap.get(Display.DEFAULT_DISPLAY).widthPixels,
+ defaultDisplayResources.getDisplayMetrics().widthPixels);
+ assertEquals(mDisplayMetricsMap.get(Display.DEFAULT_DISPLAY).widthPixels,
+ defaultDisplayResources.getDisplayMetrics().widthPixels);
+ }
}
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java
index 7807f01..bef27e2 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java
@@ -39,6 +39,7 @@
BatteryStatsTimerTest.class,
BatteryStatsUidTest.class,
BatteryStatsUserLifecycleTests.class,
+ BstatsCpuTimesValidationTest.class,
KernelCpuProcStringReaderTest.class,
KernelCpuUidActiveTimeReaderTest.class,
KernelCpuUidBpfMapReaderTest.class,
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index f410490..4f95a53 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -684,15 +684,13 @@
return b;
}
- // FIXME: The maxTargetSdk should be R, once R is no longer set to
- // CUR_DEVELOPMENT.
/**
* Creates a new immutable bitmap backed by ashmem which can efficiently
* be passed between processes.
*
* @hide
*/
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q,
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R,
publicAlternatives = "Use {@link #asShared()} instead")
public Bitmap createAshmemBitmap() {
checkRecycled("Can't copy a recycled bitmap");
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java
index aeda2d9..283fd8d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java
@@ -68,7 +68,7 @@
private final SparseArray<PerDisplay> mImePerDisplay = new SparseArray<>();
private final ArrayList<ImePositionProcessor> mPositionProcessors = new ArrayList<>();
- protected DisplayImeController(IWindowManager wmService, DisplayController displayController,
+ public DisplayImeController(IWindowManager wmService, DisplayController displayController,
Handler mainHandler, TransactionPool transactionPool) {
mHandler = mainHandler;
mWmService = wmService;
@@ -76,7 +76,8 @@
mDisplayController = displayController;
}
- protected void startMonitorDisplays() {
+ /** Starts monitor displays changes and set insets controller for each displays. */
+ public void startMonitorDisplays() {
mDisplayController.addDisplayWindowListener(this);
}
@@ -493,29 +494,4 @@
return IInputMethodManager.Stub.asInterface(
ServiceManager.getService(Context.INPUT_METHOD_SERVICE));
}
-
- /** Builds {@link DisplayImeController} instance. */
- public static class Builder {
- private IWindowManager mWmService;
- private DisplayController mDisplayController;
- private Handler mHandler;
- private TransactionPool mTransactionPool;
-
- public Builder(IWindowManager wmService, DisplayController displayController,
- Handler handler, TransactionPool transactionPool) {
- mWmService = wmService;
- mDisplayController = displayController;
- mHandler = handler;
- mTransactionPool = transactionPool;
- }
-
- /** Builds and initializes {@link DisplayImeController} instance. */
- public DisplayImeController build() {
- DisplayImeController displayImeController = new DisplayImeController(mWmService,
- mDisplayController, mHandler, mTransactionPool);
- // Separates startMonitorDisplays from constructor to prevent circular init issue.
- displayImeController.startMonitorDisplays();
- return displayImeController;
- }
- }
}
diff --git a/libs/WindowManager/Shell/tests/README.md b/libs/WindowManager/Shell/tests/README.md
new file mode 100644
index 0000000..c19db76
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/README.md
@@ -0,0 +1,15 @@
+# WM Shell Test
+
+This contains all tests written for WM (WindowManager) Shell and it's currently
+divided into 3 categories
+
+- unittest, tests against individual functions, usually @SmallTest and do not
+ require UI automation nor real device to run
+- integration, this maybe a mix of functional and integration tests. Contains
+ tests verify the WM Shell as a whole, like talking to WM core. This usually
+ involves mocking the window manager service or even talking to the real one.
+ Due to this nature, test cases in this package is normally annotated as
+ @LargeTest and runs with UI automation on real device
+- flicker, similar to functional tests with its sole focus on flickerness. See
+ [WM Shell Flicker Test Package](http://cs/android/framework/base/libs/WindowManager/Shell/tests/flicker/)
+ for more details
diff --git a/libs/WindowManager/Shell/tests/flicker/Android.bp b/libs/WindowManager/Shell/tests/flicker/Android.bp
new file mode 100644
index 0000000..5879022
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/Android.bp
@@ -0,0 +1,34 @@
+//
+// 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.
+//
+
+android_test {
+ name: "WMShellFlickerTests",
+ srcs: ["src/**/*.java", "src/**/*.kt"],
+ manifest: "AndroidManifest.xml",
+ test_config: "AndroidTest.xml",
+ platform_apis: true,
+ certificate: "platform",
+ test_suites: ["device-tests"],
+ libs: ["android.test.runner"],
+ static_libs: [
+ "androidx.test.ext.junit",
+ "flickerlib",
+ "truth-prebuilt",
+ "app-helpers-core",
+ "launcher-helper-lib",
+ "launcher-aosp-tapl"
+ ],
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/AndroidManifest.xml b/libs/WindowManager/Shell/tests/flicker/AndroidManifest.xml
new file mode 100644
index 0000000..8b2f668
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/AndroidManifest.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.wm.shell.flicker">
+
+ <uses-sdk android:minSdkVersion="29" android:targetSdkVersion="29"/>
+ <!-- Read and write traces from external storage -->
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+ <!-- Write secure settings -->
+ <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
+ <!-- Capture screen contents -->
+ <uses-permission android:name="android.permission.ACCESS_SURFACE_FLINGER" />
+ <!-- Enable / Disable tracing !-->
+ <uses-permission android:name="android.permission.DUMP" />
+ <!-- Run layers trace -->
+ <uses-permission android:name="android.permission.HARDWARE_TEST"/>
+ <!-- Workaround grant runtime permission exception from b/152733071 -->
+ <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/>
+ <uses-permission android:name="android.permission.READ_LOGS"/>
+ <application>
+ <uses-library android:name="android.test.runner"/>
+ </application>
+
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="com.android.wm.shell.flicker"
+ android:label="WindowManager Shell Flicker Tests">
+ </instrumentation>
+</manifest>
diff --git a/libs/WindowManager/Shell/tests/flicker/AndroidTest.xml b/libs/WindowManager/Shell/tests/flicker/AndroidTest.xml
new file mode 100644
index 0000000..526fc50
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/AndroidTest.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright 2020 Google Inc. All Rights Reserved.
+ -->
+<configuration description="Runs WindowManager Shell Flicker Tests">
+ <option name="test-tag" value="FlickerTests" />
+ <target_preparer class="com.android.tradefed.targetprep.DeviceSetup">
+ <!-- keeps the screen on during tests -->
+ <option name="screen-always-on" value="on" />
+ <!-- prevents the phone from restarting -->
+ <option name="force-skip-system-props" value="true" />
+ <!-- set WM tracing verbose level to all -->
+ <option name="run-command" value="cmd window tracing level all" />
+ <!-- inform WM to log all transactions -->
+ <option name="run-command" value="cmd window tracing transaction" />
+ <!-- restart launcher to activate TAPL -->
+ <option name="run-command" value="setprop ro.test_harness 1 ; am force-stop com.google.android.apps.nexuslauncher" />
+ </target_preparer>
+ <target_preparer class="com.android.tradefed.targetprep.DeviceCleaner">
+ <!-- reboot the device to teardown any crashed tests -->
+ <option name="cleanup-action" value="REBOOT" />
+ </target_preparer>
+ <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+ <option name="cleanup-apks" value="true"/>
+ <option name="test-file-name" value="WMShellFlickerTests.apk"/>
+ <option name="test-file-name" value="WMShellFlickerTestApp.apk" />
+ </target_preparer>
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest">
+ <option name="package" value="com.android.wm.shell.flicker"/>
+ <option name="exclude-annotation" value="androidx.test.filters.FlakyTest" />
+ <option name="shell-timeout" value="6600s" />
+ <option name="test-timeout" value="6000s" />
+ <option name="hidden-api-checks" value="false" />
+ </test>
+ <metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
+ <option name="directory-keys" value="/storage/emulated/0/Android/data/com.android.wm.shell.flicker/files" />
+ <option name="collect-on-run-ended-only" value="true" />
+ <option name="clean-up" value="true" />
+ </metrics_collector>
+</configuration>
diff --git a/libs/WindowManager/Shell/tests/flicker/README.md b/libs/WindowManager/Shell/tests/flicker/README.md
new file mode 100644
index 0000000..4502d49
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/README.md
@@ -0,0 +1,10 @@
+# WM Shell Flicker Test Package
+
+Please reference the following links
+
+- [Introduction to Flicker Test Library](http://cs/android/platform_testing/libraries/flicker/)
+- [Flicker Test in frameworks/base](http://cs/android/frameworks/base/tests/FlickerTests/)
+
+on what is Flicker Test and how to write a Flicker Test
+
+To run the Flicker Tests for WM Shell, simply run `atest WMShellFlickerTests`
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt
new file mode 100644
index 0000000..4ff2bfc
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt
@@ -0,0 +1,153 @@
+/*
+ * 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.wm.shell.flicker
+
+import com.android.server.wm.flicker.dsl.EventLogAssertion
+import com.android.server.wm.flicker.dsl.LayersAssertion
+import com.android.server.wm.flicker.dsl.WmAssertion
+import com.android.server.wm.flicker.helpers.WindowUtils
+
+@JvmOverloads
+fun WmAssertion.statusBarWindowIsAlwaysVisible(
+ bugId: Int = 0,
+ enabled: Boolean = bugId == 0
+) {
+ all("statusBarWindowIsAlwaysVisible", enabled, bugId) {
+ this.showsAboveAppWindow(FlickerTestBase.STATUS_BAR_WINDOW_TITLE)
+ }
+}
+
+@JvmOverloads
+fun WmAssertion.navBarWindowIsAlwaysVisible(
+ bugId: Int = 0,
+ enabled: Boolean = bugId == 0
+) {
+ all("navBarWindowIsAlwaysVisible", enabled, bugId) {
+ this.showsAboveAppWindow(FlickerTestBase.NAVIGATION_BAR_WINDOW_TITLE)
+ }
+}
+
+@JvmOverloads
+fun LayersAssertion.noUncoveredRegions(
+ beginRotation: Int,
+ endRotation: Int = beginRotation,
+ allStates: Boolean = true,
+ bugId: Int = 0,
+ enabled: Boolean = bugId == 0
+) {
+ val startingBounds = WindowUtils.getDisplayBounds(beginRotation)
+ val endingBounds = WindowUtils.getDisplayBounds(endRotation)
+ if (allStates) {
+ all("noUncoveredRegions", enabled, bugId) {
+ if (startingBounds == endingBounds) {
+ this.coversAtLeastRegion(startingBounds)
+ } else {
+ this.coversAtLeastRegion(startingBounds)
+ .then()
+ .coversAtLeastRegion(endingBounds)
+ }
+ }
+ } else {
+ start("noUncoveredRegions_StartingPos") {
+ this.coversAtLeastRegion(startingBounds)
+ }
+ end("noUncoveredRegions_EndingPos") {
+ this.coversAtLeastRegion(endingBounds)
+ }
+ }
+}
+
+@JvmOverloads
+fun LayersAssertion.navBarLayerIsAlwaysVisible(
+ bugId: Int = 0,
+ enabled: Boolean = bugId == 0
+) {
+ all("navBarLayerIsAlwaysVisible", enabled, bugId) {
+ this.showsLayer(FlickerTestBase.NAVIGATION_BAR_WINDOW_TITLE)
+ }
+}
+
+@JvmOverloads
+fun LayersAssertion.statusBarLayerIsAlwaysVisible(
+ bugId: Int = 0,
+ enabled: Boolean = bugId == 0
+) {
+ all("statusBarLayerIsAlwaysVisible", enabled, bugId) {
+ this.showsLayer(FlickerTestBase.STATUS_BAR_WINDOW_TITLE)
+ }
+}
+
+@JvmOverloads
+fun LayersAssertion.navBarLayerRotatesAndScales(
+ beginRotation: Int,
+ endRotation: Int = beginRotation,
+ bugId: Int = 0,
+ enabled: Boolean = bugId == 0
+) {
+ val startingPos = WindowUtils.getNavigationBarPosition(beginRotation)
+ val endingPos = WindowUtils.getNavigationBarPosition(endRotation)
+
+ start("navBarLayerRotatesAndScales_StartingPos", enabled, bugId) {
+ this.hasVisibleRegion(FlickerTestBase.NAVIGATION_BAR_WINDOW_TITLE, startingPos)
+ }
+ end("navBarLayerRotatesAndScales_EndingPost", enabled, bugId) {
+ this.hasVisibleRegion(FlickerTestBase.NAVIGATION_BAR_WINDOW_TITLE, endingPos)
+ }
+
+ if (startingPos == endingPos) {
+ all("navBarLayerRotatesAndScales", enabled, bugId) {
+ this.hasVisibleRegion(FlickerTestBase.NAVIGATION_BAR_WINDOW_TITLE, startingPos)
+ }
+ }
+}
+
+@JvmOverloads
+fun LayersAssertion.statusBarLayerRotatesScales(
+ beginRotation: Int,
+ endRotation: Int = beginRotation,
+ bugId: Int = 0,
+ enabled: Boolean = bugId == 0
+) {
+ val startingPos = WindowUtils.getStatusBarPosition(beginRotation)
+ val endingPos = WindowUtils.getStatusBarPosition(endRotation)
+
+ start("statusBarLayerRotatesScales_StartingPos", enabled, bugId) {
+ this.hasVisibleRegion(FlickerTestBase.STATUS_BAR_WINDOW_TITLE, startingPos)
+ }
+ end("statusBarLayerRotatesScales_EndingPos", enabled, bugId) {
+ this.hasVisibleRegion(FlickerTestBase.STATUS_BAR_WINDOW_TITLE, endingPos)
+ }
+}
+
+fun EventLogAssertion.focusChanges(
+ vararg windows: String,
+ bugId: Int = 0,
+ enabled: Boolean = bugId == 0
+) {
+ all(enabled = enabled, bugId = bugId) {
+ this.focusChanges(windows)
+ }
+}
+
+fun EventLogAssertion.focusDoesNotChange(
+ bugId: Int = 0,
+ enabled: Boolean = bugId == 0
+) {
+ all(enabled = enabled, bugId = bugId) {
+ this.focusDoesNotChange()
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/FlickerTestBase.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/FlickerTestBase.kt
new file mode 100644
index 0000000..99f824b
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/FlickerTestBase.kt
@@ -0,0 +1,130 @@
+/*
+ * 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.wm.shell.flicker
+
+import android.os.RemoteException
+import android.os.SystemClock
+import android.platform.helpers.IAppHelper
+import android.view.Surface
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.uiautomator.UiDevice
+import com.android.server.wm.flicker.Flicker
+
+/**
+ * Base class of all Flicker test that performs common functions for all flicker tests:
+ *
+ *
+ * - Caches transitions so that a transition is run once and the transition results are used by
+ * tests multiple times. This is needed for parameterized tests which call the BeforeClass methods
+ * multiple times.
+ * - Keeps track of all test artifacts and deletes ones which do not need to be reviewed.
+ * - Fails tests if results are not available for any test due to jank.
+ */
+abstract class FlickerTestBase {
+ val instrumentation by lazy {
+ InstrumentationRegistry.getInstrumentation()
+ }
+ val uiDevice by lazy {
+ UiDevice.getInstance(instrumentation)
+ }
+
+ /**
+ * Build a test tag for the test
+ * @param testName Name of the transition(s) being tested
+ * @param app App being launcher
+ * @param rotation Initial screen rotation
+ *
+ * @return test tag with pattern <NAME>__<APP>__<ROTATION>
+ </ROTATION></APP></NAME> */
+ protected fun buildTestTag(testName: String, app: IAppHelper, rotation: Int): String {
+ return buildTestTag(
+ testName, app, rotation, rotation, app2 = null, extraInfo = "")
+ }
+
+ /**
+ * Build a test tag for the test
+ * @param testName Name of the transition(s) being tested
+ * @param app App being launcher
+ * @param beginRotation Initial screen rotation
+ * @param endRotation End screen rotation (if any, otherwise use same as initial)
+ *
+ * @return test tag with pattern <NAME>__<APP>__<BEGIN_ROTATION>-<END_ROTATION>
+ </END_ROTATION></BEGIN_ROTATION></APP></NAME> */
+ protected fun buildTestTag(
+ testName: String,
+ app: IAppHelper,
+ beginRotation: Int,
+ endRotation: Int
+ ): String {
+ return buildTestTag(
+ testName, app, beginRotation, endRotation, app2 = null, extraInfo = "")
+ }
+
+ /**
+ * Build a test tag for the test
+ * @param testName Name of the transition(s) being tested
+ * @param app App being launcher
+ * @param app2 Second app being launched (if any)
+ * @param beginRotation Initial screen rotation
+ * @param endRotation End screen rotation (if any, otherwise use same as initial)
+ * @param extraInfo Additional information to append to the tag
+ *
+ * @return test tag with pattern <NAME>__<APP></APP>(S)>__<ROTATION></ROTATION>(S)>[__<EXTRA>]
+ </EXTRA></NAME> */
+ protected fun buildTestTag(
+ testName: String,
+ app: IAppHelper,
+ beginRotation: Int,
+ endRotation: Int,
+ app2: IAppHelper?,
+ extraInfo: String
+ ): String {
+ var testTag = "${testName}__${app.launcherName}"
+ if (app2 != null) {
+ testTag += "-${app2.launcherName}"
+ }
+ testTag += "__${Surface.rotationToString(beginRotation)}"
+ if (endRotation != beginRotation) {
+ testTag += "-${Surface.rotationToString(endRotation)}"
+ }
+ if (extraInfo.isNotEmpty()) {
+ testTag += "__$extraInfo"
+ }
+ return testTag
+ }
+
+ protected fun Flicker.setRotation(rotation: Int) {
+ try {
+ when (rotation) {
+ Surface.ROTATION_270 -> device.setOrientationLeft()
+ Surface.ROTATION_90 -> device.setOrientationRight()
+ Surface.ROTATION_0 -> device.setOrientationNatural()
+ else -> device.setOrientationNatural()
+ }
+ // Wait for animation to complete
+ SystemClock.sleep(1000)
+ } catch (e: RemoteException) {
+ throw RuntimeException(e)
+ }
+ }
+
+ companion object {
+ const val NAVIGATION_BAR_WINDOW_TITLE = "NavigationBar"
+ const val STATUS_BAR_WINDOW_TITLE = "StatusBar"
+ const val DOCKED_STACK_DIVIDER = "DockedStackDivider"
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/NonRotationTestBase.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/NonRotationTestBase.kt
new file mode 100644
index 0000000..90334ae
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/NonRotationTestBase.kt
@@ -0,0 +1,36 @@
+/*
+ * 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.wm.shell.flicker
+
+import android.view.Surface
+import org.junit.runners.Parameterized
+
+abstract class NonRotationTestBase(
+ protected val rotationName: String,
+ protected val rotation: Int
+) : FlickerTestBase() {
+ companion object {
+ const val SCREENSHOT_LAYER = "RotationLayer"
+
+ @Parameterized.Parameters(name = "{0}")
+ @JvmStatic
+ fun getParams(): Collection<Array<Any>> {
+ val supportedRotations = intArrayOf(Surface.ROTATION_0, Surface.ROTATION_90)
+ return supportedRotations.map { arrayOf(Surface.rotationToString(it), it) }
+ }
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/FlickerAppHelper.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/FlickerAppHelper.kt
new file mode 100644
index 0000000..308a36e
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/FlickerAppHelper.kt
@@ -0,0 +1,31 @@
+/*
+ * 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.wm.shell.flicker.helpers
+
+import android.app.Instrumentation
+import android.support.test.launcherhelper.ILauncherStrategy
+import com.android.server.wm.flicker.StandardAppHelper
+
+abstract class FlickerAppHelper(
+ instr: Instrumentation,
+ launcherName: String,
+ launcherStrategy: ILauncherStrategy
+) : StandardAppHelper(instr, sFlickerPackage, launcherName, launcherStrategy) {
+ companion object {
+ var sFlickerPackage = "com.android.wm.shell.flicker.testapp"
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt
new file mode 100644
index 0000000..5391702
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt
@@ -0,0 +1,45 @@
+/*
+ * 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.wm.shell.flicker.helpers
+
+import android.app.Instrumentation
+import android.support.test.launcherhelper.ILauncherStrategy
+import android.support.test.launcherhelper.LauncherStrategyFactory
+import androidx.test.uiautomator.By
+import androidx.test.uiautomator.UiDevice
+import com.android.server.wm.flicker.helpers.hasPipWindow
+import com.android.server.wm.flicker.helpers.closePipWindow
+import org.junit.Assert
+
+class PipAppHelper(
+ instr: Instrumentation,
+ launcherStrategy: ILauncherStrategy = LauncherStrategyFactory
+ .getInstance(instr)
+ .launcherStrategy
+) : FlickerAppHelper(instr, "PipApp", launcherStrategy) {
+ fun clickEnterPipButton(device: UiDevice) {
+ val enterPipButton = device.findObject(By.res(getPackage(), "enter_pip"))
+ Assert.assertNotNull("Pip button not found, this usually happens when the device " +
+ "was left in an unknown state (e.g. in split screen)", enterPipButton)
+ enterPipButton.click()
+ device.hasPipWindow()
+ }
+
+ fun closePipWindow(device: UiDevice) {
+ device.closePipWindow()
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
new file mode 100644
index 0000000..4b04449
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
@@ -0,0 +1,121 @@
+/*
+ * 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.wm.shell.flicker.pip
+
+import android.view.Surface
+import androidx.test.filters.FlakyTest
+import androidx.test.filters.LargeTest
+import com.android.server.wm.flicker.dsl.flicker
+import com.android.server.wm.flicker.helpers.closePipWindow
+import com.android.server.wm.flicker.helpers.expandPipWindow
+import com.android.server.wm.flicker.helpers.hasPipWindow
+import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
+import com.android.wm.shell.flicker.navBarLayerIsAlwaysVisible
+import com.android.wm.shell.flicker.navBarLayerRotatesAndScales
+import com.android.wm.shell.flicker.navBarWindowIsAlwaysVisible
+import com.android.wm.shell.flicker.noUncoveredRegions
+import com.android.wm.shell.flicker.statusBarLayerIsAlwaysVisible
+import com.android.wm.shell.flicker.statusBarLayerRotatesScales
+import com.android.wm.shell.flicker.statusBarWindowIsAlwaysVisible
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test Pip launch.
+ * To run this test: `atest FlickerTests:PipToAppTest`
+ */
+@LargeTest
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@FlakyTest(bugId = 152738416)
+class EnterPipTest(
+ rotationName: String,
+ rotation: Int
+) : PipTestBase(rotationName, rotation) {
+ @Test
+ fun test() {
+ flicker(instrumentation) {
+ withTag { buildTestTag("enterPip", testApp, rotation) }
+ repeat { 1 }
+ setup {
+ test {
+ device.wakeUpAndGoToHomeScreen()
+ }
+ eachRun {
+ device.pressHome()
+ testApp.open()
+ this.setRotation(rotation)
+ }
+ }
+ teardown {
+ eachRun {
+ if (device.hasPipWindow()) {
+ device.closePipWindow()
+ }
+ testApp.exit()
+ this.setRotation(Surface.ROTATION_0)
+ }
+ test {
+ if (device.hasPipWindow()) {
+ device.closePipWindow()
+ }
+ }
+ }
+ transitions {
+ testApp.clickEnterPipButton(device)
+ device.expandPipWindow()
+ }
+ assertions {
+ windowManagerTrace {
+ navBarWindowIsAlwaysVisible()
+ statusBarWindowIsAlwaysVisible()
+ all("pipWindowBecomesVisible") {
+ this.showsAppWindow(testApp.`package`)
+ .then()
+ .showsAppWindow(sPipWindowTitle)
+ }
+ }
+
+ layersTrace {
+ navBarLayerIsAlwaysVisible()
+ statusBarLayerIsAlwaysVisible()
+ noUncoveredRegions(rotation, Surface.ROTATION_0, allStates = false)
+ navBarLayerRotatesAndScales(rotation, Surface.ROTATION_0)
+ statusBarLayerRotatesScales(rotation, Surface.ROTATION_0)
+
+ all("pipLayerBecomesVisible") {
+ this.showsLayer(testApp.launcherName)
+ .then()
+ .showsLayer(sPipWindowTitle)
+ }
+ }
+ }
+ }
+ }
+
+ companion object {
+ @Parameterized.Parameters(name = "{0}")
+ @JvmStatic
+ fun getParams(): Collection<Array<Any>> {
+ val supportedRotations = intArrayOf(Surface.ROTATION_0)
+ return supportedRotations.map { arrayOf(Surface.rotationToString(it), it) }
+ }
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/src/com/android/wm/shell/WindowManagerShellTest.java b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTestBase.kt
similarity index 60%
rename from libs/WindowManager/Shell/tests/src/com/android/wm/shell/WindowManagerShellTest.java
rename to libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTestBase.kt
index f1ead3c..3822d69 100644
--- a/libs/WindowManager/Shell/tests/src/com/android/wm/shell/WindowManagerShellTest.java
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTestBase.kt
@@ -14,25 +14,18 @@
* limitations under the License.
*/
-package com.android.wm.shell;
+package com.android.wm.shell.flicker.pip
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
+import com.android.wm.shell.flicker.NonRotationTestBase
+import com.android.wm.shell.flicker.helpers.PipAppHelper
-import org.junit.Test;
-import org.junit.runner.RunWith;
+abstract class PipTestBase(
+ rotationName: String,
+ rotation: Int
+) : NonRotationTestBase(rotationName, rotation) {
+ protected val testApp = PipAppHelper(instrumentation)
-/**
- * Tests for the shell.
- */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class WindowManagerShellTest {
-
- WindowManagerShell mShell;
-
- @Test
- public void testNothing() {
- // Do nothing
+ companion object {
+ const val sPipWindowTitle = "PipMenuActivity"
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/Android.bp b/libs/WindowManager/Shell/tests/flicker/test-apps/Android.bp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/test-apps/Android.bp
diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/Android.bp b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/Android.bp
new file mode 100644
index 0000000..d12b492
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/Android.bp
@@ -0,0 +1,20 @@
+// 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.
+
+android_test {
+ name: "WMShellFlickerTestApp",
+ srcs: ["**/*.java"],
+ sdk_version: "current",
+ test_suites: ["device-tests"],
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/AndroidManifest.xml b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/AndroidManifest.xml
new file mode 100644
index 0000000..95dc1d4
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/AndroidManifest.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.wm.shell.flicker.testapp">
+
+ <uses-sdk android:minSdkVersion="29"
+ android:targetSdkVersion="29"/>
+ <application android:allowBackup="false"
+ android:supportsRtl="true">
+ <activity android:name=".PipActivity"
+ android:resizeableActivity="true"
+ android:supportsPictureInPicture="true"
+ android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
+ android:taskAffinity="com.android.wm.shell.flicker.testapp.PipActivity"
+ android:label="PipApp"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_pip.xml b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_pip.xml
new file mode 100644
index 0000000..e1870d9
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_pip.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+-->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@android:color/holo_blue_bright">
+ <Button android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:id="@+id/enter_pip"
+ android:text="Enter PIP"/>
+</LinearLayout>
diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/PipActivity.java b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/PipActivity.java
new file mode 100644
index 0000000..3052816
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/PipActivity.java
@@ -0,0 +1,45 @@
+/*
+ * 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.wm.shell.flicker.testapp;
+
+import android.app.Activity;
+import android.app.PictureInPictureParams;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.util.Rational;
+import android.view.WindowManager;
+import android.widget.Button;
+
+public class PipActivity extends Activity {
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ WindowManager.LayoutParams p = getWindow().getAttributes();
+ p.layoutInDisplayCutoutMode = WindowManager.LayoutParams
+ .LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
+ getWindow().setAttributes(p);
+ setContentView(R.layout.activity_pip);
+ Button enterPip = (Button) findViewById(R.id.enter_pip);
+
+ PictureInPictureParams params = new PictureInPictureParams.Builder()
+ .setAspectRatio(new Rational(1, 1))
+ .setSourceRectHint(new Rect(0, 0, 100, 100))
+ .build();
+
+ enterPip.setOnClickListener((v) -> enterPictureInPictureMode(params));
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/Android.bp b/libs/WindowManager/Shell/tests/unittest/Android.bp
similarity index 96%
rename from libs/WindowManager/Shell/tests/Android.bp
rename to libs/WindowManager/Shell/tests/unittest/Android.bp
index 9868879..692e2fa 100644
--- a/libs/WindowManager/Shell/tests/Android.bp
+++ b/libs/WindowManager/Shell/tests/unittest/Android.bp
@@ -13,7 +13,7 @@
// limitations under the License.
android_test {
- name: "WindowManagerShellTests",
+ name: "WMShellUnitTests",
srcs: ["**/*.java"],
diff --git a/libs/WindowManager/Shell/tests/AndroidManifest.xml b/libs/WindowManager/Shell/tests/unittest/AndroidManifest.xml
similarity index 100%
rename from libs/WindowManager/Shell/tests/AndroidManifest.xml
rename to libs/WindowManager/Shell/tests/unittest/AndroidManifest.xml
diff --git a/libs/WindowManager/Shell/tests/AndroidTest.xml b/libs/WindowManager/Shell/tests/unittest/AndroidTest.xml
similarity index 90%
rename from libs/WindowManager/Shell/tests/AndroidTest.xml
rename to libs/WindowManager/Shell/tests/unittest/AndroidTest.xml
index 4dce4db..21ed2c0 100644
--- a/libs/WindowManager/Shell/tests/AndroidTest.xml
+++ b/libs/WindowManager/Shell/tests/unittest/AndroidTest.xml
@@ -17,12 +17,12 @@
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
<option name="install-arg" value="-t" />
- <option name="test-file-name" value="WindowManagerShellTests.apk" />
+ <option name="test-file-name" value="WMShellUnitTests.apk" />
</target_preparer>
<option name="test-suite-tag" value="apct" />
<option name="test-suite-tag" value="framework-base-presubmit" />
- <option name="test-tag" value="WindowManagerShellTests" />
+ <option name="test-tag" value="WMShellUnitTests" />
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="com.android.wm.shell.tests" />
<option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
diff --git a/libs/WindowManager/Shell/tests/res/values/config.xml b/libs/WindowManager/Shell/tests/unittest/res/values/config.xml
similarity index 100%
rename from libs/WindowManager/Shell/tests/res/values/config.xml
rename to libs/WindowManager/Shell/tests/unittest/res/values/config.xml
diff --git a/libs/WindowManager/Shell/tests/src/com/android/wm/shell/ShellTaskOrganizerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java
similarity index 100%
rename from libs/WindowManager/Shell/tests/src/com/android/wm/shell/ShellTaskOrganizerTests.java
rename to libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java
diff --git a/libs/WindowManager/Shell/tests/src/com/android/wm/shell/common/DisplayLayoutTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayLayoutTest.java
similarity index 100%
rename from libs/WindowManager/Shell/tests/src/com/android/wm/shell/common/DisplayLayoutTest.java
rename to libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayLayoutTest.java
diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp
index 892d43a..473dc53d 100644
--- a/libs/hwui/RecordingCanvas.cpp
+++ b/libs/hwui/RecordingCanvas.cpp
@@ -524,6 +524,7 @@
// Next greater multiple of SKLITEDL_PAGE.
fReserved = (fUsed + skip + SKLITEDL_PAGE) & ~(SKLITEDL_PAGE - 1);
fBytes.realloc(fReserved);
+ LOG_ALWAYS_FATAL_IF(fBytes.get() == nullptr, "realloc(%zd) failed", fReserved);
}
SkASSERT(fUsed + skip <= fReserved);
auto op = (T*)(fBytes.get() + fUsed);
diff --git a/libs/hwui/jni/Picture.cpp b/libs/hwui/jni/Picture.cpp
index d1b9521..8e4203c 100644
--- a/libs/hwui/jni/Picture.cpp
+++ b/libs/hwui/jni/Picture.cpp
@@ -111,7 +111,7 @@
SkPictureRecorder reRecorder;
- SkCanvas* canvas = reRecorder.beginRecording(mWidth, mHeight, NULL, 0);
+ SkCanvas* canvas = reRecorder.beginRecording(mWidth, mHeight);
mRecorder->partialReplay(canvas);
return reRecorder.finishRecordingAsPicture();
}
diff --git a/libs/hwui/renderthread/VulkanManager.cpp b/libs/hwui/renderthread/VulkanManager.cpp
index 0c5cf682..76ec078 100644
--- a/libs/hwui/renderthread/VulkanManager.cpp
+++ b/libs/hwui/renderthread/VulkanManager.cpp
@@ -361,20 +361,6 @@
mGetDeviceQueue(mDevice, mGraphicsQueueIndex, 0, &mGraphicsQueue);
mGetDeviceQueue(mDevice, mGraphicsQueueIndex, 1, &mAHBUploadQueue);
- // create the command pool for the command buffers
- if (VK_NULL_HANDLE == mCommandPool) {
- VkCommandPoolCreateInfo commandPoolInfo;
- memset(&commandPoolInfo, 0, sizeof(VkCommandPoolCreateInfo));
- commandPoolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
- // this needs to be on the render queue
- commandPoolInfo.queueFamilyIndex = mGraphicsQueueIndex;
- commandPoolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
- SkDEBUGCODE(VkResult res =)
- mCreateCommandPool(mDevice, &commandPoolInfo, nullptr, &mCommandPool);
- SkASSERT(VK_SUCCESS == res);
- }
- LOG_ALWAYS_FATAL_IF(mCommandPool == VK_NULL_HANDLE);
-
mGetDeviceQueue(mDevice, mPresentQueueIndex, 0, &mPresentQueue);
if (Properties::enablePartialUpdates && Properties::useBufferAge) {
diff --git a/libs/hwui/renderthread/VulkanManager.h b/libs/hwui/renderthread/VulkanManager.h
index 13335f3..75c05b8 100644
--- a/libs/hwui/renderthread/VulkanManager.h
+++ b/libs/hwui/renderthread/VulkanManager.h
@@ -165,7 +165,6 @@
VkQueue mAHBUploadQueue = VK_NULL_HANDLE;
uint32_t mPresentQueueIndex;
VkQueue mPresentQueue = VK_NULL_HANDLE;
- VkCommandPool mCommandPool = VK_NULL_HANDLE;
// Variables saved to populate VkFunctorInitParams.
static const uint32_t mAPIVersion = VK_MAKE_VERSION(1, 1, 0);
diff --git a/libs/hwui/tests/unit/SkiaCanvasTests.cpp b/libs/hwui/tests/unit/SkiaCanvasTests.cpp
index fcc64fd..f77ca2a 100644
--- a/libs/hwui/tests/unit/SkiaCanvasTests.cpp
+++ b/libs/hwui/tests/unit/SkiaCanvasTests.cpp
@@ -73,7 +73,7 @@
// Test picture recording.
SkPictureRecorder recorder;
- SkCanvas* skPicCanvas = recorder.beginRecording(1, 1, NULL, 0);
+ SkCanvas* skPicCanvas = recorder.beginRecording(1, 1);
SkiaCanvas picCanvas(skPicCanvas);
picCanvas.drawBitmap(*adobeBitmap, 0, 0, nullptr);
sk_sp<SkPicture> picture = recorder.finishRecordingAsPicture();
@@ -104,7 +104,7 @@
// Create a picture canvas.
SkPictureRecorder recorder;
- SkCanvas* skPicCanvas = recorder.beginRecording(1, 1, NULL, 0);
+ SkCanvas* skPicCanvas = recorder.beginRecording(1, 1);
SkiaCanvas picCanvas(skPicCanvas);
state = picCanvas.captureCanvasState();
diff --git a/media/java/android/media/MediaTranscodeManager.java b/media/java/android/media/MediaTranscodeManager.java
index e1bff03..4e2ae5c 100644
--- a/media/java/android/media/MediaTranscodeManager.java
+++ b/media/java/android/media/MediaTranscodeManager.java
@@ -36,7 +36,10 @@
import java.io.FileNotFoundException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
import java.util.Objects;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
@@ -94,11 +97,17 @@
TODO(hkuang): Clarify whether supports framerate conversion.
@hide
*/
-public final class MediaTranscodeManager {
+public final class MediaTranscodeManager implements AutoCloseable {
private static final String TAG = "MediaTranscodeManager";
private static final String MEDIA_TRANSCODING_SERVICE = "media.transcoding";
+ /** Maximum number of retry to connect to the service. */
+ private static final int CONNECT_SERVICE_RETRY_COUNT = 100;
+
+ /** Interval between trying to reconnect to the service. */
+ private static final int INTERVAL_CONNECT_SERVICE_RETRY_MS = 40;
+
/**
* Default transcoding type.
* @hide
@@ -117,6 +126,25 @@
*/
public static final int TRANSCODING_TYPE_IMAGE = 2;
+ @Override
+ public void close() throws Exception {
+ release();
+ }
+
+ /**
+ * Releases the MediaTranscodeManager.
+ */
+ //TODO(hkuang): add test for it.
+ private void release() throws Exception {
+ synchronized (mLock) {
+ if (mTranscodingClient != null) {
+ mTranscodingClient.unregister();
+ } else {
+ throw new UnsupportedOperationException("Failed to release");
+ }
+ }
+ }
+
/** @hide */
@IntDef(prefix = {"TRANSCODING_TYPE_"}, value = {
TRANSCODING_TYPE_UNKNOWN,
@@ -181,10 +209,12 @@
private final String mPackageName;
private final int mPid;
private final int mUid;
- private final ExecutorService mCallbackExecutor = Executors.newSingleThreadExecutor();
- private static MediaTranscodeManager sMediaTranscodeManager;
+ private final ExecutorService mExecutor = Executors.newSingleThreadExecutor();
private final HashMap<Integer, TranscodingJob> mPendingTranscodingJobs = new HashMap();
- @NonNull private ITranscodingClient mTranscodingClient;
+ private final Object mLock = new Object();
+ @GuardedBy("mLock")
+ @NonNull private ITranscodingClient mTranscodingClient = null;
+ private static MediaTranscodeManager sMediaTranscodeManager;
private void handleTranscodingFinished(int jobId, TranscodingResultParcel result) {
synchronized (mPendingTranscodingJobs) {
@@ -209,7 +239,7 @@
}
}
- private void handleTranscodingFailed(int jobId, int errorCodec) {
+ private void handleTranscodingFailed(int jobId, int errorCode) {
synchronized (mPendingTranscodingJobs) {
// Gets the job associated with the jobId and removes it from
// mPendingTranscodingJobs.
@@ -254,6 +284,98 @@
}
}
+ private static IMediaTranscodingService getService(boolean retry) {
+ int retryCount = !retry ? 1 : CONNECT_SERVICE_RETRY_COUNT;
+ Log.i(TAG, "get service with rety " + retryCount);
+ for (int count = 1; count <= retryCount; count++) {
+ Log.d(TAG, "Trying to connect to service. Try count: " + count);
+ IMediaTranscodingService service = IMediaTranscodingService.Stub.asInterface(
+ ServiceManager.getService(MEDIA_TRANSCODING_SERVICE));
+ if (service != null) {
+ return service;
+ }
+ try {
+ // Sleep a bit before retry.
+ Thread.sleep(INTERVAL_CONNECT_SERVICE_RETRY_MS);
+ } catch (InterruptedException ie) {
+ /* ignore */
+ }
+ }
+
+ throw new UnsupportedOperationException("Failed to connect to MediaTranscoding service");
+ }
+
+ /*
+ * Handle client binder died event.
+ * Upon receiving a binder died event of the client, we will do the following:
+ * 1) For the job that is running, notify the client that the job is failed with error code,
+ * so client could choose to retry the job or not.
+ * TODO(hkuang): Add a new error code to signal service died error.
+ * 2) For the jobs that is still pending or paused, we will resubmit the job internally once
+ * we successfully reconnect to the service and register a new client.
+ * 3) When trying to connect to the service and register a new client. The service may need time
+ * to reboot or never boot up again. So we will retry for a number of times. If we still
+ * could not connect, we will notify client job failure for the pending and paused jobs.
+ */
+ private void onClientDied() {
+ synchronized (mLock) {
+ mTranscodingClient = null;
+ }
+
+ // Delegates the job notification and retry to the executor as it may take some time.
+ mExecutor.execute(() -> {
+ // List to track the jobs that we want to retry.
+ List<TranscodingJob> retryJobs = new ArrayList<TranscodingJob>();
+
+ // First notify the client of job failure for all the running jobs.
+ synchronized (mPendingTranscodingJobs) {
+ for (Map.Entry<Integer, TranscodingJob> entry :
+ mPendingTranscodingJobs.entrySet()) {
+ TranscodingJob job = entry.getValue();
+
+ if (job.getStatus() == TranscodingJob.STATUS_RUNNING) {
+ job.updateStatusAndResult(TranscodingJob.STATUS_FINISHED,
+ TranscodingJob.RESULT_ERROR);
+
+ // Remove the job from pending jobs.
+ mPendingTranscodingJobs.remove(entry.getKey());
+
+ if (job.mListener != null && job.mListenerExecutor != null) {
+ Log.i(TAG, "Notify client job failed");
+ job.mListenerExecutor.execute(
+ () -> job.mListener.onTranscodingFinished(job));
+ }
+ } else if (job.getStatus() == TranscodingJob.STATUS_PENDING
+ || job.getStatus() == TranscodingJob.STATUS_PAUSED) {
+ // Add the job to retryJobs to handle them later.
+ retryJobs.add(job);
+ }
+ }
+ }
+
+ // Try to register with the service once it boots up.
+ IMediaTranscodingService service = getService(true /*retry*/);
+ boolean haveTranscodingClient = false;
+ if (service != null) {
+ synchronized (mLock) {
+ mTranscodingClient = registerClient(service);
+ if (mTranscodingClient != null) {
+ haveTranscodingClient = true;
+ }
+ }
+ }
+
+ for (TranscodingJob job : retryJobs) {
+ // Notify the job failure if we fails to connect to the service or fail
+ // to retry the job.
+ if (!haveTranscodingClient || !job.retry()) {
+ // TODO(hkuang): Return correct error code to the client.
+ handleTranscodingFailed(job.getJobId(), 0 /*unused */);
+ }
+ }
+ });
+ }
+
private void updateStatus(int jobId, int status) {
synchronized (mPendingTranscodingJobs) {
final TranscodingJob job = mPendingTranscodingJobs.get(jobId);
@@ -336,6 +458,30 @@
}
};
+ private ITranscodingClient registerClient(IMediaTranscodingService service)
+ throws UnsupportedOperationException {
+ synchronized (mLock) {
+ try {
+ // Registers the client with MediaTranscoding service.
+ mTranscodingClient = service.registerClient(
+ mTranscodingClientCallback,
+ mPackageName,
+ mPackageName,
+ IMediaTranscodingService.USE_CALLING_UID,
+ IMediaTranscodingService.USE_CALLING_PID);
+
+ if (mTranscodingClient != null) {
+ mTranscodingClient.asBinder().linkToDeath(() -> onClientDied(), /* flags */ 0);
+ }
+ return mTranscodingClient;
+ } catch (RemoteException re) {
+ Log.e(TAG, "Failed to register new client due to exception " + re);
+ mTranscodingClient = null;
+ }
+ }
+ throw new UnsupportedOperationException("Failed to register new client");
+ }
+
/* Private constructor. */
private MediaTranscodeManager(@NonNull Context context,
IMediaTranscodingService transcodingService) {
@@ -344,21 +490,17 @@
mPackageName = mContext.getPackageName();
mPid = Os.getuid();
mUid = Os.getpid();
-
- try {
- // Registers the client with MediaTranscoding service.
- mTranscodingClient = transcodingService.registerClient(
- mTranscodingClientCallback,
- mPackageName,
- mPackageName,
- IMediaTranscodingService.USE_CALLING_UID,
- IMediaTranscodingService.USE_CALLING_PID);
- } catch (RemoteException re) {
- Log.e(TAG, "Failed to register new client due to exception " + re);
- throw new UnsupportedOperationException("Failed to register new client");
- }
+ mTranscodingClient = registerClient(transcodingService);
}
+ @Override
+ protected void finalize() {
+ try {
+ release();
+ } catch (Exception ex) {
+ Log.e(TAG, "Failed to release");
+ }
+ }
public static final class TranscodingRequest {
/** Uri of the source media file. */
@@ -807,6 +949,16 @@
}
/**
+ * Resubmit the transcoding job to the service.
+ *
+ * @return true if successfully resubmit the job to the service. False otherwise.
+ */
+ public synchronized boolean retry() {
+ // TODO(hkuang): Implement this.
+ return true;
+ }
+
+ /**
* Cancels the transcoding job and notify the listener.
* If the job happened to finish before being canceled this call is effectively a no-op and
* will not update the result in that case.
@@ -879,9 +1031,15 @@
*/
public static MediaTranscodeManager getInstance(@NonNull Context context) {
// Acquires the MediaTranscoding service.
- IMediaTranscodingService service = IMediaTranscodingService.Stub.asInterface(
- ServiceManager.getService(MEDIA_TRANSCODING_SERVICE));
+ IMediaTranscodingService service = getService(false /*retry*/);
+ return getInstance(context, service);
+ }
+ /** Similar as above, but wait till the service is ready. */
+ @VisibleForTesting
+ public static MediaTranscodeManager getInstance(@NonNull Context context, boolean retry) {
+ // Acquires the MediaTranscoding service.
+ IMediaTranscodingService service = getService(retry);
return getInstance(context, service);
}
@@ -896,6 +1054,7 @@
sMediaTranscodeManager = new MediaTranscodeManager(context.getApplicationContext(),
transcodingService);
}
+
return sMediaTranscodeManager;
}
}
diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java
index 6c41f7b..549e793 100644
--- a/media/java/android/media/session/MediaSession.java
+++ b/media/java/android/media/session/MediaSession.java
@@ -103,6 +103,8 @@
* System only flag for a session that needs to have priority over all other
* sessions. This flag ensures this session will receive media button events
* regardless of the current ordering in the system.
+ * If there are two or more sessions with this flag, the last session that sets this flag
+ * will be the global priority session.
*
* @hide
*/
diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp
index 5770c67..5db6729 100644
--- a/media/jni/android_media_tv_Tuner.cpp
+++ b/media/jni/android_media_tv_Tuner.cpp
@@ -2060,7 +2060,7 @@
env->GetIntField(settings, env->GetFieldID(clazz, "mModulation", "I")));
FrontendInnerFec innerFec =
static_cast<FrontendInnerFec>(
- env->GetLongField(settings, env->GetFieldID(clazz, "mFec", "J")));
+ env->GetLongField(settings, env->GetFieldID(clazz, "mInnerFec", "J")));
uint32_t symbolRate =
static_cast<uint32_t>(
env->GetIntField(settings, env->GetFieldID(clazz, "mSymbolRate", "I")));
@@ -2069,7 +2069,7 @@
env->GetIntField(settings, env->GetFieldID(clazz, "mOuterFec", "I")));
FrontendDvbcAnnex annex =
static_cast<FrontendDvbcAnnex>(
- env->GetByteField(settings, env->GetFieldID(clazz, "mAnnex", "B")));
+ env->GetIntField(settings, env->GetFieldID(clazz, "mAnnex", "I")));
FrontendDvbcSpectralInversion spectralInversion =
static_cast<FrontendDvbcSpectralInversion>(
env->GetIntField(
diff --git a/media/tests/MediaTranscodingTest/Android.bp b/media/tests/MediaTranscodingTest/Android.bp
index fcf8f11..907c3c8 100644
--- a/media/tests/MediaTranscodingTest/Android.bp
+++ b/media/tests/MediaTranscodingTest/Android.bp
@@ -8,6 +8,7 @@
static_libs: [
"androidx.test.ext.junit",
"androidx.test.rules",
+ "androidx.test.uiautomator_uiautomator",
"android-support-test",
"testng"
],
diff --git a/media/tests/MediaTranscodingTest/src/com/android/mediatranscodingtest/MediaTranscodeManagerTest.java b/media/tests/MediaTranscodingTest/src/com/android/mediatranscodingtest/MediaTranscodeManagerTest.java
index 8fe1088..009a41e 100644
--- a/media/tests/MediaTranscodingTest/src/com/android/mediatranscodingtest/MediaTranscodeManagerTest.java
+++ b/media/tests/MediaTranscodingTest/src/com/android/mediatranscodingtest/MediaTranscodeManagerTest.java
@@ -23,15 +23,23 @@
import android.media.MediaTranscodeManager.TranscodingJob;
import android.media.MediaTranscodeManager.TranscodingRequest;
import android.net.Uri;
+import android.os.Bundle;
import android.os.FileUtils;
+import android.os.ParcelFileDescriptor;
import android.test.ActivityInstrumentationTestCase2;
import android.util.Log;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.uiautomator.UiDevice;
+
import org.junit.Test;
+import java.io.BufferedReader;
import java.io.File;
+import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
@@ -127,8 +135,9 @@
super.setUp();
mContext = getInstrumentation().getContext();
- mMediaTranscodeManager = MediaTranscodeManager.getInstance(mContext);
+ mMediaTranscodeManager = MediaTranscodeManager.getInstance(mContext, true /*retry*/);
assertNotNull(mMediaTranscodeManager);
+ androidx.test.InstrumentationRegistry.registerInstance(getInstrumentation(), new Bundle());
// Setup source HEVC file uri.
mSourceHEVCVideoUri = resourceToUri(mContext, R.raw.VideoOnlyHEVC, "VideoOnlyHEVC.mp4");
@@ -148,8 +157,6 @@
@Test
public void testTranscodingFromHevcToAvc() throws Exception {
- Log.d(TAG, "Starting: testMediaTranscodeManager");
-
Semaphore transcodeCompleteSemaphore = new Semaphore(0);
// Create a file Uri: file:///data/user/0/com.android.mediatranscodingtest/cache/temp.mp4
@@ -194,6 +201,7 @@
stats.mAveragePSNR >= PSNR_THRESHOLD);
}
+
@Test
public void testCancelTranscoding() throws Exception {
Log.d(TAG, "Starting: testMediaTranscodeManager");
@@ -300,5 +308,94 @@
assertTrue("Failed to receive at least 10 progress updates",
progressUpdateCount.get() > 10);
}
+
+ // [[ $(adb shell whoami) == "root" ]]
+ private boolean checkIfRoot() throws IOException {
+ try (ParcelFileDescriptor result = getInstrumentation().getUiAutomation()
+ .executeShellCommand("whoami");
+ BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(
+ new FileInputStream(result.getFileDescriptor())))) {
+ String line;
+ while ((line = bufferedReader.readLine()) != null) {
+ if (line.contains("root")) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private String executeShellCommand(String cmd) throws Exception {
+ return UiDevice.getInstance(
+ InstrumentationRegistry.getInstrumentation()).executeShellCommand(cmd);
+ }
+
+ @Test
+ public void testHandleTranscoderServiceDied() throws Exception {
+ try {
+ if (!checkIfRoot()) {
+ throw new AssertionError("must be root to run this test; try adb root?");
+ } else {
+ Log.i(TAG, "Device is root");
+ }
+ } catch (IOException e) {
+ throw new AssertionError(e);
+ }
+
+ Semaphore transcodeCompleteSemaphore = new Semaphore(0);
+ Semaphore jobStartedSemaphore = new Semaphore(0);
+
+ // Transcode a 15 seconds video, so that the transcoding is not finished when we kill the
+ // service.
+ Uri srcUri = Uri.parse(ContentResolver.SCHEME_FILE + "://"
+ + mContext.getCacheDir().getAbsolutePath() + "/longtest_15s.mp4");
+ Uri destinationUri = Uri.parse(ContentResolver.SCHEME_FILE + "://"
+ + mContext.getCacheDir().getAbsolutePath() + "/HevcTranscode.mp4");
+
+ TranscodingRequest request =
+ new TranscodingRequest.Builder()
+ .setSourceUri(mSourceHEVCVideoUri)
+ .setDestinationUri(destinationUri)
+ .setType(MediaTranscodeManager.TRANSCODING_TYPE_VIDEO)
+ .setPriority(MediaTranscodeManager.PRIORITY_REALTIME)
+ .setVideoTrackFormat(createMediaFormat())
+ .build();
+ Executor listenerExecutor = Executors.newSingleThreadExecutor();
+
+ Log.i(TAG, "transcoding to " + createMediaFormat());
+
+ TranscodingJob job = mMediaTranscodeManager.enqueueRequest(request, listenerExecutor,
+ transcodingJob -> {
+ Log.d(TAG, "Transcoding completed with result: " + transcodingJob.getResult());
+ assertEquals(transcodingJob.getResult(), TranscodingJob.RESULT_ERROR);
+ transcodeCompleteSemaphore.release();
+ });
+ assertNotNull(job);
+
+ AtomicInteger progressUpdateCount = new AtomicInteger(0);
+
+ // Set progress update executor and use the same executor as result listener.
+ job.setOnProgressUpdateListener(listenerExecutor,
+ new TranscodingJob.OnProgressUpdateListener() {
+ @Override
+ public void onProgressUpdate(int newProgress) {
+ if (newProgress > 0) {
+ jobStartedSemaphore.release();
+ }
+ }
+ });
+
+ // Wait for progress update so the job is in running state.
+ jobStartedSemaphore.tryAcquire(TRANSCODE_TIMEOUT_SECONDS, TimeUnit.SECONDS);
+ assertTrue("Job is not running", job.getStatus() == TranscodingJob.STATUS_RUNNING);
+
+ // Kills the service and expects receiving failure of the job.
+ executeShellCommand("pkill -f media.transcoding");
+
+ Log.d(TAG, "testMediaTranscodeManager - Waiting for transcode result.");
+ boolean finishedOnTime = transcodeCompleteSemaphore.tryAcquire(
+ TRANSCODE_TIMEOUT_SECONDS, TimeUnit.SECONDS);
+ assertTrue("Invalid job status", job.getStatus() == TranscodingJob.STATUS_FINISHED);
+ }
}
diff --git a/non-updatable-api/current.txt b/non-updatable-api/current.txt
index cfdb48b..e0ebec6 100644
--- a/non-updatable-api/current.txt
+++ b/non-updatable-api/current.txt
@@ -45992,6 +45992,7 @@
method public void onDataConnectionStateChanged(int);
method public void onDataConnectionStateChanged(int, int);
method @RequiresPermission("android.permission.READ_PHONE_STATE") public void onDisplayInfoChanged(@NonNull android.telephony.TelephonyDisplayInfo);
+ method public void onEmergencyNumberListChanged(@NonNull java.util.Map<java.lang.Integer,java.util.List<android.telephony.emergency.EmergencyNumber>>);
method @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public void onImsCallDisconnectCauseChanged(@NonNull android.telephony.ims.ImsReasonInfo);
method public void onMessageWaitingIndicatorChanged(boolean);
method @RequiresPermission("android.permission.MODIFY_PHONE_STATE") public void onPreciseDataConnectionStateChanged(@NonNull android.telephony.PreciseDataConnectionState);
diff --git a/non-updatable-api/system-current.txt b/non-updatable-api/system-current.txt
index 0cfad1c76..d1264df 100644
--- a/non-updatable-api/system-current.txt
+++ b/non-updatable-api/system-current.txt
@@ -9683,7 +9683,8 @@
public class PhoneStateListener {
method public void onCallAttributesChanged(@NonNull android.telephony.CallAttributes);
- method public void onOutgoingEmergencyCall(@NonNull android.telephony.emergency.EmergencyNumber);
+ method @Deprecated public void onOutgoingEmergencyCall(@NonNull android.telephony.emergency.EmergencyNumber);
+ method public void onOutgoingEmergencyCall(@NonNull android.telephony.emergency.EmergencyNumber, int);
method public void onOutgoingEmergencySms(@NonNull android.telephony.emergency.EmergencyNumber);
method @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public void onPreciseCallStateChanged(@NonNull android.telephony.PreciseCallState);
method public void onRadioPowerStateChanged(int);
diff --git a/packages/CarSystemUI/res/values/config.xml b/packages/CarSystemUI/res/values/config.xml
index 039f2c0..d3277de 100644
--- a/packages/CarSystemUI/res/values/config.xml
+++ b/packages/CarSystemUI/res/values/config.xml
@@ -121,7 +121,6 @@
<string-array name="config_systemUIServiceComponentsExclude" translatable="false">
<item>com.android.systemui.recents.Recents</item>
<item>com.android.systemui.volume.VolumeUI</item>
- <item>com.android.systemui.stackdivider.Divider</item>
<item>com.android.systemui.statusbar.phone.StatusBar</item>
<item>com.android.systemui.keyboard.KeyboardUI</item>
<item>com.android.systemui.pip.PipUI</item>
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java
index 797a178..3971e18 100644
--- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java
+++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java
@@ -34,7 +34,6 @@
import com.android.systemui.recents.Recents;
import com.android.systemui.recents.RecentsModule;
import com.android.systemui.shortcut.ShortcutKeyDispatcher;
-import com.android.systemui.stackdivider.Divider;
import com.android.systemui.statusbar.dagger.StatusBarModule;
import com.android.systemui.statusbar.notification.InstantAppNotifier;
import com.android.systemui.statusbar.notification.dagger.NotificationsModule;
@@ -42,6 +41,7 @@
import com.android.systemui.theme.ThemeOverlayController;
import com.android.systemui.toast.ToastUI;
import com.android.systemui.util.leak.GarbageMonitor;
+import com.android.systemui.wmshell.WMShell;
import dagger.Binds;
import dagger.Module;
@@ -59,12 +59,6 @@
@ClassKey(AuthController.class)
public abstract SystemUI bindAuthController(AuthController sysui);
- /** Inject into Divider. */
- @Binds
- @IntoMap
- @ClassKey(Divider.class)
- public abstract SystemUI bindDivider(Divider sysui);
-
/** Inject Car Navigation Bar. */
@Binds
@IntoMap
@@ -192,4 +186,10 @@
@IntoMap
@ClassKey(SideLoadedAppController.class)
public abstract SystemUI bindSideLoadedAppController(SideLoadedAppController sysui);
+
+ /** Inject into WMShell. */
+ @Binds
+ @IntoMap
+ @ClassKey(WMShell.class)
+ public abstract SystemUI bindWMShell(WMShell sysui);
}
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
index 290700f..3eea513 100644
--- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
+++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
@@ -47,7 +47,6 @@
import com.android.systemui.qs.tileimpl.QSFactoryImpl;
import com.android.systemui.recents.Recents;
import com.android.systemui.recents.RecentsImplementation;
-import com.android.systemui.stackdivider.DividerModule;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationLockscreenUserManagerImpl;
@@ -75,7 +74,6 @@
@Module(
includes = {
- DividerModule.class,
QSModule.class,
CarWMShellModule.class
})
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/SystemBarConfigs.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/SystemBarConfigs.java
index 143c444f..b8bf825 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/SystemBarConfigs.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/SystemBarConfigs.java
@@ -29,6 +29,8 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.R;
+import com.android.systemui.car.notification.BottomNotificationPanelViewMediator;
+import com.android.systemui.car.notification.TopNotificationPanelViewMediator;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
@@ -95,6 +97,7 @@
populateMaps();
readConfigs();
checkEnabledBarsHaveUniqueBarTypes();
+ checkSystemBarEnabledForNotificationPanel();
setInsetPaddingsForOverlappingCorners();
sortSystemBarSidesByZOrder();
}
@@ -221,6 +224,34 @@
}
}
+ private void checkSystemBarEnabledForNotificationPanel() throws RuntimeException {
+
+ String notificationPanelMediatorName =
+ mResources.getString(R.string.config_notificationPanelViewMediator);
+ if (notificationPanelMediatorName == null) {
+ return;
+ }
+
+ Class<?> notificationPanelMediatorUsed = null;
+ try {
+ notificationPanelMediatorUsed = Class.forName(notificationPanelMediatorName);
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ }
+
+ if (!mTopNavBarEnabled && notificationPanelMediatorUsed.isAssignableFrom(
+ TopNotificationPanelViewMediator.class)) {
+ throw new RuntimeException(
+ "Top System Bar must be enabled to use " + notificationPanelMediatorName);
+ }
+
+ if (!mBottomNavBarEnabled && notificationPanelMediatorUsed.isAssignableFrom(
+ BottomNotificationPanelViewMediator.class)) {
+ throw new RuntimeException("Bottom System Bar must be enabled to use "
+ + notificationPanelMediatorName);
+ }
+ }
+
private void setInsetPaddingsForOverlappingCorners() {
setInsetPaddingForOverlappingCorner(TOP, LEFT);
setInsetPaddingForOverlappingCorner(TOP, RIGHT);
@@ -277,7 +308,7 @@
}
private static boolean isHorizontalBar(@SystemBarSide int side) {
- return side == TOP || side == BOTTOM;
+ return side == TOP || side == BOTTOM;
}
private static boolean isVerticalBar(@SystemBarSide int side) {
diff --git a/packages/CarSystemUI/src/com/android/systemui/wm/DisplaySystemBarsController.java b/packages/CarSystemUI/src/com/android/systemui/wm/DisplaySystemBarsController.java
index e493c97..c7354ed 100644
--- a/packages/CarSystemUI/src/com/android/systemui/wm/DisplaySystemBarsController.java
+++ b/packages/CarSystemUI/src/com/android/systemui/wm/DisplaySystemBarsController.java
@@ -49,7 +49,7 @@
private final Context mContext;
private SparseArray<PerDisplay> mPerDisplaySparseArray;
- private DisplaySystemBarsController(
+ public DisplaySystemBarsController(
Context context,
IWindowManager wmService,
DisplayController displayController,
@@ -167,33 +167,4 @@
}
}
}
-
- /** Builds {@link DisplaySystemBarsController} instance. */
- public static class Builder {
- private Context mContext;
- private IWindowManager mWmService;
- private DisplayController mDisplayController;
- private Handler mHandler;
- private TransactionPool mTransactionPool;
-
- public Builder(Context context, IWindowManager wmService,
- DisplayController displayController, Handler handler,
- TransactionPool transactionPool) {
- mContext = context;
- mWmService = wmService;
- mDisplayController = displayController;
- mHandler = handler;
- mTransactionPool = transactionPool;
- }
-
- /** Builds and initializes {@link DisplaySystemBarsController} instance. */
- public DisplaySystemBarsController build() {
- DisplaySystemBarsController displaySystemBarsController =
- new DisplaySystemBarsController(
- mContext, mWmService, mDisplayController, mHandler, mTransactionPool);
- // Separates startMonitorDisplays from constructor to prevent circular init issue.
- displaySystemBarsController.startMonitorDisplays();
- return displaySystemBarsController;
- }
- }
}
diff --git a/packages/CarSystemUI/src/com/android/systemui/wmshell/CarWMShellModule.java b/packages/CarSystemUI/src/com/android/systemui/wmshell/CarWMShellModule.java
index 2324c3d..fd6685f 100644
--- a/packages/CarSystemUI/src/com/android/systemui/wmshell/CarWMShellModule.java
+++ b/packages/CarSystemUI/src/com/android/systemui/wmshell/CarWMShellModule.java
@@ -40,8 +40,8 @@
DisplayImeController provideDisplayImeController(Context context,
IWindowManager wmService, DisplayController displayController,
@Main Handler mainHandler, TransactionPool transactionPool) {
- return new DisplaySystemBarsController.Builder(context, wmService, displayController,
- mainHandler, transactionPool).build();
+ return new DisplaySystemBarsController(context, wmService, displayController,
+ mainHandler, transactionPool);
}
/** TODO(b/150319024): PipMenuActivity will move to a Window */
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/wm/DisplaySystemBarsControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/wm/DisplaySystemBarsControllerTest.java
index b65578d..391f75e 100644
--- a/packages/CarSystemUI/tests/src/com/android/systemui/wm/DisplaySystemBarsControllerTest.java
+++ b/packages/CarSystemUI/tests/src/com/android/systemui/wm/DisplaySystemBarsControllerTest.java
@@ -64,13 +64,13 @@
public void setUp() {
MockitoAnnotations.initMocks(this);
- mController = new DisplaySystemBarsController.Builder(
+ mController = new DisplaySystemBarsController(
mContext,
mIWindowManager,
mDisplayController,
mHandler,
mTransactionPool
- ).build();
+ );
}
@Test
diff --git a/packages/PrintSpooler/res/values-fa/strings.xml b/packages/PrintSpooler/res/values-fa/strings.xml
index 596947d..719fc92 100644
--- a/packages/PrintSpooler/res/values-fa/strings.xml
+++ b/packages/PrintSpooler/res/values-fa/strings.xml
@@ -31,7 +31,7 @@
<string name="template_all_pages" msgid="3322235982020148762">"همه <xliff:g id="PAGE_COUNT">%1$s</xliff:g> صفحه"</string>
<string name="template_page_range" msgid="428638530038286328">"محدوده <xliff:g id="PAGE_COUNT">%1$s</xliff:g> صفحه"</string>
<string name="pages_range_example" msgid="8558694453556945172">"مثلاً ۱—۵،۹،۷—۱۰"</string>
- <string name="print_preview" msgid="8010217796057763343">"پیشنمایش چاپ"</string>
+ <string name="print_preview" msgid="8010217796057763343">"پیشنمای چاپ"</string>
<string name="install_for_print_preview" msgid="6366303997385509332">"نصب نمایشگر PDF برای پیشنمایش"</string>
<string name="printing_app_crashed" msgid="854477616686566398">"برنامه چاپ خراب شد"</string>
<string name="generating_print_job" msgid="3119608742651698916">"در حال ایجاد کار چاپ"</string>
diff --git a/packages/PrintSpooler/res/values-uz/strings.xml b/packages/PrintSpooler/res/values-uz/strings.xml
index d17bce7..ea0a6ea 100644
--- a/packages/PrintSpooler/res/values-uz/strings.xml
+++ b/packages/PrintSpooler/res/values-uz/strings.xml
@@ -100,7 +100,7 @@
</string-array>
<string-array name="orientation_labels">
<item msgid="4061931020926489228">"Tik holat"</item>
- <item msgid="3199660090246166812">"Eniga"</item>
+ <item msgid="3199660090246166812">"Yotiq"</item>
</string-array>
<string name="print_write_error_message" msgid="5787642615179572543">"Faylga yozib bo‘lmadi"</string>
<string name="print_error_default_message" msgid="8602678405502922346">"Xatolik yuz berdi. Qaytadan urining."</string>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index f3b22d3..5fc311a 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -139,7 +139,7 @@
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"قدرت سیگنال Wi‑Fi کامل است."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"شبکه باز"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"شبکه ایمن"</string>
- <string name="process_kernel_label" msgid="950292573930336765">"سیستم عامل Android"</string>
+ <string name="process_kernel_label" msgid="950292573930336765">"سیستمعامل Android"</string>
<string name="data_usage_uninstalled_apps" msgid="1933665711856171491">"برنامههای حذف شده"</string>
<string name="data_usage_uninstalled_apps_users" msgid="5533981546921913295">"برنامهها و کاربران حذف شده"</string>
<string name="data_usage_ota" msgid="7984667793701597001">"بهروزرسانیهای سیستم"</string>
diff --git a/packages/SystemUI/README.md b/packages/SystemUI/README.md
index 68b9553..148fabb 100644
--- a/packages/SystemUI/README.md
+++ b/packages/SystemUI/README.md
@@ -88,11 +88,6 @@
Registers all the callbacks/listeners required to show the Volume dialog when
it should be shown.
-### [com.android.systemui.stackdivider.Divider](/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java)
-
-Shows the drag handle for the divider between two apps when in split screen
-mode.
-
### [com.android.systemui.status.phone.StatusBar](/packages/SystemUI/src/com/android/systemui/status/phone/StatusBar.java)
This shows the UI for the status bar and the notification shade it contains.
@@ -153,6 +148,10 @@
Biometric UI.
+### [com.android.systemui.wmshell.WMShell](/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java)
+
+Delegates SysUI events to WM Shell controllers.
+
---
* [Plugins](/packages/SystemUI/docs/plugins.md)
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index bac915d..316fa8a 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Hervat"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Kanselleer"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Deel"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Vee uit"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Skermopname is gekanselleer"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Skermopname is gestoor, tik om te sien"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Skermopname is uitgevee"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Kon nie skermopname uitvee nie"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Kon nie toestemmings kry nie"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Kon nie skermopname begin nie"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 43ab1d2..e2a4dc6 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"ከቆመበት ቀጥል"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"ይቅር"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"አጋራ"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"ሰርዝ"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"የማያ ገጽ ቀረጻ ተሰርዟል"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"የማያ ገጽ ቀረጻ ተቀምጧል፣ ለመመልከት መታ ያድርጉ"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"የማያ ገጽ ቀረጻ ተሰርዟል"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"የማያ ገጽ ቀረጻን መሰረዝ ላይ ስህተት"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"ፈቃዶችን ማግኘት አልተቻለም"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"የማያ ገጽ ቀረጻን መጀመር ላይ ስህተት"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index c68d088..b33c6c5 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"استئناف"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"إلغاء"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"مشاركة"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"حذف"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"تمّ إلغاء تسجيل الشاشة."</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"تمّ حفظ تسجيل الشاشة، انقر لعرضه."</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"تمّ حذف تسجيل الشاشة."</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"حدث خطأ أثناء حذف تسجيل الشاشة."</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"تعذّر الحصول على أذونات."</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"حدث خطأ في بدء تسجيل الشاشة"</string>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index d604fd4..5a3c659 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"ৰখোৱাৰ পৰা পুনৰ আৰম্ভ কৰক"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"বাতিল কৰক"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"শ্বেয়াৰ কৰক"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"মচক"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"স্ক্রীণ ৰেকৰ্ড কৰাটো বাতিল কৰা হ’ল"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"স্ক্রীণ ৰেকৰ্ডিং ছেভ কৰা হ’ল, চাবলৈ টিপক"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"স্ক্রীণ ৰেকৰ্ডিং মচা হ’ল"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"স্ক্রীণ ৰেকৰ্ডিং মচি থাকোঁতে কিবা আসোঁৱাহ হ’ল"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"অনুমতি পাব পৰা নগ\'ল"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"স্ক্রীন ৰেকৰ্ড কৰা আৰম্ভ কৰোঁতে আসোঁৱাহ হৈছে"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index b1df252..4aa4bda 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Davam edin"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Ləğv edin"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Paylaşın"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Silin"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Ekranın video çəkimi ləğv edildi"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Ekranın video çəkimi yadda saxlanıldı. Baxmaq üçün klikləyin"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Ekranın video çəkimi silindi"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Ekranın video çəkiminin silinməsi zamanı xəta baş verdi"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"İcazələr əldə edilmədi"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Ekranın yazılması ilə bağlı xəta"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index f3c4c6b..a9725f3 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Nastavi"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Otkaži"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Deli"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Izbriši"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Snimanje ekrana je otkazano"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Snimak ekrana je sačuvan, dodirnite da biste pregledali"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Snimak ekrana je izbrisan"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Došlo je do problema pri brisanju snimka ekrana"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Preuzimanje dozvola nije uspelo"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Greška pri pokretanju snimanja ekrana"</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 9c0eeb2..b4c5eba 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Узнавіць"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Скасаваць"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Абагуліць"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Выдаліць"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Запіс экрана скасаваны"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Запіс экрана захаваны. Націсніце, каб прагледзець"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Запіс экрана выдалены"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Памылка выдалення запісу экрана"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Не ўдалося атрымаць дазволы"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Памылка пачатку запісу экрана"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 3bf12ad..52e8286 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Възобновяване"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Отказ"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Споделяне"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Изтриване"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Записването на екрана е анулирано"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Записът на екрана е запазен. Докоснете, за да го видите"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Записът на екрана е изтрит"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"При изтриването на записа на екрана възникна грешка"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Извличането на разрешенията не бе успешно."</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"При стартирането на записа на екрана възникна грешка"</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 5b7c953..d0de9cf 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"আবার চালু করুন"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"বাতিল করুন"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"শেয়ার করুন"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"মুছুন"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"স্ক্রিন রেকর্ডিং বাতিল করা হয়েছে"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"স্ক্রিন রেকর্ডিং সেভ করা হয়েছে, দেখতে ট্যাপ করুন"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"স্ক্রিন রেকর্ডিং মুছে ফেলা হয়েছে"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"স্ক্রিন রেকডিং মুছে ফেলার সময় সমস্যা হয়েছে"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"অনুমতি পাওয়া যায়নি"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"স্ক্রিন রেকর্ডিং শুরু করার সময় সমস্যা হয়েছে"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 31f88c8f..57b7945 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Nastavi"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Otkaži"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Dijeli"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Izbriši"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Snimanje ekrana je otkazano"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Snimak ekrana je sačuvan. Dodirnite za prikaz."</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Snimak ekrana je izbrisan"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Greška prilikom brisanja snimka ekrana"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Dobijanje odobrenja nije uspjelo"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Greška pri pokretanju snimanja ekrana"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 753e25f..0489d18 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Reprèn"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Cancel·la"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Comparteix"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Suprimeix"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"S\'ha cancel·lat la gravació de la pantalla"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"S\'ha desat la gravació de la pantalla; toca per mostrar"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"S\'ha suprimit la gravació de la pantalla"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"S\'ha produït un error en suprimir la gravació de la pantalla"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"No s\'han pogut obtenir els permisos"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"S\'ha produït un error en iniciar la gravació de pantalla"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 039500d..121a81d 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Obnovit"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Zrušit"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Sdílet"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Smazat"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Nahrávání obrazovky bylo zrušeno"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Záznam obrazovky byl uložen, zobrazíte jej klepnutím"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Záznam obrazovky byl smazán"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Při mazání záznamu obrazovky došlo k chybě"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Nepodařilo se načíst oprávnění"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Při spouštění nahrávání obrazovky došlo k chybě"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 0c8a5b7..8863695 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Genoptag"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Annuller"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Del"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Slet"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Skærmoptagelsen er annulleret"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Skærmoptagelsen er gemt. Tryk for at se den."</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Skærmoptagelsen er slettet"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Der opstod en fejl ved sletning af skærmoptagelsen"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Det lykkedes ikke et hente tilladelserne"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Skærmoptagelsen kunne ikke startes"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 1c4c7ab..8d990c6 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Fortsetzen"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Abbrechen"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Teilen"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Löschen"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Bildschirmaufzeichnung abgebrochen"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Bildschirmaufzeichnung gespeichert, zum Ansehen tippen"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Bildschirmaufzeichnung gelöscht"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Fehler beim Löschen der Bildschirmaufzeichnung"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Berechtigungen nicht erhalten"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Fehler beim Start der Bildschirmaufzeichnung"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 07ff807..4384749 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Συνέχιση"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Ακύρωση"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Κοινοποίηση"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Διαγραφή"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Η εγγραφή οθόνης ακυρώθηκε"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Η εγγραφή οθόνης αποθηκεύτηκε. Πατήστε για προβολή."</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Η εγγραφή οθόνης διαγράφηκε"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Παρουσιάστηκε σφάλμα κατά τη διαγραφή της εγγραφής οθόνης"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Η λήψη αδειών απέτυχε"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Σφάλμα κατά την έναρξη της εγγραφής οθόνης"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 0e22b58..8a7963a 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Resume"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Cancel"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Share"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Delete"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Screen recording cancelled"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Screen recording saved, tap to view"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Screen recording deleted"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Error deleting screen recording"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Failed to get permissions"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Error starting screen recording"</string>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index acf087d..7b2b25a 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Resume"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Cancel"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Share"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Delete"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Screen recording cancelled"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Screen recording saved, tap to view"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Screen recording deleted"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Error deleting screen recording"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Failed to get permissions"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Error starting screen recording"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 0e22b58..8a7963a 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Resume"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Cancel"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Share"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Delete"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Screen recording cancelled"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Screen recording saved, tap to view"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Screen recording deleted"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Error deleting screen recording"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Failed to get permissions"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Error starting screen recording"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 0e22b58..8a7963a 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Resume"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Cancel"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Share"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Delete"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Screen recording cancelled"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Screen recording saved, tap to view"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Screen recording deleted"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Error deleting screen recording"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Failed to get permissions"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Error starting screen recording"</string>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index 4f4238a..15738f2 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Resume"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Cancel"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Share"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Delete"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Screen recording canceled"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Screen recording saved, tap to view"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Screen recording deleted"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Error deleting screen recording"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Failed to get permissions"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Error starting screen recording"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 38fa528..aa81ab8 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Reanudar"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Cancelar"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Compartir"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Borrar"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Se canceló la grabación de pantalla"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Se guardó la grabación de pantalla; presiona para verla"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Se borró la grabación de pantalla"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Error al borrar la grabación de pantalla"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Error al obtener permisos"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Error al iniciar la grabación de pantalla"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 10aa6ca..8638570 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Seguir"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Cancelar"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Compartir"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Eliminar"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Se ha cancelado la grabación de la pantalla"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Se ha guardado la grabación de la pantalla; toca para verla"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Se ha eliminado la grabación de la pantalla"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"No se ha podido eliminar la grabación de la pantalla"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"No se han podido obtener los permisos"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"No se ha podido empezar a grabar la pantalla"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 9122ce5..f5ffad2 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Jätka"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Tühista"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Jaga"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Kustuta"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Ekraanikuva salvestamine on tühistatud"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Ekraanikuva salvestis on salvestatud, puudutage vaatamiseks"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Ekraanikuva salvestis on kustutatud"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Viga ekraanikuva salvestise kustutamisel"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Lubade hankimine ebaõnnestus"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Viga ekraanikuva salvestamise alustamisel"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 38b2103d..1d5ac1a 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Berrekin"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Utzi"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Partekatu"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Ezabatu"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Utzi zaio pantaila grabatzeari"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Gorde da pantailaren grabaketa; sakatu ikusteko"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Ezabatu da pantailaren grabaketa"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Errore bat gertatu da pantailaren grabaketa ezabatzean"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Ezin izan dira lortu baimenak"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Errore bat gertatu da pantaila grabatzen hastean"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index d39d0c3..55d8ab2 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"ازسرگیری"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"لغو"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"همرسانی"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"حذف"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"ضبط صفحهنمایش لغو شد"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"ضبط صفحهنمایش ذخیره شد، برای مشاهده ضربه بزنید"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"فایل ضبط صفحهنمایش حذف شد"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"خطا در حذف فایل ضبط صفحهنمایش"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"مجوزها دریافت نشدند"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"خطا هنگام شروع ضبط صفحهنمایش"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 52e5e8c..f30c44b 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Jatka"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Peruuta"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Jaa"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Poista"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Näytön tallennus peruutettu"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Näyttötallenne tallennettu, katso napauttamalla"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Näyttötallenne poistettu"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Virhe poistettaessa näyttötallennetta"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Käyttöoikeuksien hakeminen epäonnistui."</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Virhe näytön tallennuksen aloituksessa"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 4797f32..f6196dd63 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Reprendre"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Annuler"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Partager"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Supprimer"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"L\'enregistrement d\'écran a été annulé"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"L\'enregistrement d\'écran est terminé. Touchez ici pour l\'afficher."</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"L\'enregistrement d\'écran a été supprimé"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Une erreur s\'est produite lors de la suppression de l\'enregistrement d\'écran"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Impossible d\'obtenir les autorisations"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Une erreur s\'est produite lors du démarrage de l\'enregistrement d\'écran"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index e5df728..0146ce4 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Reprendre"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Annuler"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Partager"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Supprimer"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Enregistrement de l\'écran annulé"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Enregistrement de l\'écran enregistré. Appuyez pour afficher"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Enregistrement de l\'écran supprimé"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Erreur lors de la suppression de l\'enregistrement de l\'écran"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Échec d\'obtention des autorisations"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Erreur lors du démarrage de l\'enregistrement de l\'écran"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 246fefd..fd4d3c6 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Retomar"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Cancelar"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Compartir"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Eliminar"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Cancelouse a gravación de pantalla"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Gardouse a gravación de pantalla; toca esta notificación para visualizala"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Eliminouse a gravación de pantalla"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Produciuse un erro ao eliminar a gravación de pantalla"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Produciuse un erro ao obter os permisos"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Produciuse un erro ao iniciar a gravación da pantalla"</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index beaacaa..46f7a2b 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"ફરી શરૂ કરો"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"રદ કરો"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"શેર કરો"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"ડિલીટ કરો"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"સ્ક્રીન રેકોર્ડિંગ રદ કર્યું"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"સ્ક્રીન રેકોર્ડિંગ સાચવ્યું, જોવા માટે ટૅપ કરો"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"સ્ક્રીન રેકોર્ડિંગ ડિલીટ કર્યું"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"સ્ક્રીન રેકોર્ડિંગ ડિલીટ કરવામાં ભૂલ આવી"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"પરવાનગીઓ મેળવવામાં નિષ્ફળ રહ્યાં"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"સ્ક્રીનને રેકૉર્ડ કરવાનું શરૂ કરવામાં ભૂલ"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index de4fc48..e4a6ed7 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"फिर से शुरू करें"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"रद्द करें"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"शेयर करें"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"मिटाएं"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"स्क्रीन रिकॉर्डिंग रद्द कर दी गई"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"स्क्रीन रिकॉर्डिंग सेव की गई, देखने के लिए टैप करें"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"स्क्रीन रिकॉर्डिंग मिटा दी गई"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"स्क्रीन रिकॉर्डिंग मिटाने में गड़बड़ी हुई"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"मंज़ूरी नहीं मिल सकी"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"स्क्रीन को रिकॉर्ड करने में गड़बड़ी आ रही है"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 7bf0b93..a27b066 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Nastavi"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Odustani"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Dijeli"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Izbriši"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Snimanje zaslona otkazano"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Snimanje zaslona spremljeno je, dodirnite da biste ga pregledali"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Snimanje zaslona izbrisano"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Pogreška prilikom brisanja snimanja zaslona"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Dohvaćanje dopuštenja nije uspjelo"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Pogreška prilikom pokretanja snimanja zaslona"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 875a05f..0d1f50a 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Folytatás"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Mégse"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Megosztás"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Törlés"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"A képernyő rögzítése megszakítva"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Képernyőfelvétel mentve, koppintson a megtekintéshez"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"A képernyőről készült felvétel törölve"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Hiba történt a képernyőről készült felvétel törlésekor"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Nincs engedély"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Hiba a képernyőrögzítés indításakor"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 4cc406b..f9a10fa 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Վերսկսել"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Չեղարկել"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Կիսվել"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Ջնջել"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Էկրանի տեսագրումը չեղարկվեց"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Էկրանի տեսագրությունը պահվեց։ Հպեք՝ դիտելու համար:"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Էկրանի տեսագրությունը ջնջվեց"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Չհաջողվեց ջնջել տեսագրությունը"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Չհաջողվեց ստանալ անհրաժեշտ թույլտվությունները"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Չհաջողվեց սկսել տեսագրումը"</string>
@@ -337,7 +335,7 @@
<string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Էկրանը կողպված է ուղղաձիգ դիրքավորմամբ:"</string>
<string name="accessibility_rotation_lock_off_changed" msgid="5772498370935088261">"Էկրանն այժմ ավտոմատ կպտտվի:"</string>
<string name="accessibility_rotation_lock_on_landscape_changed" msgid="5785739044300729592">"Էկրանն այժմ կողպված է հորիզոնական դիրքում:"</string>
- <string name="accessibility_rotation_lock_on_portrait_changed" msgid="5580170829728987989">"Էկրանն այժմ կողպված է ուղղահայաց դիրքում:"</string>
+ <string name="accessibility_rotation_lock_on_portrait_changed" msgid="5580170829728987989">"Էկրանն այժմ կողպված է ուղղաձիգ դիրքում:"</string>
<string name="dessert_case" msgid="9104973640704357717">"Dessert Case"</string>
<string name="start_dreams" msgid="9131802557946276718">"Էկրանապահ"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 5f7dce4..f65be90 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Lanjutkan"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Batal"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Bagikan"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Hapus"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Rekaman layar dibatalkan"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Rekaman layar disimpan, ketuk untuk melihat"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Rekaman layar dihapus"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Error saat menghapus rekaman layar"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Gagal mendapatkan izin"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Terjadi error saat memulai perekaman layar"</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index b5f6e57..66c9147 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Halda áfram"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Hætta við"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Deila"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Eyða"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Hætt við skjáupptöku"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Skjáupptaka vistuð, ýttu til að skoða"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Skjáupptöku eytt"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Villa við að eyða skjáupptöku"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Ekki tókst að fá heimildir"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Villa við að hefja upptöku skjás"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index f4453b7..b0e64a2 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Riprendi"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Annulla"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Condividi"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"CANC"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Registrazione dello schermo annullata"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Registrazione dello schermo salvata. Tocca per visualizzarla."</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Registrazione dello schermo eliminata"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Errore durante l\'eliminazione della registrazione dello schermo"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Impossibile ottenere le autorizzazioni"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Errore durante l\'avvio della registrazione dello schermo"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 161fedc..92fa09b 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"המשך"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"ביטול"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"שיתוף"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"מחיקה"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"הקלטת המסך בוטלה"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"הקלטת המסך נשמרה, יש להקיש כדי להציג"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"הקלטת המסך נמחקה"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"שגיאה במחיקת הקלטת המסך"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"קבלת ההרשאות נכשלה"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"שגיאה בהפעלה של הקלטת המסך"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index fa9c040..e427c8f 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"再開"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"キャンセル"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"共有"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"削除"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"画面の録画をキャンセルしました"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"画面の録画を保存しました。タップで表示できます"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"画面の録画を削除しました"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"画面の録画の削除中にエラーが発生しました"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"権限を取得できませんでした"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"画面の録画中にエラーが発生しました"</string>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index a3ddf70..b86bf8c 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"გაგრძელება"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"გაუქმება"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"გაზიარება"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"წაშლა"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"ეკრანის ჩაწერა გაუქმდა"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"ეკრანის ჩანაწერი შენახულია, შეეხეთ სანახავად"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"ეკრანის ჩანაწერი წაიშალა"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"ეკრანის ჩანაწერის წაშლისას წარმოიშვა შეცდომა"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"ნებართვების მიღება ვერ მოხერხდა"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"ეკრანის ჩაწერის დაწყებისას წარმოიქმნა შეცდომა"</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 0d3f7f9..1adaf2b 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Жалғастыру"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Бас тарту"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Бөлісу"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Жою"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Экранды бейнеге жазудан бас тартылды"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Экран бейне жазбасы сақталды, көру үшін түртіңіз"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Экран бейне жазбасы жойылды"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Экран бейне жазбасын жою кезінде қате кетті"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Рұқсаттар алынбады"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Экрандағы бейнені жазу кезінде қате шықты."</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 5abd740..961a37b 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"បន្ត"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"បោះបង់"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"ចែករំលែក"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"លុប"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"បានបោះបង់ការថតសកម្មភាពអេក្រង់"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"បានរក្សាទុកការថតសកម្មភាពអេក្រង់។ សូមចុចដើម្បីមើល"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"បានលុបការថតសកម្មភាពអេក្រង់"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"មានបញ្ហាក្នុងការលុបការថតសកម្មភាពអេក្រង់"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"មិនអាចទទួលបានការអនុញ្ញាតទេ"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"មានបញ្ហាក្នុងការចាប់ផ្ដើមថតអេក្រង់"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index 47f2385..7ec6a9f 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"ಮುಂದುವರಿಸಿ"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"ರದ್ದುಮಾಡಿ"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"ಹಂಚಿಕೊಳ್ಳಿ"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"ಅಳಿಸಿ"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಅನ್ನು ರದ್ದುಮಾಡಲಾಗಿದೆ"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಅನ್ನು ಉಳಿಸಲಾಗಿದೆ, ವೀಕ್ಷಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಅಳಿಸಲಾಗಿದೆ"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಅಳಿಸುವಾಗ ದೋಷ ಕಂಡುಬಂದಿದೆ"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"ಅನುಮತಿಗಳನ್ನು ಪಡೆಯುವಲ್ಲಿ ವಿಫಲವಾಗಿದೆ"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಪ್ರಾರಂಭಿಸುವಾಗ ದೋಷ ಕಂಡುಬಂದಿದೆ"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index beb7eda..840a98e 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"재개"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"취소"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"공유"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"삭제"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"화면 녹화가 취소되었습니다."</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"화면 녹화본이 저장되었습니다. 확인하려면 탭하세요."</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"화면 녹화가 삭제되었습니다."</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"화면 녹화는 삭제하는 중에 오류가 발생했습니다."</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"권한을 확보하지 못했습니다."</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"화면 녹화 시작 중 오류 발생"</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 4fbb09e..14ee566 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Улантуу"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Жокко чыгаруу"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Бөлүшүү"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Ооба"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Экранды жаздыруу жокко чыгарылды"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Экранды жаздыруу сакталды, көрүү үчүн таптап коюңуз"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Экранды жаздыруу өчүрүлдү"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Экранды жаздырууну өчүрүүдө ката кетти"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Уруксаттар алынбай калды"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Экранды жаздырууну баштоодо ката кетти"</string>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 6d7feab..553d0da 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"ສືບຕໍ່"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"ຍົກເລີກ"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"ແບ່ງປັນ"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"ລຶບ"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"ຍົກເລີກການບັນທຶກໜ້າຈໍແລ້ວ"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"ຈັດເກັບການບັນທຶກໜ້າຈໍ, ແຕະເພື່ອເບິ່ງ"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"ລຶບການບັນທຶກໜ້າຈໍອອກແລ້ວ"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"ເກີດຄວາມຜິດພາດໃນການລຶບການບັນທຶກໜ້າຈໍ"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"ໂຫຼດສິດອະນຸຍາດບໍ່ສຳເລັດ"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"ເກີດຄວາມຜິດພາດໃນການບັນທຶກໜ້າຈໍ"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 21217a0..28d6e6b 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Tęsti"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Atšaukti"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Bendrinti"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Ištrinti"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Ekrano įrašymas atšauktas"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Ekrano įrašas išsaugotas, palieskite ir peržiūrėkite"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Ekrano įrašas ištrintas"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Ištrinant ekrano įrašą įvyko klaida"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Nepavyko gauti leidimų"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Pradedant ekrano vaizdo įrašymą iškilo problema"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 4945dfa..223a57f 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Atsākt"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Atcelt"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Kopīgot"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Dzēst"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Ekrāna ierakstīšana ir atcelta."</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Ekrāna ieraksts ir saglabāts. Pieskarieties, lai to skatītu."</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Ekrāna ieraksts ir izdzēsts."</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Dzēšot ekrāna ierakstu, radās kļūda."</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Neizdevās iegūt atļaujas."</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Sākot ierakstīt ekrāna saturu, radās kļūda."</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 40d4698..a591031 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Продолжи"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Откажи"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Сподели"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Избриши"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Снимањето екран е откажано"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Снимката од екранот е зачувана, допрете за да ја видите"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Снимката од екранот е избришана"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Грешка при бришењето на снимката од екранот"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Не успеаја да се добијат дозволи"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Грешка при почетокот на снимањето на екранот"</string>
@@ -667,7 +665,7 @@
<string name="tuner_warning_title" msgid="7721976098452135267">"Забава за некои, но не за сите"</string>
<string name="tuner_warning" msgid="1861736288458481650">"Адаптерот на УИ на системот ви дава дополнителни начини за дотерување и приспособување на корисничкиот интерфејс на Android. Овие експериментални функции можеби ќе се изменат, расипат или ќе исчезнат во следните изданија. Продолжете со претпазливост."</string>
<string name="tuner_persistent_warning" msgid="230466285569307806">"Овие експериментални функции можеби ќе се изменат, расипат или ќе исчезнат во следните изданија. Продолжете со претпазливост."</string>
- <string name="got_it" msgid="477119182261892069">"Разбрав"</string>
+ <string name="got_it" msgid="477119182261892069">"Сфатив"</string>
<string name="tuner_toast" msgid="3812684836514766951">"Честито! Го додадовте Адаптерот на УИ на системот на Поставки"</string>
<string name="remove_from_settings" msgid="633775561782209994">"Отстрани од поставки"</string>
<string name="remove_from_settings_prompt" msgid="551565437265615426">"Да се отстрани Адаптерот на УИ на системот од Поставки и да престанат да се користат сите негови функции?"</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index c3bd65e..47d220d 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"പുനരാരംഭിക്കുക"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"റദ്ദാക്കുക"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"പങ്കിടുക"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"ഇല്ലാതാക്കുക"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"സ്ക്രീൻ റെക്കോർഡിംഗ് റദ്ദാക്കി"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"സ്ക്രീൻ റെക്കോർഡിംഗ് സംരക്ഷിച്ചു, കാണാൻ ടാപ്പ് ചെയ്യുക"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"സ്ക്രീൻ റെക്കോർഡിംഗ് ഇല്ലാതാക്കി"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"സ്ക്രീൻ റെക്കോർഡിംഗ് ഇല്ലാതാക്കുന്നതിൽ പിശക്"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"അനുമതികൾ ലഭിച്ചില്ല"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"സ്ക്രീൻ റെക്കോർഡിംഗ് ആരംഭിക്കുന്നതിൽ പിശക്"</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 5f08f05..202f292 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Үргэлжлүүлэх"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Цуцлах"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Хуваалцах"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Устгах"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Дэлгэцийн бичлэгийг цуцалсан"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Дэлгэцийн бичлэгийг хадгалсан. Харахын тулд товшино уу"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Дэлгэцийн бичлэгийг устгасан"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Дэлгэцийн бичлэгийг устгахад алдаа гарлаа"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Зөвшөөрөл авч чадсангүй"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Дэлгэцийн бичлэгийг эхлүүлэхэд алдаа гарлаа"</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 6d525df..e412072 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"पुन्हा सुरू करा"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"रद्द करा"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"शेअर करा"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"हटवा"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"स्क्रीन रेकॉर्डिंग रद्द केले"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"स्क्रीन रेकॉर्डिंग सेव्ह केली, पाहण्यासाठी टॅप करा"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"स्क्रीन रेकॉर्डिंग हटवले"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"स्क्रीन रेकॉर्डिंग हटवताना एरर आली"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"परवानग्या मिळवता आल्या नाहीत"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"स्क्रीन रेकॉर्डिंग सुरू करताना एरर आली"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 4f832e4..d01ab8c 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Sambung semula"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Batal"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Kongsi"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Padam"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Rakaman skrin dibatalkan"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Rakaman skrin disimpan, ketik untuk melihat"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Rakaman skrin dipadamkan"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Ralat semasa memadamkan rakaman skrin"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Gagal mendapatkan kebenaran"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Ralat semasa memulakan rakaman skrin"</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 150ed94e..83272f2 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"ဆက်လုပ်ရန်"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"မလုပ်တော့"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"မျှဝေရန်"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"ဖျက်ရန်"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"ဖန်သားပြင် ရိုက်ကူးမှု ပယ်ဖျက်လိုက်ပါပြီ"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"ဖန်သားပြင် ရိုက်ကူးမှု သိမ်းထားသည်၊ ကြည့်ရန် တို့ပါ"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"ဖန်သားပြင် ရိုက်ကူးမှု ဖျက်ပြီးပါပြီ"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"ဖန်သားပြင် ရိုက်ကူးမှု ဖျက်ရာတွင် အမှားအယွင်းရှိနေသည်"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"ခွင့်ပြုချက် မရယူနိုင်ပါ"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"ဖန်သားပြင် ရိုက်ကူးမှု စတင်ရာတွင် အမှားအယွင်းရှိနေသည်"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 849c2e9..01859ef 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Gjenoppta"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Avbryt"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Del"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Slett"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Skjermopptak er avbrutt"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Skjermopptaket er lagret. Trykk for å se det"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Skjermopptaket er slettet"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Feil ved sletting av skjermopptaket"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Kunne ikke få tillatelser"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Feil ved start av skjermopptaket"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 2ac442e..e548a96 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"जारी राख्नुहोस्"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"रद्द गर्नुहोस्"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"सेयर गर्नुहोस्"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"मेट्नुहोस्"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"स्क्रिन रेकर्ड गर्ने कार्य रद्द गरियो"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"स्क्रिन रेकर्डिङ सुरक्षित गरियो, हेर्न ट्याप गर्नुहोस्"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"स्क्रिनको रेकर्डिङ मेटाइयो"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"स्क्रिनको रेकर्डिङ मेट्ने क्रममा त्रुटि"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"अनुमति प्राप्त गर्न सकिएन"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"स्क्रिन रेकर्ड गर्न थाल्ने क्रममा त्रुटि भयो"</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index da0f427..fa028c3 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Hervatten"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Annuleren"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Delen"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Verwijderen"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Schermopname geannuleerd"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Schermopname opgeslagen, tik om te bekijken"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Schermopname verwijderd"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Fout bij verwijderen van schermopname"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Kan rechten niet ophalen"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Fout bij starten van schermopname"</string>
@@ -354,7 +352,7 @@
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string>
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Invoer"</string>
- <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="3003338571871392293">"Gehoorapparaten"</string>
+ <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="3003338571871392293">"Hoortoestellen"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Inschakelen..."</string>
<string name="quick_settings_brightness_label" msgid="680259653088849563">"Helderheid"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automatisch draaien"</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 029aa69..4c6ef48 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"ପୁଣି ଚାଲୁ କରନ୍ତୁ"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"ବାତିଲ୍ କରନ୍ତୁ"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"ସେୟାର୍ କରନ୍ତୁ"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"ଡିଲିଟ୍ କରନ୍ତୁ"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"ସ୍କ୍ରିନ୍ ରେକର୍ଡିଂ ବାତିଲ୍ କରିଦିଆଯାଇଛି"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"ସ୍କ୍ରିନ୍ ରେକର୍ଡିଂ ସେଭ୍ ହୋଇଛି, ଦେଖିବାକୁ ଟାପ୍ କରନ୍ତୁ"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"ସ୍କ୍ରିନ୍ ରେକର୍ଡିଂ ଡିଲିଟ୍ କରିଦିଆଯାଇଛି"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"ସ୍କ୍ରିନ୍ ରେକର୍ଡିଂ ଡିଲିଟ୍ କରିବାରେ ତ୍ରୁଟି"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"ଅନୁମତି ପାଇବାରେ ଅସଫଳ ହେଲା।"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"ସ୍କ୍ରିନ୍ ରେକର୍ଡିଂ ଆରମ୍ଭ କରିବାରେ ତ୍ରୁଟି"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index ed5f40c..98583c0 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"ਮੁੜ-ਚਾਲੂ ਕਰੋ"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"ਰੱਦ ਕਰੋ"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"ਸਾਂਝਾ ਕਰੋ"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"ਮਿਟਾਓ"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"ਸਕ੍ਰੀਨ ਦੀ ਰਿਕਾਰਡਿੰਗ ਰੱਦ ਕੀਤੀ ਗਈ"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਿੰਗ ਰੱਖਿਅਤ ਕੀਤੀ ਗਈ, ਦੇਖਣ ਲਈ ਟੈਪ ਕਰੋ"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਿੰਗ ਨੂੰ ਮਿਟਾਇਆ ਗਿਆ"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਿੰਗ ਨੂੰ ਮਿਟਾਉਣ ਦੌਰਾਨ ਗੜਬੜ ਹੋਈ"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"ਇਜਾਜ਼ਤਾਂ ਪ੍ਰਾਪਤ ਕਰਨਾ ਅਸਫਲ ਰਿਹਾ"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਿੰਗ ਨੂੰ ਸ਼ੁਰੂ ਕਰਨ ਵੇਲੇ ਗੜਬੜ ਹੋਈ"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index ba30ced..4d5a2ae 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Wznów"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Anuluj"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Udostępnij"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Usuń"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Anulowano nagrywanie zawartości ekranu"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Zapisano nagranie zawartości ekranu – kliknij, by je obejrzeć"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Usunięto nagranie zawartości ekranu"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Błąd podczas usuwania nagrania zawartości ekranu"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Nie udało się uzyskać uprawnień"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Błąd podczas rozpoczynania rejestracji zawartości ekranu"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 715b0e4..ef5c9ce 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Retomar"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Cancelar"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Compartilhar"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Excluir"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Gravação de tela cancelada"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Gravação de tela salva, toque para ver"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Gravação de tela excluída"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Erro ao excluir a gravação de tela"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Não foi possível acessar as permissões"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Erro ao iniciar a gravação de tela"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 1a59de4..541f12c 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Retomar"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Cancelar"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Partilhar"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Eliminar"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Gravação de ecrã cancelada."</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Gravação de ecrã guardada. Toque para ver."</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Gravação de ecrã eliminada."</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Erro ao eliminar a gravação de ecrã."</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Falha ao obter as autorizações."</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Ocorreu um erro ao iniciar a gravação do ecrã."</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 715b0e4..ef5c9ce 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Retomar"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Cancelar"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Compartilhar"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Excluir"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Gravação de tela cancelada"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Gravação de tela salva, toque para ver"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Gravação de tela excluída"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Erro ao excluir a gravação de tela"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Não foi possível acessar as permissões"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Erro ao iniciar a gravação de tela"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index cf428a3..3e2373d 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Reluați"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Anulați"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Trimiteți"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Ștergeți"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Înregistrarea ecranului a fost anulată"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Înregistrarea ecranului a fost salvată. Atingeți pentru vizualizare"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Înregistrarea ecranului a fost ștearsă."</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Eroare la ștergerea înregistrării ecranului"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Nu s-au obținut permisiunile"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Eroare la începerea înregistrării ecranului"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index ba86e95..7747724 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Возобновить"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Отмена"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Поделиться"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Удалить"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Запись видео с экрана отменена"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Запись видео с экрана сохранена. Чтобы открыть ее, нажмите на уведомление."</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Запись видео с экрана удалена"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Не удалось удалить запись видео с экрана"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Не удалось получить необходимые разрешения"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Не удалось начать запись видео с экрана."</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 1cd1ceb..b8813f2 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"නැවත අරඹන්න"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"අවලංගු කරන්න"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"බෙදා ගන්න"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"මකන්න"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"තිර පටිගත කිරීම අවලංගු කරන ලදී"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"තිර පටිගත කිරීම සුරකින ලදී, බැලීමට තට්ටු කරන්න"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"තිර පටිගත කිරීම මකන ලදී"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"තිර පටිගත කිරීම මැකීමේ දෝෂයකි"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"අවසර ලබා ගැනීමට අසමත් විය"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"තිර පටිගත කිරීම ආරම්භ කිරීමේ දෝෂයකි"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 7548607..0f9cb5f 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Obnoviť"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Zrušiť"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Zdieľať"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Odstrániť"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Záznam obrazovky bol zrušený"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Záznam obrazovky bol uložený, zobrazíte ho klepnutím"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Záznam obrazovky bol odstránený"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Pri odstraňovaní záznamu obrazovky sa vyskytla chyba"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Nepodarilo sa získať povolenia"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Pri spustení nahrávania obrazovky sa vyskytla chyba"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 07ad8c1..18db332 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Nadaljuj"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Prekliči"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Deli"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Izbriši"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Snemanje zaslona je preklicano"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Videoposnetek zaslona je shranjen, dotaknite se za ogled"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Videoposnetek zaslona je izbrisan"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Napaka pri brisanju videoposnetka zaslona"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Dovoljenj ni bilo mogoče pridobiti"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Napaka pri začenjanju snemanja zaslona"</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index b92744d..57ab1c3 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -108,15 +108,13 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Vazhdo"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Anulo"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Ndaj"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Fshi"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Regjistrimi i ekranit u anulua"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Regjistrimi i ekranit u ruajt, trokit për ta parë"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Regjistrimi i ekranit u fshi"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Gabim gjatë fshirjes së regjistrimit të ekranit"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Marrja e lejeve dështoi"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Gabim gjatë nisjes së regjistrimit të ekranit"</string>
<string name="usb_preference_title" msgid="1439924437558480718">"Opsionet e transferimit të dosjeve të USB-së"</string>
- <string name="use_mtp_button_title" msgid="5036082897886518086">"Lidh si një lexues \"media\" (MTP)"</string>
+ <string name="use_mtp_button_title" msgid="5036082897886518086">"Lidh si një luajtës të medias (MTP)"</string>
<string name="use_ptp_button_title" msgid="7676427598943446826">"Montoje si kamerë (PTP)"</string>
<string name="installer_cd_button_title" msgid="5499998592841984743">"Instalo \"Transferimi i skedarëve të Android\" për Mac"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Prapa"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index f57d92b..ec763f6 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Настави"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Откажи"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Дели"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Избриши"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Снимање екрана је отказано"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Снимак екрана је сачуван, додирните да бисте прегледали"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Снимак екрана је избрисан"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Дошло је до проблема при брисању снимка екрана"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Преузимање дозвола није успело"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Грешка при покретању снимања екрана"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 876e337..a0a563d 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Återuppta"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Avbryt"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Dela"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Radera"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Skärminspelningen har avbrutits"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Skärminspelningen har sparats, tryck här om du vill titta på den"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Skärminspelningen har raderats"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Det gick inte att radera skärminspelningen"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Behörighet saknas"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Det gick inte att starta skärminspelningen"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 25e3493..7e264a4 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Endelea"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Ghairi"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Shiriki"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Futa"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Imeghairi mchakato wa kurekodi skrini"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Imehifadhi rekodi ya skrini, gusa ili uangalie"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Imefuta rekodi ya skrini"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Hitilafu imetokea wakati wa kufuta rekodi ya skrini"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Imeshindwa kupata ruhusa"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Hitilafu imetokea wakati wa kuanza kurekodi skrini"</string>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 19e67db..e0f20ce 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"மீண்டும் தொடங்கு"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"ரத்துசெய்"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"பகிர்"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"நீக்கு"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"திரை ரெக்கார்டிங் ரத்துசெய்யப்பட்டது"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"திரை ரெக்கார்டிங் சேமிக்கப்பட்டது, பார்க்கத் தட்டவும்"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"திரை ரெக்கார்டிங் நீக்கப்பட்டது"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"திரை ரெக்கார்டிங்கை நீக்குவதில் பிழை"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"அனுமதிகளைப் பெற இயலவில்லை"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"ஸ்கிரீன் ரெக்கார்டிங்கைத் தொடங்குவதில் பிழை"</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 34ff9b1..3e94b72 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"కొనసాగించు"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"రద్దు చేయి"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"షేర్ చేయి"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"తొలగించు"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"స్క్రీన్ రికార్డ్ రద్దు చేయబడింది"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"స్క్రీన్ రికార్డింగ్ సేవ్ చేయబడింది, చూడటం కోసం నొక్కండి"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"స్క్రీన్ రికార్డింగ్ తొలగించబడింది"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"స్క్రీన్ రికార్డింగ్ని తొలగిస్తున్నప్పుడు ఎర్రర్ ఏర్పడింది"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"అనుమతులను పొందడం విఫలమైంది"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"స్క్రీన్ రికార్డింగ్ ప్రారంభించడంలో ఎర్రర్ ఏర్పడింది"</string>
diff --git a/packages/SystemUI/res/values-television/config.xml b/packages/SystemUI/res/values-television/config.xml
index 7b1479a..b2d057b 100644
--- a/packages/SystemUI/res/values-television/config.xml
+++ b/packages/SystemUI/res/values-television/config.xml
@@ -28,7 +28,6 @@
<string-array name="config_systemUIServiceComponents" translatable="false">
<item>com.android.systemui.util.NotificationChannels</item>
<item>com.android.systemui.volume.VolumeUI</item>
- <item>com.android.systemui.stackdivider.Divider</item>
<item>com.android.systemui.statusbar.tv.TvStatusBar</item>
<item>com.android.systemui.usb.StorageNotification</item>
<item>com.android.systemui.power.PowerUI</item>
@@ -42,6 +41,7 @@
<item>com.android.systemui.statusbar.notification.InstantAppNotifier</item>
<item>com.android.systemui.toast.ToastUI</item>
<item>com.android.systemui.onehanded.OneHandedUI</item>
+ <item>com.android.systemui.wmshell.WMShell</item>
</string-array>
<!-- Show a separate icon for low and high volume on the volume dialog -->
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index d37be57..088b624 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"ทำต่อ"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"ยกเลิก"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"แชร์"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"ลบ"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"ยกเลิกการบันทึกหน้าจอแล้ว"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"บันทึกการบันทึกหน้าจอแล้ว แตะเพื่อดู"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"ลบการบันทึกหน้าจอแล้ว"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"เกิดข้อผิดพลาดในการลบการบันทึกหน้าจอ"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"ขอสิทธิ์ไม่สำเร็จ"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"เกิดข้อผิดพลาดขณะเริ่มบันทึกหน้าจอ"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index af474c7..e787b17 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Ituloy"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Kanselahin"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Ibahagi"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"I-delete"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Kinansela ang pag-record ng screen"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Na-save ang pag-record ng screen, i-tap para tingnan"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Na-delete ang pag-record ng screen"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Error sa pag-delete sa pag-record ng screen"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Hindi nakuha ang mga pahintulot"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Nagkaroon ng error sa pagsisimula ng pag-record ng screen"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index ee494a2..e339445 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Devam ettir"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"İptal"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Paylaş"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Sil"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Ekran kaydı iptal edildi"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Ekran kaydı tamamlandı, görüntülemek için dokunun"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Ekran kaydı silindi"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Ekran kaydı silinirken hata oluştu"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"İzinler alınamadı"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Ekran kaydı başlatılırken hata oluştu"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index c444c47..f5419f1 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Відновити"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Скасувати"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Поділитися"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Видалити"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Запис екрана скасовано"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Запис екрана збережено. Натисніть, щоб переглянути"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Запис екрана видалено"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Не вдалося видалити запис екрана"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Не вдалось отримати дозволи"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Не вдалося почати запис екрана"</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 729ed5a..2abf350 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"دوبارہ شروع کریں"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"منسوخ کریں"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"اشتراک کریں"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"حذف کریں"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"اسکرین ریکارڈنگ منسوخ ہو گئی"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"اسکرین ریکارڈنگ محفوظ ہو گئی، دیکھنے کیلئے تھپتھپائیں"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"اسکرین ریکارڈنگ حذف ہو گئی"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"اسکرین ریکارڈنگ کو حذف کرنے میں خرابی"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"اجازتیں حاصل کرنے میں ناکامی"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"اسکرین ریکارڈنگ شروع کرنے میں خرابی"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index cf1da75..61b10a4 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Davom etish"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Bekor qilish"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Ulashish"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"O‘chirish"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Ekrandan yozib olish bekor qilindi"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Ekrandan yozib olingan video saqlandi. Uni ochish uchun bildirishnomani bosing."</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Ekrandan yozib olingan video o‘chirib tashlandi"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Ekrandan yozib olingan vi olib tashlanmadi"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Zarur ruxsatlar olinmadi"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Ekranni yozib olish boshlanmadi"</string>
@@ -362,7 +360,7 @@
<string name="accessibility_quick_settings_rotation_value" msgid="2916484894750819251">"<xliff:g id="ID_1">%s</xliff:g> rejimi"</string>
<string name="quick_settings_rotation_locked_label" msgid="4420863550666310319">"Aylanmaydigan qilingan"</string>
<string name="quick_settings_rotation_locked_portrait_label" msgid="1194988975270484482">"Tik holat"</string>
- <string name="quick_settings_rotation_locked_landscape_label" msgid="2000295772687238645">"Eniga"</string>
+ <string name="quick_settings_rotation_locked_landscape_label" msgid="2000295772687238645">"Yotiq"</string>
<string name="quick_settings_ime_label" msgid="3351174938144332051">"Kiritish usuli"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Joylashuv"</string>
<string name="quick_settings_location_off_label" msgid="7923929131443915919">"Joylashuvni aniqlash xizmati yoqilmagan"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 5794bdf..6107270 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Tiếp tục"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Hủy"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Chia sẻ"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Xóa"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Đã hủy bản ghi màn hình"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Đã lưu bản ghi màn hình, nhấn để xem"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Đã xóa bản ghi màn hình"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Lỗi khi xóa bản ghi màn hình"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Không được cấp đủ quyền"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Lỗi khi bắt đầu ghi màn hình"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 41c132c..ffd1995 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"继续"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"取消"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"分享"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"删除"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"已取消录制屏幕"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"屏幕录制内容已保存,点按即可查看"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"已删除屏幕录制内容"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"删除屏幕录制内容时出错"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"无法获取权限"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"启动屏幕录制时出错"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index b2e1b90..1575427 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"繼續"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"取消"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"分享"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"刪除"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"已取消錄影畫面"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"已儲存錄影畫面,輕按即可查看"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"已刪除錄影畫面"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"刪除錄影畫面時發生錯誤"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"無法獲得權限"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"開始錄影畫面時發生錯誤"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 346b1239..bbd8355 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"繼續"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"取消"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"分享"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"刪除"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"已取消錄製螢幕畫面"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"已儲存螢幕畫面錄製內容,輕觸即可查看"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"已刪除螢幕畫面錄製內容"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"刪除螢幕畫面錄製內容時發生錯誤"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"無法取得權限"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"開始錄製螢幕畫面時發生錯誤"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 5abce7f..63b4c61 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -108,10 +108,8 @@
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Qalisa kabusha"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Khansela"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Yabelana"</string>
- <string name="screenrecord_delete_label" msgid="1376347010553987058">"Susa"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Ukurekhoda isikrini kukhanseliwe"</string>
<string name="screenrecord_save_message" msgid="490522052388998226">"Ukurekhoda isikrini kulondoloziwe, thepha ukuze ubuke"</string>
- <string name="screenrecord_delete_description" msgid="1604522770162810570">"Ukurekhoda isikrini kususiwe"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Iphutha lokususa ukurekhoda isikrini"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Yehlulekile ukuthola izimvume"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Iphutha lokuqala ukurekhoda isikrini"</string>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index ce1ca5a..130bb4f 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -301,7 +301,6 @@
<item>com.android.systemui.keyguard.KeyguardViewMediator</item>
<item>com.android.systemui.recents.Recents</item>
<item>com.android.systemui.volume.VolumeUI</item>
- <item>com.android.systemui.stackdivider.Divider</item>
<item>com.android.systemui.statusbar.phone.StatusBar</item>
<item>com.android.systemui.usb.StorageNotification</item>
<item>com.android.systemui.power.PowerUI</item>
@@ -323,6 +322,7 @@
<item>com.android.systemui.accessibility.SystemActions</item>
<item>com.android.systemui.toast.ToastUI</item>
<item>com.android.systemui.onehanded.OneHandedUI</item>
+ <item>com.android.systemui.wmshell.WMShell</item>
</string-array>
<!-- QS tile shape store width. negative implies fill configuration instead of stroke-->
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 823c1ff..bfa7532 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -278,14 +278,10 @@
<string name="screenrecord_cancel_label">Cancel</string>
<!-- Label for notification action to share screen recording [CHAR LIMIT=35] -->
<string name="screenrecord_share_label">Share</string>
- <!-- Label for notification action to delete a screen recording file [CHAR LIMIT=35] -->
- <string name="screenrecord_delete_label">Delete</string>
<!-- A toast message shown after successfully canceling a screen recording [CHAR LIMIT=NONE] -->
<string name="screenrecord_cancel_success">Screen recording canceled</string>
<!-- Notification text shown after saving a screen recording to prompt the user to view it [CHAR LIMIT=100] -->
<string name="screenrecord_save_message">Screen recording saved, tap to view</string>
- <!-- A toast message shown after successfully deleting a screen recording [CHAR LIMIT=NONE] -->
- <string name="screenrecord_delete_description">Screen recording deleted</string>
<!-- A toast message shown when there is an error deleting a screen recording [CHAR LIMIT=NONE] -->
<string name="screenrecord_delete_error">Error deleting screen recording</string>
<!-- A toast message shown when the screen recording cannot be started due to insufficient permissions [CHAR LIMIT=NONE] -->
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index 748a9c9..27809b5 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -65,7 +65,6 @@
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.DevicePolicyManagerWrapper;
import com.android.systemui.shared.system.PackageManagerWrapper;
-import com.android.systemui.stackdivider.Divider;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.NotificationListener;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
@@ -324,7 +323,6 @@
@Inject Lazy<DisplayImeController> mDisplayImeController;
@Inject Lazy<RecordingController> mRecordingController;
@Inject Lazy<ProtoTracer> mProtoTracer;
- @Inject Lazy<Divider> mDivider;
@Inject
public Dependency() {
@@ -521,7 +519,6 @@
mProviders.put(AutoHideController.class, mAutoHideController::get);
mProviders.put(RecordingController.class, mRecordingController::get);
- mProviders.put(Divider.class, mDivider::get);
Dependency.setInstance(this);
}
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index d17ca404..47066a0 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -22,7 +22,6 @@
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.annotation.NonNull;
-import android.content.Context;
import android.content.res.Resources;
import android.graphics.RectF;
import android.os.Handler;
@@ -115,24 +114,24 @@
private final ArrayMap<View, Animator> mDismissPendingMap = new ArrayMap<>();
public SwipeHelper(
- int swipeDirection, Callback callback, Context context, FalsingManager falsingManager) {
+ int swipeDirection, Callback callback, Resources resources,
+ ViewConfiguration viewConfiguration, FalsingManager falsingManager) {
mCallback = callback;
mHandler = new Handler();
mSwipeDirection = swipeDirection;
mVelocityTracker = VelocityTracker.obtain();
- final ViewConfiguration configuration = ViewConfiguration.get(context);
- mPagingTouchSlop = configuration.getScaledPagingTouchSlop();
- mSlopMultiplier = configuration.getScaledAmbiguousGestureMultiplier();
+ mPagingTouchSlop = viewConfiguration.getScaledPagingTouchSlop();
+ mSlopMultiplier = viewConfiguration.getScaledAmbiguousGestureMultiplier();
// Extra long-press!
mLongPressTimeout = (long) (ViewConfiguration.getLongPressTimeout() * 1.5f);
- Resources res = context.getResources();
- mDensityScale = res.getDisplayMetrics().density;
- mFalsingThreshold = res.getDimensionPixelSize(R.dimen.swipe_helper_falsing_threshold);
- mFadeDependingOnAmountSwiped = res.getBoolean(R.bool.config_fadeDependingOnAmountSwiped);
+ mDensityScale = resources.getDisplayMetrics().density;
+ mFalsingThreshold = resources.getDimensionPixelSize(R.dimen.swipe_helper_falsing_threshold);
+ mFadeDependingOnAmountSwiped = resources.getBoolean(
+ R.bool.config_fadeDependingOnAmountSwiped);
mFalsingManager = falsingManager;
- mFlingAnimationUtils = new FlingAnimationUtils(res.getDisplayMetrics(),
+ mFlingAnimationUtils = new FlingAnimationUtils(resources.getDisplayMetrics(),
getMaxEscapeAnimDuration() / 1000f);
}
diff --git a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java
index eeb3b28..a3339f6 100644
--- a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java
@@ -19,6 +19,7 @@
import android.app.AppOpsManager;
import android.content.Context;
import android.content.pm.PackageManager;
+import android.location.LocationManager;
import android.media.AudioManager;
import android.media.AudioRecordingConfiguration;
import android.os.Handler;
@@ -66,6 +67,13 @@
private final AppOpsManager mAppOps;
private final AudioManager mAudioManager;
+ private final LocationManager mLocationManager;
+
+ // mLocationProviderPackages are cached and updated only occasionally
+ private static final long LOCATION_PROVIDER_UPDATE_FREQUENCY_MS = 30000;
+ private long mLastLocationProviderPackageUpdate;
+ private List<String> mLocationProviderPackages;
+
private H mBGHandler;
private final List<AppOpsController.Callback> mCallbacks = new ArrayList<>();
private final SparseArray<Set<Callback>> mCallbacksByCode = new SparseArray<>();
@@ -83,8 +91,10 @@
protected static final int[] OPS = new int[] {
AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION,
AppOpsManager.OP_CAMERA,
+ AppOpsManager.OP_PHONE_CALL_CAMERA,
AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
AppOpsManager.OP_RECORD_AUDIO,
+ AppOpsManager.OP_PHONE_CALL_MICROPHONE,
AppOpsManager.OP_COARSE_LOCATION,
AppOpsManager.OP_FINE_LOCATION
};
@@ -105,6 +115,7 @@
mCallbacksByCode.put(OPS[i], new ArraySet<>());
}
mAudioManager = audioManager;
+ mLocationManager = context.getSystemService(LocationManager.class);
dumpManager.registerDumpable(TAG, this);
}
@@ -288,6 +299,26 @@
return isUserVisible(item.getCode(), item.getUid(), item.getPackageName());
}
+ /**
+ * Checks if a package is the current location provider.
+ *
+ * <p>Data is cached to avoid too many calls into system server
+ *
+ * @param packageName The package that might be the location provider
+ *
+ * @return {@code true} iff the package is the location provider.
+ */
+ private boolean isLocationProvider(String packageName) {
+ long now = System.currentTimeMillis();
+
+ if (mLastLocationProviderPackageUpdate + LOCATION_PROVIDER_UPDATE_FREQUENCY_MS < now) {
+ mLastLocationProviderPackageUpdate = now;
+ mLocationProviderPackages = mLocationManager.getProviderPackages(
+ LocationManager.FUSED_PROVIDER);
+ }
+
+ return mLocationProviderPackages.contains(packageName);
+ }
/**
* Does the app-op, uid and package name, refer to an operation that should be shown to the
@@ -303,7 +334,13 @@
// does not correspond to a platform permission
// which may be user sensitive, so for now always show it to the user.
if (appOpCode == AppOpsManager.OP_SYSTEM_ALERT_WINDOW
- || appOpCode == AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION) {
+ || appOpCode == AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION
+ || appOpCode == AppOpsManager.OP_PHONE_CALL_CAMERA
+ || appOpCode == AppOpsManager.OP_PHONE_CALL_MICROPHONE) {
+ return true;
+ }
+
+ if (appOpCode == AppOpsManager.OP_CAMERA && isLocationProvider(packageName)) {
return true;
}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
index 2fc5cba..8a67e96 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
@@ -61,7 +61,7 @@
import com.android.systemui.shared.plugins.PluginManagerImpl;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.DevicePolicyManagerWrapper;
-import com.android.systemui.stackdivider.Divider;
+import com.android.systemui.stackdivider.SplitScreen;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.phone.AutoHideController;
@@ -193,7 +193,7 @@
SysUiState sysUiFlagsContainer,
BroadcastDispatcher broadcastDispatcher,
CommandQueue commandQueue,
- Divider divider,
+ Optional<SplitScreen> splitScreenOptional,
Optional<Recents> recentsOptional,
Lazy<StatusBar> statusBarLazy,
ShadeController shadeController,
@@ -215,7 +215,7 @@
sysUiFlagsContainer,
broadcastDispatcher,
commandQueue,
- divider,
+ splitScreenOptional,
recentsOptional,
statusBarLazy,
shadeController,
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemServicesModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemServicesModule.java
index e7d2f125..ceb9aee 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemServicesModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemServicesModule.java
@@ -60,6 +60,7 @@
import android.telecom.TelecomManager;
import android.telephony.TelephonyManager;
import android.view.IWindowManager;
+import android.view.ViewConfiguration;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
import android.view.accessibility.AccessibilityManager;
@@ -321,6 +322,12 @@
@Provides
@SysUISingleton
+ static ViewConfiguration provideViewConfiguration(Context context) {
+ return ViewConfiguration.get(context);
+ }
+
+ @Provides
+ @SysUISingleton
static UserManager provideUserManager(Context context) {
return context.getSystemService(UserManager.class);
}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java
index 0aebb7e..9dfd9f8 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java
@@ -34,7 +34,6 @@
import com.android.systemui.recents.Recents;
import com.android.systemui.recents.RecentsModule;
import com.android.systemui.shortcut.ShortcutKeyDispatcher;
-import com.android.systemui.stackdivider.Divider;
import com.android.systemui.statusbar.dagger.StatusBarModule;
import com.android.systemui.statusbar.notification.InstantAppNotifier;
import com.android.systemui.statusbar.phone.StatusBar;
@@ -43,6 +42,7 @@
import com.android.systemui.toast.ToastUI;
import com.android.systemui.util.leak.GarbageMonitor;
import com.android.systemui.volume.VolumeUI;
+import com.android.systemui.wmshell.WMShell;
import dagger.Binds;
import dagger.Module;
@@ -61,12 +61,6 @@
@ClassKey(AuthController.class)
public abstract SystemUI bindAuthController(AuthController service);
- /** Inject into Divider. */
- @Binds
- @IntoMap
- @ClassKey(Divider.class)
- public abstract SystemUI bindDivider(Divider sysui);
-
/** Inject into GarbageMonitor.Service. */
@Binds
@IntoMap
@@ -187,4 +181,10 @@
@IntoMap
@ClassKey(WindowMagnification.class)
public abstract SystemUI bindWindowMagnification(WindowMagnification sysui);
+
+ /** Inject into WMShell. */
+ @Binds
+ @IntoMap
+ @ClassKey(WMShell.class)
+ public abstract SystemUI bindWMShell(WMShell sysui);
}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java
index 3b225d5..a021114 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java
@@ -41,7 +41,6 @@
import com.android.systemui.qs.tileimpl.QSFactoryImpl;
import com.android.systemui.recents.Recents;
import com.android.systemui.recents.RecentsImplementation;
-import com.android.systemui.stackdivider.DividerModule;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationLockscreenUserManagerImpl;
@@ -75,7 +74,6 @@
* overridden by the System UI implementation.
*/
@Module(includes = {
- DividerModule.class,
QSModule.class,
WMShellModule.class
})
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index d0e4543..e985e3d 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
@@ -27,7 +27,6 @@
import com.android.systemui.recents.Recents;
import com.android.systemui.screenshot.dagger.ScreenshotModule;
import com.android.systemui.settings.dagger.SettingsModule;
-import com.android.systemui.stackdivider.Divider;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinder;
import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinderImpl;
@@ -95,9 +94,6 @@
abstract CommandQueue optionalCommandQueue();
@BindsOptionalOf
- abstract Divider optionalDivider();
-
- @BindsOptionalOf
abstract HeadsUpManager optionalHeadsUpManager();
@BindsOptionalOf
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaTimeoutListener.kt b/packages/SystemUI/src/com/android/systemui/media/MediaTimeoutListener.kt
index fdbff98..6bd5274 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaTimeoutListener.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaTimeoutListener.kt
@@ -54,32 +54,35 @@
if (mediaListeners.containsKey(key)) {
return
}
- // Having an old key means that we're migrating from/to resumption. We should invalidate
- // the old listener and create a new one.
+ // Having an old key means that we're migrating from/to resumption. We should update
+ // the old listener to make sure that events will be dispatched to the new location.
val migrating = oldKey != null && key != oldKey
var wasPlaying = false
if (migrating) {
- if (mediaListeners.containsKey(oldKey)) {
- val oldListener = mediaListeners.remove(oldKey)
- wasPlaying = oldListener?.playing ?: false
- oldListener?.destroy()
+ val reusedListener = mediaListeners.remove(oldKey)
+ if (reusedListener != null) {
+ wasPlaying = reusedListener.playing ?: false
if (DEBUG) Log.d(TAG, "migrating key $oldKey to $key, for resumption")
+ reusedListener.mediaData = data
+ reusedListener.key = key
+ mediaListeners[key] = reusedListener
+ if (wasPlaying != reusedListener.playing) {
+ // If a player becomes active because of a migration, we'll need to broadcast
+ // its state. Doing it now would lead to reentrant callbacks, so let's wait
+ // until we're done.
+ mainExecutor.execute {
+ if (mediaListeners[key]?.playing == true) {
+ if (DEBUG) Log.d(TAG, "deliver delayed playback state for $key")
+ timeoutCallback.invoke(key, false /* timedOut */)
+ }
+ }
+ }
+ return
} else {
Log.w(TAG, "Old key $oldKey for player $key doesn't exist. Continuing...")
}
}
mediaListeners[key] = PlaybackStateListener(key, data)
-
- // If a player becomes active because of a migration, we'll need to broadcast its state.
- // Doing it now would lead to reentrant callbacks, so let's wait until we're done.
- if (migrating && mediaListeners[key]?.playing != wasPlaying) {
- mainExecutor.execute {
- if (mediaListeners[key]?.playing == true) {
- if (DEBUG) Log.d(TAG, "deliver delayed playback state for $key")
- timeoutCallback.invoke(key, false /* timedOut */)
- }
- }
- }
}
override fun onMediaDataRemoved(key: String) {
@@ -91,26 +94,34 @@
}
private inner class PlaybackStateListener(
- private val key: String,
+ var key: String,
data: MediaData
) : MediaController.Callback() {
var timedOut = false
var playing: Boolean? = null
+ var mediaData: MediaData = data
+ set(value) {
+ mediaController?.unregisterCallback(this)
+ field = value
+ mediaController = if (field.token != null) {
+ mediaControllerFactory.create(field.token)
+ } else {
+ null
+ }
+ mediaController?.registerCallback(this)
+ // Let's register the cancellations, but not dispatch events now.
+ // Timeouts didn't happen yet and reentrant events are troublesome.
+ processState(mediaController?.playbackState, dispatchEvents = false)
+ }
+
// Resume controls may have null token
- private val mediaController = if (data.token != null) {
- mediaControllerFactory.create(data.token)
- } else {
- null
- }
+ private var mediaController: MediaController? = null
private var cancellation: Runnable? = null
init {
- mediaController?.registerCallback(this)
- // Let's register the cancellations, but not dispatch events now.
- // Timeouts didn't happen yet and reentrant events are troublesome.
- processState(mediaController?.playbackState, dispatchEvents = false)
+ mediaData = data
}
fun destroy() {
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
index 6c8a23b..aec3543 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
@@ -111,7 +111,6 @@
import com.android.systemui.assist.AssistManager;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.fragments.FragmentHostManager;
import com.android.systemui.model.SysUiState;
import com.android.systemui.navigationbar.buttons.ButtonDispatcher;
import com.android.systemui.navigationbar.buttons.KeyButtonView;
@@ -123,7 +122,7 @@
import com.android.systemui.recents.Recents;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.QuickStepContract;
-import com.android.systemui.stackdivider.Divider;
+import com.android.systemui.stackdivider.SplitScreen;
import com.android.systemui.statusbar.AutoHideUiElement;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.CommandQueue.Callbacks;
@@ -180,7 +179,7 @@
private final NavigationModeController mNavigationModeController;
private final BroadcastDispatcher mBroadcastDispatcher;
private final CommandQueue mCommandQueue;
- private final Divider mDivider;
+ private final Optional<SplitScreen> mSplitScreenOptional;
private final Optional<Recents> mRecentsOptional;
private final SystemActions mSystemActions;
private final Handler mHandler;
@@ -377,22 +376,22 @@
private final DeviceConfig.OnPropertiesChangedListener mOnPropertiesChangedListener =
new DeviceConfig.OnPropertiesChangedListener() {
- @Override
- public void onPropertiesChanged(DeviceConfig.Properties properties) {
- if (properties.getKeyset().contains(NAV_BAR_HANDLE_FORCE_OPAQUE)) {
- mForceNavBarHandleOpaque = properties.getBoolean(
- NAV_BAR_HANDLE_FORCE_OPAQUE, /* defaultValue = */ true);
- }
- }
- };
+ @Override
+ public void onPropertiesChanged(DeviceConfig.Properties properties) {
+ if (properties.getKeyset().contains(NAV_BAR_HANDLE_FORCE_OPAQUE)) {
+ mForceNavBarHandleOpaque = properties.getBoolean(
+ NAV_BAR_HANDLE_FORCE_OPAQUE, /* defaultValue = */ true);
+ }
+ }
+ };
private final DeviceProvisionedController.DeviceProvisionedListener mUserSetupListener =
new DeviceProvisionedController.DeviceProvisionedListener() {
- @Override
- public void onUserSetupChanged() {
- mIsCurrentUserSetup = mDeviceProvisionedController.isCurrentUserSetup();
- }
- };
+ @Override
+ public void onUserSetupChanged() {
+ mIsCurrentUserSetup = mDeviceProvisionedController.isCurrentUserSetup();
+ }
+ };
public NavigationBar(Context context,
WindowManager windowManager,
@@ -406,7 +405,8 @@
StatusBarStateController statusBarStateController,
SysUiState sysUiFlagsContainer,
BroadcastDispatcher broadcastDispatcher,
- CommandQueue commandQueue, Divider divider,
+ CommandQueue commandQueue,
+ Optional<SplitScreen> splitScreenOptional,
Optional<Recents> recentsOptional, Lazy<StatusBar> statusBarLazy,
ShadeController shadeController,
NotificationRemoteInputManager notificationRemoteInputManager,
@@ -430,7 +430,7 @@
mNavBarMode = navigationModeController.addListener(this);
mBroadcastDispatcher = broadcastDispatcher;
mCommandQueue = commandQueue;
- mDivider = divider;
+ mSplitScreenOptional = splitScreenOptional;
mRecentsOptional = recentsOptional;
mSystemActions = systemActions;
mHandler = mainHandler;
@@ -458,10 +458,10 @@
lp.windowAnimations = 0;
lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC;
- LayoutInflater layoutInflater = LayoutInflater.from(mContext);
- NavigationBarFrame frame = (NavigationBarFrame) layoutInflater.inflate(
+ NavigationBarFrame frame = (NavigationBarFrame) LayoutInflater.from(mContext).inflate(
R.layout.navigation_bar_window, null);
- View barView = layoutInflater.inflate(R.layout.navigation_bar, frame);
+ View barView = LayoutInflater.from(frame.getContext()).inflate(
+ R.layout.navigation_bar, frame);
barView.addOnAttachStateChangeListener(this);
if (DEBUG) Log.v(TAG, "addNavigationBar: about to add " + barView);
@@ -528,6 +528,7 @@
}
mNavigationBarView.setNavigationIconHints(mNavigationIconHints);
mNavigationBarView.setWindowVisible(isNavBarWindowVisible());
+ mSplitScreenOptional.ifPresent(mNavigationBarView::registerDockedListener);
prepareNavigationBarView();
checkNavBarModes();
@@ -559,7 +560,7 @@
setDisabled2Flags(mDisabledFlags2);
if (mIsOnDefaultDisplay) {
mAssistHandlerViewController =
- new AssistHandleViewController(mHandler, mNavigationBarView);
+ new AssistHandleViewController(mHandler, mNavigationBarView);
getBarTransitions().addDarkIntensityListener(mAssistHandlerViewController);
}
@@ -690,7 +691,8 @@
return;
}
- if (mStartingQuickSwitchRotation == -1 || mDivider.isDividerVisible()) {
+ if (mStartingQuickSwitchRotation == -1 || mSplitScreenOptional
+ .map(SplitScreen::isDividerVisible).orElse(false)) {
// Hide the secondary home handle if we are in multiwindow since apps in multiwindow
// aren't allowed to set the display orientation
resetSecondaryHandle();
@@ -1121,7 +1123,7 @@
}
mMetricsLogger.action(MetricsEvent.ACTION_ASSIST_LONG_PRESS);
mUiEventLogger.log(NavBarActionEvent.NAVBAR_ASSIST_LONGPRESS);
- Bundle args = new Bundle();
+ Bundle args = new Bundle();
args.putInt(
AssistManager.INVOCATION_TYPE_KEY, AssistManager.INVOCATION_HOME_BUTTON_LONG_PRESS);
mAssistManagerLazy.get().startAssist(args);
@@ -1246,10 +1248,12 @@
private boolean onLongPressRecents() {
if (mRecentsOptional.isPresent() || !ActivityTaskManager.supportsMultiWindow(mContext)
- || !mDivider.getView().getSnapAlgorithm().isSplitScreenFeasible()
|| ActivityManager.isLowRamDeviceStatic()
// If we are connected to the overview service, then disable the recents button
- || mOverviewProxyService.getProxy() != null) {
+ || mOverviewProxyService.getProxy() != null
+ || !mSplitScreenOptional.map(splitScreen ->
+ splitScreen.getDividerView().getSnapAlgorithm().isSplitScreenFeasible())
+ .orElse(false)) {
return false;
}
@@ -1311,6 +1315,7 @@
/**
* Returns the system UI flags corresponding the the current accessibility button state
+ *
* @param outFeedbackEnabled if non-null, sets it to true if accessibility feedback is enabled.
*/
public int getA11yButtonState(@Nullable boolean[] outFeedbackEnabled) {
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java
index fd157c6..9b9dc6d 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java
@@ -55,7 +55,7 @@
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.recents.Recents;
import com.android.systemui.shared.system.ActivityManagerWrapper;
-import com.android.systemui.stackdivider.Divider;
+import com.android.systemui.stackdivider.SplitScreen;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.CommandQueue.Callbacks;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
@@ -96,7 +96,7 @@
private final SysUiState mSysUiFlagsContainer;
private final BroadcastDispatcher mBroadcastDispatcher;
private final CommandQueue mCommandQueue;
- private final Divider mDivider;
+ private final Optional<SplitScreen> mSplitScreenOptional;
private final Optional<Recents> mRecentsOptional;
private final Lazy<StatusBar> mStatusBarLazy;
private final ShadeController mShadeController;
@@ -130,7 +130,7 @@
SysUiState sysUiFlagsContainer,
BroadcastDispatcher broadcastDispatcher,
CommandQueue commandQueue,
- Divider divider,
+ Optional<SplitScreen> splitScreenOptional,
Optional<Recents> recentsOptional,
Lazy<StatusBar> statusBarLazy,
ShadeController shadeController,
@@ -152,7 +152,7 @@
mSysUiFlagsContainer = sysUiFlagsContainer;
mBroadcastDispatcher = broadcastDispatcher;
mCommandQueue = commandQueue;
- mDivider = divider;
+ mSplitScreenOptional = splitScreenOptional;
mRecentsOptional = recentsOptional;
mStatusBarLazy = statusBarLazy;
mShadeController = shadeController;
@@ -278,7 +278,7 @@
mSysUiFlagsContainer,
mBroadcastDispatcher,
mCommandQueue,
- mDivider,
+ mSplitScreenOptional,
mRecentsOptional,
mStatusBarLazy,
mShadeController,
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
index a335183..8a468f6e 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
@@ -87,14 +87,13 @@
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.shared.system.SysUiStatsLog;
import com.android.systemui.shared.system.WindowManagerWrapper;
-import com.android.systemui.stackdivider.Divider;
+import com.android.systemui.stackdivider.SplitScreen;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.phone.AutoHideController;
import com.android.systemui.statusbar.phone.LightBarTransitionsController;
import com.android.systemui.statusbar.phone.NotificationPanelViewController;
import com.android.systemui.statusbar.phone.StatusBar;
-import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.function.Consumer;
@@ -329,8 +328,8 @@
mContextualButtonGroup.addButton(accessibilityButton);
mOverviewProxyService = Dependency.get(OverviewProxyService.class);
- mRecentsOnboarding = new RecentsOnboarding(context, mOverviewProxyService);
mFloatingRotationButton = new FloatingRotationButton(context);
+ mRecentsOnboarding = new RecentsOnboarding(context, mOverviewProxyService);
mRotationButtonController = new RotationButtonController(mLightContext,
mLightIconColor, mDarkIconColor,
isGesturalMode ? mFloatingRotationButton : rotateSuggestionButton,
@@ -912,9 +911,6 @@
mNavigationInflaterView.setButtonDispatchers(mButtonDispatchers);
getImeSwitchButton().setOnClickListener(mImeSwitcherClickListener);
-
- Divider divider = Dependency.get(Divider.class);
- divider.registerInSplitScreenListener(mDockedListener);
updateOrientationViews();
reloadNavIcons();
}
@@ -1287,6 +1283,10 @@
return super.onApplyWindowInsets(insets);
}
+ void registerDockedListener(SplitScreen splitScreen) {
+ splitScreen.registerInSplitScreenListener(mDockedListener);
+ }
+
private static void dumpButton(PrintWriter pw, String caption, ButtonDispatcher button) {
pw.print(" " + caption + ": ");
if (button == null) {
diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java
index 1ea5888..7421ec1 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java
@@ -58,7 +58,7 @@
import com.android.internal.os.SomeArgs;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.pip.phone.PipUpdateThread;
-import com.android.systemui.stackdivider.Divider;
+import com.android.systemui.stackdivider.SplitScreen;
import com.android.wm.shell.R;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayController;
@@ -69,6 +69,7 @@
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.util.Optional;
import java.util.function.Consumer;
/**
@@ -104,7 +105,7 @@
private final int mEnterExitAnimationDuration;
private final PipSurfaceTransactionHelper mSurfaceTransactionHelper;
private final Map<IBinder, Configuration> mInitialState = new HashMap<>();
- private final Divider mSplitDivider;
+ private final Optional<SplitScreen> mSplitScreenOptional;
protected final ShellTaskOrganizer mTaskOrganizer;
// These callbacks are called on the update thread
@@ -207,7 +208,7 @@
public PipTaskOrganizer(Context context, @NonNull PipBoundsHandler boundsHandler,
@NonNull PipSurfaceTransactionHelper surfaceTransactionHelper,
- @Nullable Divider divider,
+ Optional<SplitScreen> splitScreenOptional,
@NonNull DisplayController displayController,
@NonNull PipUiEventLogger pipUiEventLogger,
@NonNull ShellTaskOrganizer shellTaskOrganizer) {
@@ -220,7 +221,7 @@
mPipAnimationController = new PipAnimationController(mSurfaceTransactionHelper);
mPipUiEventLoggerLogger = pipUiEventLogger;
mSurfaceControlTransactionFactory = SurfaceControl.Transaction::new;
- mSplitDivider = divider;
+ mSplitScreenOptional = splitScreenOptional;
mTaskOrganizer = shellTaskOrganizer;
mTaskOrganizer.addListener(this, WINDOWING_MODE_PINNED);
displayController.addDisplayWindowListener(this);
@@ -336,9 +337,11 @@
wct.setWindowingMode(mToken, getOutPipWindowingMode());
// Simply reset the activity mode set prior to the animation running.
wct.setActivityWindowingMode(mToken, WINDOWING_MODE_UNDEFINED);
- if (mSplitDivider != null && direction == TRANSITION_DIRECTION_LEAVE_PIP_TO_SPLIT_SCREEN) {
- wct.reparent(mToken, mSplitDivider.getSecondaryRoot(), true /* onTop */);
- }
+ mSplitScreenOptional.ifPresent(splitScreen -> {
+ if (direction == TRANSITION_DIRECTION_LEAVE_PIP_TO_SPLIT_SCREEN) {
+ wct.reparent(mToken, splitScreen.getSecondaryRoot(), true /* onTop */);
+ }
+ });
}
/**
@@ -934,20 +937,26 @@
}
/**
- * Sync with {@link #mSplitDivider} on destination bounds if PiP is going to split screen.
+ * Sync with {@link SplitScreen} on destination bounds if PiP is going to split screen.
*
* @param destinationBoundsOut contain the updated destination bounds if applicable
* @return {@code true} if destinationBounds is altered for split screen
*/
private boolean syncWithSplitScreenBounds(Rect destinationBoundsOut) {
- if (mSplitDivider == null || !mSplitDivider.isDividerVisible()) {
- // bail early if system is not in split screen mode
+ if (!mSplitScreenOptional.isPresent()) {
return false;
}
+
+ SplitScreen splitScreen = mSplitScreenOptional.get();
+ if (!splitScreen.isDividerVisible()) {
+ // fail early if system is not in split screen mode
+ return false;
+ }
+
// PiP window will go to split-secondary mode instead of fullscreen, populates the
// split screen bounds here.
- destinationBoundsOut.set(
- mSplitDivider.getView().getNonMinimizedSplitScreenSecondaryBounds());
+ destinationBoundsOut.set(splitScreen.getDividerView()
+ .getNonMinimizedSplitScreenSecondaryBounds());
return true;
}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
index 27cc3d4..d8864ec 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
@@ -56,7 +56,7 @@
import com.android.systemui.shared.system.PinnedStackListenerForwarder.PinnedStackListener;
import com.android.systemui.shared.system.TaskStackChangeListener;
import com.android.systemui.shared.system.WindowManagerWrapper;
-import com.android.systemui.stackdivider.Divider;
+import com.android.systemui.stackdivider.SplitScreen;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.util.DeviceConfigProxy;
import com.android.systemui.util.FloatingContentCoordinator;
@@ -65,6 +65,7 @@
import com.android.wm.shell.common.DisplayController;
import java.io.PrintWriter;
+import java.util.Optional;
import javax.inject.Inject;
@@ -270,7 +271,7 @@
ConfigurationController configController,
DeviceConfigProxy deviceConfig,
DisplayController displayController,
- Divider divider,
+ Optional<SplitScreen> splitScreenOptional,
FloatingContentCoordinator floatingContentCoordinator,
SysUiState sysUiState,
PipUiEventLogger pipUiEventLogger,
@@ -290,8 +291,8 @@
mPipBoundsHandler = new PipBoundsHandler(mContext);
mPipSurfaceTransactionHelper = new PipSurfaceTransactionHelper(context, configController);
mPipTaskOrganizer = new PipTaskOrganizer(mContext, mPipBoundsHandler,
- mPipSurfaceTransactionHelper, divider, mDisplayController, pipUiEventLogger,
- shellTaskOrganizer);
+ mPipSurfaceTransactionHelper, splitScreenOptional, mDisplayController,
+ pipUiEventLogger, shellTaskOrganizer);
mPipTaskOrganizer.registerPipTransitionCallback(this);
mInputConsumerController = InputConsumerController.getPipInputConsumer();
mMediaController = new PipMediaController(context, mActivityManager, broadcastDispatcher);
diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
index 0531ca1..8d0948b 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
@@ -60,13 +60,14 @@
import com.android.systemui.shared.system.PinnedStackListenerForwarder.PinnedStackListener;
import com.android.systemui.shared.system.TaskStackChangeListener;
import com.android.systemui.shared.system.WindowManagerWrapper;
-import com.android.systemui.stackdivider.Divider;
+import com.android.systemui.stackdivider.SplitScreen;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayController;
import java.util.ArrayList;
import java.util.List;
+import java.util.Optional;
import javax.inject.Inject;
@@ -237,7 +238,7 @@
public PipManager(Context context, BroadcastDispatcher broadcastDispatcher,
ConfigurationController configController,
DisplayController displayController,
- Divider divider,
+ Optional<SplitScreen> splitScreenOptional,
@NonNull PipUiEventLogger pipUiEventLogger,
ShellTaskOrganizer shellTaskOrganizer) {
if (mInitialized) {
@@ -257,8 +258,8 @@
.getInteger(R.integer.config_pipResizeAnimationDuration);
mPipSurfaceTransactionHelper = new PipSurfaceTransactionHelper(context, configController);
mPipTaskOrganizer = new PipTaskOrganizer(mContext, mPipBoundsHandler,
- mPipSurfaceTransactionHelper, divider, displayController, pipUiEventLogger,
- shellTaskOrganizer);
+ mPipSurfaceTransactionHelper, splitScreenOptional, displayController,
+ pipUiEventLogger, shellTaskOrganizer);
mPipTaskOrganizer.registerPipTransitionCallback(this);
mActivityTaskManager = ActivityTaskManager.getService();
ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener);
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt
index 255ba1b..e57478e 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt
+++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt
@@ -57,7 +57,8 @@
@VisibleForTesting
internal companion object {
val OPS_MIC_CAMERA = intArrayOf(AppOpsManager.OP_CAMERA,
- AppOpsManager.OP_RECORD_AUDIO)
+ AppOpsManager.OP_PHONE_CALL_CAMERA, AppOpsManager.OP_RECORD_AUDIO,
+ AppOpsManager.OP_PHONE_CALL_MICROPHONE)
val OPS_LOCATION = intArrayOf(
AppOpsManager.OP_COARSE_LOCATION,
AppOpsManager.OP_FINE_LOCATION)
@@ -248,9 +249,11 @@
private fun toPrivacyItem(appOpItem: AppOpItem): PrivacyItem? {
val type: PrivacyType = when (appOpItem.code) {
+ AppOpsManager.OP_PHONE_CALL_CAMERA,
AppOpsManager.OP_CAMERA -> PrivacyType.TYPE_CAMERA
- AppOpsManager.OP_COARSE_LOCATION -> PrivacyType.TYPE_LOCATION
+ AppOpsManager.OP_COARSE_LOCATION,
AppOpsManager.OP_FINE_LOCATION -> PrivacyType.TYPE_LOCATION
+ AppOpsManager.OP_PHONE_CALL_MICROPHONE,
AppOpsManager.OP_RECORD_AUDIO -> PrivacyType.TYPE_MICROPHONE
else -> return null
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java
index 0347867..1a7e229 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java
@@ -38,7 +38,7 @@
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.shared.recents.IOverviewProxy;
import com.android.systemui.shared.system.ActivityManagerWrapper;
-import com.android.systemui.stackdivider.Divider;
+import com.android.systemui.stackdivider.SplitScreen;
import com.android.systemui.statusbar.phone.StatusBar;
import java.util.Optional;
@@ -56,7 +56,7 @@
private final static String TAG = "OverviewProxyRecentsImpl";
@Nullable
private final Lazy<StatusBar> mStatusBarLazy;
- private final Optional<Divider> mDividerOptional;
+ private final Optional<SplitScreen> mSplitScreenOptional;
private Context mContext;
private Handler mHandler;
@@ -66,9 +66,9 @@
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
@Inject
public OverviewProxyRecentsImpl(Optional<Lazy<StatusBar>> statusBarLazy,
- Optional<Divider> dividerOptional) {
+ Optional<SplitScreen> splitScreenOptional) {
mStatusBarLazy = statusBarLazy.orElse(null);
- mDividerOptional = dividerOptional;
+ mSplitScreenOptional = splitScreenOptional;
}
@Override
@@ -163,12 +163,12 @@
if (runningTask.supportsSplitScreenMultiWindow) {
if (ActivityManagerWrapper.getInstance().setTaskWindowingModeSplitScreenPrimary(
runningTask.id, stackCreateMode, initialBounds)) {
- mDividerOptional.ifPresent(Divider::onDockedTopTask);
-
- // The overview service is handling split screen, so just skip the wait for the
- // first draw and notify the divider to start animating now
- mDividerOptional.ifPresent(Divider::onRecentsDrawn);
-
+ mSplitScreenOptional.ifPresent(splitScreen -> {
+ splitScreen.onDockedTopTask();
+ // The overview service is handling split screen, so just skip the wait
+ // for the first draw and notify the divider to start animating now
+ splitScreen.onRecentsDrawn();
+ });
return true;
}
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index e931a6b..c0cc586 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -86,7 +86,7 @@
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.InputMonitorCompat;
import com.android.systemui.shared.system.QuickStepContract;
-import com.android.systemui.stackdivider.Divider;
+import com.android.systemui.stackdivider.SplitScreen;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.phone.StatusBar;
@@ -123,7 +123,7 @@
private final Context mContext;
private final PipUI mPipUI;
private final Optional<Lazy<StatusBar>> mStatusBarOptionalLazy;
- private final Optional<Divider> mDividerOptional;
+ private final Optional<SplitScreen> mSplitScreenOptional;
private SysUiState mSysUiState;
private final Handler mHandler;
private final Lazy<NavigationBarController> mNavBarControllerLazy;
@@ -232,7 +232,9 @@
}
long token = Binder.clearCallingIdentity();
try {
- mDividerOptional.ifPresent(Divider::onDockedFirstAnimationFrame);
+ mSplitScreenOptional.ifPresent(splitScreen -> {
+ splitScreen.onDockedFirstAnimationFrame();
+ });
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -262,8 +264,8 @@
}
long token = Binder.clearCallingIdentity();
try {
- return mDividerOptional.map(
- divider -> divider.getView().getNonMinimizedSplitScreenSecondaryBounds())
+ return mSplitScreenOptional.map(splitScreen ->
+ splitScreen.getDividerView().getNonMinimizedSplitScreenSecondaryBounds())
.orElse(null);
} finally {
Binder.restoreCallingIdentity(token);
@@ -399,10 +401,8 @@
@Override
public void setSplitScreenMinimized(boolean minimized) {
- Divider divider = mDividerOptional.get();
- if (divider != null) {
- divider.setMinimized(minimized);
- }
+ mSplitScreenOptional.ifPresent(
+ splitScreen -> splitScreen.setMinimized(minimized));
}
@Override
@@ -602,7 +602,7 @@
public OverviewProxyService(Context context, CommandQueue commandQueue,
Lazy<NavigationBarController> navBarControllerLazy, NavigationModeController navModeController,
NotificationShadeWindowController statusBarWinController, SysUiState sysUiState,
- PipUI pipUI, Optional<Divider> dividerOptional,
+ PipUI pipUI, Optional<SplitScreen> splitScreenOptional,
Optional<Lazy<StatusBar>> statusBarOptionalLazy, OneHandedUI oneHandedUI,
BroadcastDispatcher broadcastDispatcher) {
super(broadcastDispatcher);
@@ -613,7 +613,7 @@
mNavBarControllerLazy = navBarControllerLazy;
mStatusBarWinController = statusBarWinController;
mConnectionBackoffAttempts = 0;
- mDividerOptional = dividerOptional;
+ mSplitScreenOptional = splitScreenOptional;
mRecentsComponentName = ComponentName.unflattenFromString(context.getString(
com.android.internal.R.string.config_recentsComponentName));
mQuickStepIntent = new Intent(ACTION_QUICKSTEP)
@@ -755,10 +755,8 @@
startConnectionToCurrentUser();
// Clean up the minimized state if launcher dies
- Divider divider = mDividerOptional.get();
- if (divider != null) {
- divider.setMinimized(false);
- }
+ mSplitScreenOptional.ifPresent(
+ splitScreen -> splitScreen.setMinimized(false));
}
public void startConnectionToCurrentUser() {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImplementation.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImplementation.java
index 1d29ac6..a641730 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImplementation.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImplementation.java
@@ -35,7 +35,6 @@
default void showRecentApps(boolean triggeredFromAltTab) {}
default void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {}
default void toggleRecentApps() {}
- default void growRecents() {}
default boolean splitPrimaryTask(int stackCreateMode, Rect initialBounds,
int metricsDockAction) {
return false;
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
index 469c4a7..8ec3db5 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
@@ -21,7 +21,6 @@
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
-import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
@@ -70,7 +69,6 @@
private static final String ACTION_STOP_NOTIF =
"com.android.systemui.screenrecord.STOP_FROM_NOTIF";
private static final String ACTION_SHARE = "com.android.systemui.screenrecord.SHARE";
- private static final String ACTION_DELETE = "com.android.systemui.screenrecord.DELETE";
private final RecordingController mController;
private final KeyguardDismissUtil mKeyguardDismissUtil;
@@ -184,25 +182,6 @@
// Close quick shade
sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
break;
- case ACTION_DELETE:
- mKeyguardDismissUtil.executeWhenUnlocked(() -> {
- // Close quick shade
- sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
- ContentResolver resolver = getContentResolver();
- Uri uri = Uri.parse(intent.getStringExtra(EXTRA_PATH));
- resolver.delete(uri, null, null);
-
- Toast.makeText(
- this,
- R.string.screenrecord_delete_description,
- Toast.LENGTH_LONG).show();
- Log.d(TAG, "Deleted recording " + uri);
-
- // Remove notification
- mNotificationManager.cancelAsUser(null, NOTIFICATION_VIEW_ID, currentUser);
- return false;
- }, false);
- break;
}
return Service.START_STICKY;
}
@@ -312,16 +291,6 @@
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE))
.build();
- Notification.Action deleteAction = new Notification.Action.Builder(
- Icon.createWithResource(this, R.drawable.ic_screenrecord),
- getResources().getString(R.string.screenrecord_delete_label),
- PendingIntent.getService(
- this,
- REQUEST_CODE,
- getDeleteIntent(this, uri.toString()),
- PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE))
- .build();
-
Bundle extras = new Bundle();
extras.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME,
getResources().getString(R.string.screenrecord_name));
@@ -335,7 +304,6 @@
viewIntent,
PendingIntent.FLAG_IMMUTABLE))
.addAction(shareAction)
- .addAction(deleteAction)
.setAutoCancel(true)
.addExtras(extras);
@@ -414,11 +382,6 @@
.putExtra(EXTRA_PATH, path);
}
- private static Intent getDeleteIntent(Context context, String path) {
- return new Intent(context, RecordingService.class).setAction(ACTION_DELETE)
- .putExtra(EXTRA_PATH, path);
- }
-
@Override
public void onInfo(MediaRecorder mr, int what, int extra) {
Log.d(TAG, "Media recorder info: " + what);
diff --git a/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java b/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java
index ee3303b..0d92d1e 100644
--- a/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java
+++ b/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java
@@ -30,8 +30,10 @@
import com.android.systemui.SystemUI;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.recents.Recents;
-import com.android.systemui.stackdivider.Divider;
import com.android.systemui.stackdivider.DividerView;
+import com.android.systemui.stackdivider.SplitScreen;
+
+import java.util.Optional;
import javax.inject.Inject;
@@ -43,7 +45,7 @@
implements ShortcutKeyServiceProxy.Callbacks {
private static final String TAG = "ShortcutKeyDispatcher";
- private final Divider mDivider;
+ private final Optional<SplitScreen> mSplitScreenOptional;
private final Recents mRecents;
private ShortcutKeyServiceProxy mShortcutKeyServiceProxy = new ShortcutKeyServiceProxy(this);
@@ -58,14 +60,16 @@
protected final long SC_DOCK_RIGHT = META_MASK | KeyEvent.KEYCODE_RIGHT_BRACKET;
@Inject
- public ShortcutKeyDispatcher(Context context, Divider divider, Recents recents) {
+ public ShortcutKeyDispatcher(Context context,
+ Optional<SplitScreen> splitScreenOptional, Recents recents) {
super(context);
- mDivider = divider;
+ mSplitScreenOptional = splitScreenOptional;
mRecents = recents;
}
/**
* Registers a shortcut key to window manager.
+ *
* @param shortcutCode packed representation of shortcut key code and meta information
*/
public void registerShortcutKey(long shortcutCode) {
@@ -92,24 +96,28 @@
}
private void handleDockKey(long shortcutCode) {
- if (mDivider == null || !mDivider.isDividerVisible()) {
- // Split the screen
- mRecents.splitPrimaryTask((shortcutCode == SC_DOCK_LEFT)
- ? SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT
- : SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT, null, -1);
- } else {
- // If there is already a docked window, we respond by resizing the docking pane.
- DividerView dividerView = mDivider.getView();
- DividerSnapAlgorithm snapAlgorithm = dividerView.getSnapAlgorithm();
- int dividerPosition = dividerView.getCurrentPosition();
- DividerSnapAlgorithm.SnapTarget currentTarget =
- snapAlgorithm.calculateNonDismissingSnapTarget(dividerPosition);
- DividerSnapAlgorithm.SnapTarget target = (shortcutCode == SC_DOCK_LEFT)
- ? snapAlgorithm.getPreviousTarget(currentTarget)
- : snapAlgorithm.getNextTarget(currentTarget);
- dividerView.startDragging(true /* animate */, false /* touching */);
- dividerView.stopDragging(target.position, 0f, false /* avoidDismissStart */,
- true /* logMetrics */);
+ if (mSplitScreenOptional.isPresent()) {
+ SplitScreen splitScreen = mSplitScreenOptional.get();
+ if (splitScreen.isDividerVisible()) {
+ // If there is already a docked window, we respond by resizing the docking pane.
+ DividerView dividerView = splitScreen.getDividerView();
+ DividerSnapAlgorithm snapAlgorithm = dividerView.getSnapAlgorithm();
+ int dividerPosition = dividerView.getCurrentPosition();
+ DividerSnapAlgorithm.SnapTarget currentTarget =
+ snapAlgorithm.calculateNonDismissingSnapTarget(dividerPosition);
+ DividerSnapAlgorithm.SnapTarget target = (shortcutCode == SC_DOCK_LEFT)
+ ? snapAlgorithm.getPreviousTarget(currentTarget)
+ : snapAlgorithm.getNextTarget(currentTarget);
+ dividerView.startDragging(true /* animate */, false /* touching */);
+ dividerView.stopDragging(target.position, 0f, false /* avoidDismissStart */,
+ true /* logMetrics */);
+ return;
+ }
}
+
+ // Split the screen
+ mRecents.splitPrimaryTask((shortcutCode == SC_DOCK_LEFT)
+ ? SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT
+ : SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT, null, -1);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
deleted file mode 100644
index e9c880e..0000000
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (C) 2015 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.stackdivider;
-
-import static com.android.systemui.shared.system.WindowManagerWrapper.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
-
-import android.app.ActivityManager;
-import android.content.Context;
-import android.window.WindowContainerToken;
-
-import com.android.systemui.SystemUI;
-import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.shared.system.ActivityManagerWrapper;
-import com.android.systemui.shared.system.TaskStackChangeListener;
-import com.android.systemui.statusbar.policy.KeyguardStateController;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.function.Consumer;
-
-/**
- * Controls the docked stack divider.
- */
-@SysUISingleton
-public class Divider extends SystemUI {
- private final KeyguardStateController mKeyguardStateController;
- private final DividerController mDividerController;
-
- Divider(Context context, DividerController dividerController,
- KeyguardStateController keyguardStateController) {
- super(context);
- mDividerController = dividerController;
- mKeyguardStateController = keyguardStateController;
- }
-
- @Override
- public void start() {
- mDividerController.start();
- // Hide the divider when keyguard is showing. Even though keyguard/statusbar is above
- // everything, it is actually transparent except for notifications, so we still need to
- // hide any surfaces that are below it.
- // TODO(b/148906453): Figure out keyguard dismiss animation for divider view.
- mKeyguardStateController.addCallback(new KeyguardStateController.Callback() {
- @Override
- public void onKeyguardShowingChanged() {
- mDividerController.onKeyguardShowingChanged(mKeyguardStateController.isShowing());
- }
- });
- // Don't initialize the divider or anything until we get the default display.
-
- ActivityManagerWrapper.getInstance().registerTaskStackListener(
- new TaskStackChangeListener() {
- @Override
- public void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task,
- boolean homeTaskVisible, boolean clearedTask, boolean wasVisible) {
- if (!wasVisible || task.configuration.windowConfiguration.getWindowingMode()
- != WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
- || !mDividerController.isSplitScreenSupported()) {
- return;
- }
-
- if (mDividerController.isMinimized()) {
- onUndockingTask();
- }
- }
-
- @Override
- public void onActivityForcedResizable(String packageName, int taskId,
- int reason) {
- mDividerController.onActivityForcedResizable(packageName, taskId, reason);
- }
-
- @Override
- public void onActivityDismissingDockedStack() {
- mDividerController.onActivityDismissingSplitScreen();
- }
-
- @Override
- public void onActivityLaunchOnSecondaryDisplayFailed() {
- mDividerController.onActivityLaunchOnSecondaryDisplayFailed();
- }
- }
- );
- }
-
- @Override
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- mDividerController.dump(pw);
- }
-
- /** Switch to minimized state if appropriate. */
- public void setMinimized(final boolean minimized) {
- mDividerController.setMinimized(minimized);
- }
-
- public boolean isMinimized() {
- return mDividerController.isMinimized();
- }
-
- public boolean isHomeStackResizable() {
- return mDividerController.isHomeStackResizable();
- }
-
- /** Callback for undocking task. */
- public void onUndockingTask() {
- mDividerController.onUndockingTask();
- }
-
- public void onRecentsDrawn() {
- mDividerController.onRecentsDrawn();
- }
-
- public void onDockedFirstAnimationFrame() {
- mDividerController.onDockedFirstAnimationFrame();
- }
-
- public void onDockedTopTask() {
- mDividerController.onDockedTopTask();
- }
-
- public void onAppTransitionFinished() {
- mDividerController.onAppTransitionFinished();
- }
-
- public DividerView getView() {
- return mDividerController.getDividerView();
- }
-
- /** @return the container token for the secondary split root task. */
- public WindowContainerToken getSecondaryRoot() {
- return mDividerController.getSecondaryRoot();
- }
-
- /** Register a listener that gets called whenever the existence of the divider changes */
- public void registerInSplitScreenListener(Consumer<Boolean> listener) {
- mDividerController.registerInSplitScreenListener(listener);
- }
-
- /** {@code true} if this is visible */
- public boolean isDividerVisible() {
- return mDividerController.isDividerVisible();
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerImeController.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerImeController.java
index c915f07..64ee7ed5 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerImeController.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerImeController.java
@@ -38,7 +38,7 @@
class DividerImeController implements DisplayImeController.ImePositionProcessor {
private static final String TAG = "DividerImeController";
- private static final boolean DEBUG = DividerController.DEBUG;
+ private static final boolean DEBUG = SplitScreenController.DEBUG;
private static final float ADJUSTED_NONFOCUS_DIM = 0.3f;
@@ -100,15 +100,15 @@
}
private DividerView getView() {
- return mSplits.mDividerController.getDividerView();
+ return mSplits.mSplitScreenController.getDividerView();
}
private SplitDisplayLayout getLayout() {
- return mSplits.mDividerController.getSplitLayout();
+ return mSplits.mSplitScreenController.getSplitLayout();
}
private boolean isDividerVisible() {
- return mSplits.mDividerController.isDividerVisible();
+ return mSplits.mSplitScreenController.isDividerVisible();
}
private boolean getSecondaryHasFocus(int displayId) {
@@ -151,7 +151,7 @@
mSecondaryHasFocus = getSecondaryHasFocus(displayId);
final boolean targetAdjusted = splitIsVisible && imeShouldShow && mSecondaryHasFocus
&& !imeIsFloating && !getLayout().mDisplayLayout.isLandscape()
- && !mSplits.mDividerController.isMinimized();
+ && !mSplits.mSplitScreenController.isMinimized();
if (mLastAdjustTop < 0) {
mLastAdjustTop = imeShouldShow ? hiddenTop : shownTop;
} else if (mLastAdjustTop != (imeShouldShow ? mShownTop : mHiddenTop)) {
@@ -236,7 +236,7 @@
SCREEN_WIDTH_DP_UNDEFINED, SCREEN_HEIGHT_DP_UNDEFINED);
}
- if (!mSplits.mDividerController.getWmProxy().queueSyncTransactionIfWaiting(wct)) {
+ if (!mSplits.mSplitScreenController.getWmProxy().queueSyncTransactionIfWaiting(wct)) {
WindowOrganizer.applyTransaction(wct);
}
}
@@ -250,7 +250,7 @@
: DisplayImeController.ANIMATION_DURATION_HIDE_MS);
}
}
- mSplits.mDividerController.setAdjustedForIme(mTargetShown && !mPaused);
+ mSplits.mSplitScreenController.setAdjustedForIme(mTargetShown && !mPaused);
}
public void updateAdjustForIme() {
@@ -402,7 +402,7 @@
mTargetAdjusted = mPausedTargetAdjusted;
updateDimTargets();
final DividerView view = getView();
- if ((mTargetAdjusted != mAdjusted) && !mSplits.mDividerController.isMinimized()
+ if ((mTargetAdjusted != mAdjusted) && !mSplits.mSplitScreenController.isMinimized()
&& view != null) {
// End unminimize animations since they conflict with adjustment animations.
view.finishAnimations();
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerModule.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerModule.java
deleted file mode 100644
index 9acb96b..0000000
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerModule.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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.stackdivider;
-
-import android.content.Context;
-import android.os.Handler;
-
-import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.statusbar.policy.KeyguardStateController;
-import com.android.wm.shell.ShellTaskOrganizer;
-import com.android.wm.shell.common.DisplayController;
-import com.android.wm.shell.common.DisplayImeController;
-import com.android.wm.shell.common.SystemWindows;
-import com.android.wm.shell.common.TransactionPool;
-
-import dagger.Module;
-import dagger.Provides;
-
-/**
- * Module which provides a Divider.
- */
-@Module
-public class DividerModule {
- @SysUISingleton
- @Provides
- static Divider provideDivider(Context context, DisplayController displayController,
- SystemWindows systemWindows, DisplayImeController imeController, @Main Handler handler,
- KeyguardStateController keyguardStateController, TransactionPool transactionPool,
- ShellTaskOrganizer shellTaskOrganizer) {
- // TODO(b/161116823): fetch DividerProxy from WM shell lib.
- DividerController dividerController = new DividerController(context, displayController,
- systemWindows, imeController, handler, transactionPool, shellTaskOrganizer);
- return new Divider(context, dividerController, keyguardStateController);
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
index e5c02d6..95f048b 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
@@ -76,7 +76,7 @@
public class DividerView extends FrameLayout implements OnTouchListener,
OnComputeInternalInsetsListener {
private static final String TAG = "DividerView";
- private static final boolean DEBUG = DividerController.DEBUG;
+ private static final boolean DEBUG = SplitScreenController.DEBUG;
public interface DividerCallbacks {
void onDraggingStart();
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java b/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java
index ff8bab0..4c26694 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java
@@ -69,9 +69,9 @@
}
public ForcedResizableInfoActivityController(Context context,
- DividerController dividerController) {
+ SplitScreenController splitScreenController) {
mContext = context;
- dividerController.registerInSplitScreenListener(mDockedStackExistsListener);
+ splitScreenController.registerInSplitScreenListener(mDockedStackExistsListener);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreen.java b/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreen.java
new file mode 100644
index 0000000..91850cc
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreen.java
@@ -0,0 +1,86 @@
+/*
+ * 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.stackdivider;
+
+import android.window.WindowContainerToken;
+
+import java.io.PrintWriter;
+import java.util.function.Consumer;
+
+/**
+ * Interface to engage split screen feature.
+ */
+public interface SplitScreen {
+ /** Returns {@code true} if split screen is supported on the device. */
+ boolean isSplitScreenSupported();
+
+ /** Called when keyguard showing state changed. */
+ void onKeyguardVisibilityChanged(boolean isShowing);
+
+ /** Returns {@link DividerView}. */
+ DividerView getDividerView();
+
+ /** Returns {@code true} if one of the split screen is in minimized mode. */
+ boolean isMinimized();
+
+ /** Returns {@code true} if the home stack is resizable. */
+ boolean isHomeStackResizable();
+
+ /** Returns {@code true} if the divider is visible. */
+ boolean isDividerVisible();
+
+ /** Switch to minimized state if appropriate. */
+ void setMinimized(boolean minimized);
+
+ /**
+ * Workaround for b/62528361, at the time recents has drawn, it may happen before a
+ * configuration change to the Divider, and internally, the event will be posted to the
+ * subscriber, or DividerView, which has been removed and prevented from resizing. Instead,
+ * register the event handler here and proxy the event to the current DividerView.
+ */
+ void onRecentsDrawn();
+
+ /** Called when there's an activity forced resizable. */
+ void onActivityForcedResizable(String packageName, int taskId, int reason);
+
+ /** Called when there's an activity dismissing split screen. */
+ void onActivityDismissingSplitScreen();
+
+ /** Called when there's an activity launch on secondary display failed. */
+ void onActivityLaunchOnSecondaryDisplayFailed();
+
+ /** Called when there's a task undocking. */
+ void onUndockingTask();
+
+ /** Called when the first docked animation frame rendered. */
+ void onDockedFirstAnimationFrame();
+
+ /** Called when top task docked. */
+ void onDockedTopTask();
+
+ /** Called when app transition finished. */
+ void onAppTransitionFinished();
+
+ /** Dumps current status of Split Screen. */
+ void dump(PrintWriter pw);
+
+ /** Registers listener that gets called whenever the existence of the divider changes. */
+ void registerInSplitScreenListener(Consumer<Boolean> listener);
+
+ /** @return the container token for the secondary split root task. */
+ WindowContainerToken getSecondaryRoot();
+}
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerController.java b/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenController.java
similarity index 96%
rename from packages/SystemUI/src/com/android/systemui/stackdivider/DividerController.java
rename to packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenController.java
index 9b5833b..11773f6 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerController.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenController.java
@@ -49,26 +49,34 @@
import java.util.function.Consumer;
/**
- * Controls the docked stack divider.
+ * Controls split screen feature.
*/
-public class DividerController implements DisplayController.OnDisplaysChangedListener {
+public class SplitScreenController implements SplitScreen,
+ DisplayController.OnDisplaysChangedListener {
static final boolean DEBUG = false;
- private static final String TAG = "Divider";
- static final int DEFAULT_APP_TRANSITION_DURATION = 336;
+ private static final String TAG = "Divider";
+ private static final int DEFAULT_APP_TRANSITION_DURATION = 336;
+
+ private final Context mContext;
+ private final DisplayChangeController.OnDisplayChangingListener mRotationController;
+ private final DisplayController mDisplayController;
+ private final DisplayImeController mImeController;
+ private final DividerImeController mImePositionProcessor;
+ private final DividerState mDividerState = new DividerState();
+ private final ForcedResizableInfoActivityController mForcedResizableController;
+ private final Handler mHandler;
+ private final SplitScreenTaskOrganizer mSplits;
+ private final SystemWindows mSystemWindows;
+ final TransactionPool mTransactionPool;
+ private final WindowManagerProxy mWindowManagerProxy;
+
+ private final ArrayList<WeakReference<Consumer<Boolean>>> mDockedStackExistsListeners =
+ new ArrayList<>();
+
private DividerWindowManager mWindowManager;
private DividerView mView;
- private final DividerState mDividerState = new DividerState();
- private boolean mVisible = false;
- private boolean mMinimized = false;
- private boolean mAdjustedForIme = false;
- private boolean mHomeStackResizable = false;
- private ForcedResizableInfoActivityController mForcedResizableController;
- private SystemWindows mSystemWindows;
- private DisplayController mDisplayController;
- private DisplayImeController mImeController;
- final TransactionPool mTransactionPool;
// Keeps track of real-time split geometry including snap positions and ime adjustments
private SplitDisplayLayout mSplitLayout;
@@ -78,19 +86,13 @@
// layout that we sent back to WM.
private SplitDisplayLayout mRotateSplitLayout;
- private final Handler mHandler;
- private final WindowManagerProxy mWindowManagerProxy;
-
- private final ArrayList<WeakReference<Consumer<Boolean>>> mDockedStackExistsListeners =
- new ArrayList<>();
-
- private final SplitScreenTaskOrganizer mSplits;
- private final DisplayChangeController.OnDisplayChangingListener mRotationController;
- private final DividerImeController mImePositionProcessor;
- private final Context mContext;
private boolean mIsKeyguardShowing;
+ private boolean mVisible = false;
+ private boolean mMinimized = false;
+ private boolean mAdjustedForIme = false;
+ private boolean mHomeStackResizable = false;
- public DividerController(Context context,
+ public SplitScreenController(Context context,
DisplayController displayController, SystemWindows systemWindows,
DisplayImeController imeController, Handler handler, TransactionPool transactionPool,
ShellTaskOrganizer shellTaskOrganizer) {
@@ -142,10 +144,7 @@
wct.merge(t, true /* transfer */);
}
};
- }
- /** Inits the divider service. */
- public void start() {
mWindowManager = new DividerWindowManager(mSystemWindows);
mDisplayController.addDisplayWindowListener(this);
// Don't initialize the divider or anything until we get the default display.
@@ -157,15 +156,15 @@
}
/** Called when keyguard showing state changed. */
- public void onKeyguardShowingChanged(boolean isShowing) {
+ public void onKeyguardVisibilityChanged(boolean showing) {
if (!isSplitActive() || mView == null) {
return;
}
- mView.setHidden(isShowing);
- if (!isShowing) {
+ mView.setHidden(showing);
+ if (!showing) {
mImePositionProcessor.updateAdjustForIme();
}
- mIsKeyguardShowing = isShowing;
+ mIsKeyguardShowing = showing;
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java b/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java
index ffd0c7c..325c559 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java
@@ -37,7 +37,7 @@
class SplitScreenTaskOrganizer implements ShellTaskOrganizer.TaskListener {
private static final String TAG = "SplitScreenTaskOrg";
- private static final boolean DEBUG = DividerController.DEBUG;
+ private static final boolean DEBUG = SplitScreenController.DEBUG;
private final ShellTaskOrganizer mTaskOrganizer;
@@ -48,14 +48,14 @@
SurfaceControl mPrimaryDim;
SurfaceControl mSecondaryDim;
Rect mHomeBounds = new Rect();
- final DividerController mDividerController;
+ final SplitScreenController mSplitScreenController;
private boolean mSplitScreenSupported = false;
final SurfaceSession mSurfaceSession = new SurfaceSession();
- SplitScreenTaskOrganizer(DividerController dividerController,
+ SplitScreenTaskOrganizer(SplitScreenController splitScreenController,
ShellTaskOrganizer shellTaskOrganizer) {
- mDividerController = dividerController;
+ mSplitScreenController = splitScreenController;
mTaskOrganizer = shellTaskOrganizer;
mTaskOrganizer.addListener(this, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY,
WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
@@ -81,11 +81,11 @@
}
SurfaceControl.Transaction getTransaction() {
- return mDividerController.mTransactionPool.acquire();
+ return mSplitScreenController.mTransactionPool.acquire();
}
void releaseTransaction(SurfaceControl.Transaction t) {
- mDividerController.mTransactionPool.release(t);
+ mSplitScreenController.mTransactionPool.release(t);
}
@Override
@@ -146,7 +146,7 @@
t.apply();
releaseTransaction(t);
- mDividerController.onTaskVanished();
+ mSplitScreenController.onTaskVanished();
}
}
}
@@ -156,7 +156,7 @@
if (taskInfo.displayId != DEFAULT_DISPLAY) {
return;
}
- mDividerController.post(() -> handleTaskInfoChanged(taskInfo));
+ mSplitScreenController.post(() -> handleTaskInfoChanged(taskInfo));
}
/**
@@ -175,7 +175,7 @@
}
final boolean secondaryImpliedMinimize = mSecondary.topActivityType == ACTIVITY_TYPE_HOME
|| (mSecondary.topActivityType == ACTIVITY_TYPE_RECENTS
- && mDividerController.isHomeStackResizable());
+ && mSplitScreenController.isHomeStackResizable());
final boolean primaryWasEmpty = mPrimary.topActivityType == ACTIVITY_TYPE_UNDEFINED;
final boolean secondaryWasEmpty = mSecondary.topActivityType == ACTIVITY_TYPE_UNDEFINED;
if (info.token.asBinder() == mPrimary.token.asBinder()) {
@@ -187,7 +187,7 @@
final boolean secondaryIsEmpty = mSecondary.topActivityType == ACTIVITY_TYPE_UNDEFINED;
final boolean secondaryImpliesMinimize = mSecondary.topActivityType == ACTIVITY_TYPE_HOME
|| (mSecondary.topActivityType == ACTIVITY_TYPE_RECENTS
- && mDividerController.isHomeStackResizable());
+ && mSplitScreenController.isHomeStackResizable());
if (DEBUG) {
Log.d(TAG, "onTaskInfoChanged " + mPrimary + " " + mSecondary);
}
@@ -203,14 +203,14 @@
Log.d(TAG, " at-least one split empty " + mPrimary.topActivityType
+ " " + mSecondary.topActivityType);
}
- if (mDividerController.isDividerVisible()) {
+ if (mSplitScreenController.isDividerVisible()) {
// Was in split-mode, which means we are leaving split, so continue that.
// This happens when the stack in the primary-split is dismissed.
if (DEBUG) {
Log.d(TAG, " was in split, so this means leave it "
+ mPrimary.topActivityType + " " + mSecondary.topActivityType);
}
- mDividerController.startDismissSplit();
+ mSplitScreenController.startDismissSplit();
} else if (!primaryIsEmpty && primaryWasEmpty && secondaryWasEmpty) {
// Wasn't in split-mode (both were empty), but now that the primary split is
// populated, we should fully enter split by moving everything else into secondary.
@@ -219,15 +219,15 @@
if (DEBUG) {
Log.d(TAG, " was not in split, but primary is populated, so enter it");
}
- mDividerController.startEnterSplit();
+ mSplitScreenController.startEnterSplit();
}
} else if (secondaryImpliesMinimize) {
// Both splits are populated but the secondary split has a home/recents stack on top,
// so enter minimized mode.
- mDividerController.ensureMinimizedSplit();
+ mSplitScreenController.ensureMinimizedSplit();
} else {
// Both splits are populated by normal activities, so make sure we aren't minimized.
- mDividerController.ensureNormalSplit();
+ mSplitScreenController.ensureNormalSplit();
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/SyncTransactionQueue.java b/packages/SystemUI/src/com/android/systemui/stackdivider/SyncTransactionQueue.java
index f2500e5..13ed02e 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/SyncTransactionQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/SyncTransactionQueue.java
@@ -33,7 +33,7 @@
* Helper for serializing sync-transactions and corresponding callbacks.
*/
class SyncTransactionQueue {
- private static final boolean DEBUG = DividerController.DEBUG;
+ private static final boolean DEBUG = SplitScreenController.DEBUG;
private static final String TAG = "SyncTransactionQueue";
// Just a little longer than the sync-engine timeout of 5s
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationPresenter.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationPresenter.java
index 1079f10..17bf346 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationPresenter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationPresenter.java
@@ -55,14 +55,6 @@
void updateNotificationViews(String reason);
/**
- * Returns the maximum number of notifications to show while locked.
- *
- * @param recompute whether something has changed that means we should recompute this value
- * @return the maximum number of notifications to show while locked
- */
- int getMaxNotificationsWhileLocked(boolean recompute);
-
- /**
* Called when the row states are updated by {@link NotificationViewHierarchyManager}.
*/
void onUpdateRowStates();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelfController.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelfController.java
index 77abcfa..1e935c1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelfController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelfController.java
@@ -85,6 +85,10 @@
return mView.getShelfIcons();
}
+ public @View.Visibility int getVisibility() {
+ return mView.getVisibility();
+ };
+
public void setCollapsedIcons(NotificationIconContainer notificationIcons) {
mView.setCollapsedIcons(notificationIcons);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
index 1cd1b60..852c055 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
@@ -420,11 +420,6 @@
int visibleNotifications = 0;
boolean onKeyguard = mStatusBarStateController.getState() == StatusBarState.KEYGUARD;
- int maxNotifications = -1;
- if (onKeyguard && !mBypassController.getBypassEnabled()) {
- maxNotifications = mPresenter.getMaxNotificationsWhileLocked(true /* recompute */);
- }
- mListContainer.setMaxDisplayedNotifications(maxNotifications);
Stack<ExpandableNotificationRow> stack = new Stack<>();
for (int i = N - 1; i >= 0; i--) {
View child = mListContainer.getContainerChildAt(i);
@@ -439,8 +434,6 @@
boolean isChildNotification =
mGroupManager.isChildInGroupWithSummary(entry.getSbn());
- row.setOnKeyguard(onKeyguard);
-
if (!onKeyguard) {
// If mAlwaysExpandNonGroupedNotification is false, then only expand the
// very first notification and if it's not a child of grouped notifications.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java
index ea614fb..838cf0c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java
@@ -55,12 +55,13 @@
import com.android.systemui.SystemUI;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.UiBackground;
-import com.android.systemui.stackdivider.Divider;
+import com.android.systemui.stackdivider.SplitScreen;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.NotificationChannels;
import java.util.List;
+import java.util.Optional;
import java.util.concurrent.Executor;
import javax.inject.Inject;
@@ -80,13 +81,13 @@
private final CommandQueue mCommandQueue;
private boolean mDockedStackExists;
private KeyguardStateController mKeyguardStateController;
- private final Divider mDivider;
+ private final Optional<SplitScreen> mSplitScreenOptional;
@Inject
public InstantAppNotifier(Context context, CommandQueue commandQueue,
- @UiBackground Executor uiBgExecutor, Divider divider) {
+ @UiBackground Executor uiBgExecutor, Optional<SplitScreen> splitScreenOptional) {
super(context);
- mDivider = divider;
+ mSplitScreenOptional = splitScreenOptional;
mCommandQueue = commandQueue;
mUiBgExecutor = uiBgExecutor;
}
@@ -105,11 +106,11 @@
mCommandQueue.addCallback(this);
mKeyguardStateController.addCallback(this);
- mDivider.registerInSplitScreenListener(
- exists -> {
+ mSplitScreenOptional.ifPresent(splitScreen ->
+ splitScreen.registerInSplitScreenListener(exists -> {
mDockedStackExists = exists;
updateForegroundInstantApps();
- });
+ }));
// Clear out all old notifications on startup (only present in the case where sysui dies)
NotificationManager noMan = mContext.getSystemService(NotificationManager.class);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java
index 7c061aa..e5425cf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java
@@ -140,7 +140,7 @@
.build();
ExpandableNotificationRowController rowController =
component.getExpandableNotificationRowController();
- rowController.init();
+ rowController.init(entry);
entry.setRowController(rowController);
bindRow(entry, row);
updateRow(entry, row);
@@ -160,7 +160,6 @@
mNotificationRemoteInputManager.bindRow(row);
row.setOnActivatedListener(mPresenter);
entry.setRow(row);
- row.setEntry(entry);
mNotifBindPipeline.manageRow(entry, row);
mBindRowCallback.onBindRow(row);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index 9c09cba..46b4973 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -141,7 +141,7 @@
void onExpansionChanged(boolean isExpanded);
}
- private StatusBarStateController mStatusbarStateController;
+ private StatusBarStateController mStatusBarStateController;
private KeyguardBypassController mBypassController;
private LayoutListener mLayoutListener;
private RowContentBindStage mRowContentBindStage;
@@ -463,16 +463,6 @@
}
/**
- * Set the entry for the row.
- *
- * @param entry the entry this row is tied to
- */
- public void setEntry(@NonNull NotificationEntry entry) {
- mEntry = entry;
- cacheIsSystemNotification();
- }
-
- /**
* Marks a content view as freeable, setting it so that future inflations do not reinflate
* and ensuring that the view is freed when it is safe to remove.
*
@@ -1584,6 +1574,7 @@
* Initialize row.
*/
public void initialize(
+ NotificationEntry entry,
String appName,
String notificationKey,
ExpansionLogger logger,
@@ -1598,6 +1589,7 @@
StatusBarStateController statusBarStateController,
PeopleNotificationIdentifier peopleNotificationIdentifier,
OnUserInteractionCallback onUserInteractionCallback) {
+ mEntry = entry;
mAppName = appName;
if (mMenuRow == null) {
mMenuRow = new NotificationMenuRow(mContext, peopleNotificationIdentifier);
@@ -1616,12 +1608,15 @@
mMediaManager = notificationMediaManager;
setOnFeedbackClickListener(onFeedbackClickListener);
mFalsingManager = falsingManager;
- mStatusbarStateController = statusBarStateController;
+ mStatusBarStateController = statusBarStateController;
+
mPeopleNotificationIdentifier = peopleNotificationIdentifier;
for (NotificationContentView l : mLayouts) {
l.setPeopleNotificationIdentifier(mPeopleNotificationIdentifier);
}
mOnUserInteractionCallback = onUserInteractionCallback;
+
+ cacheIsSystemNotification();
}
private void initDimens() {
@@ -2134,8 +2129,8 @@
*/
@Override
public boolean isSoundEffectsEnabled() {
- final boolean mute = mStatusbarStateController != null
- && mStatusbarStateController.isDozing()
+ final boolean mute = mStatusBarStateController != null
+ && mStatusBarStateController.isDozing()
&& mSecureStateProvider != null &&
!mSecureStateProvider.getAsBoolean();
return !mute && super.isSoundEffectsEnabled();
@@ -2259,10 +2254,7 @@
}
}
- /**
- * @param onKeyguard whether to prevent notification expansion
- */
- public void setOnKeyguard(boolean onKeyguard) {
+ void setOnKeyguard(boolean onKeyguard) {
if (onKeyguard != mOnKeyguard) {
boolean wasAboveShelf = isAboveShelf();
final boolean wasExpanded = isExpanded();
@@ -2331,7 +2323,7 @@
}
private boolean isDozing() {
- return mStatusbarStateController != null && mStatusbarStateController.isDozing();
+ return mStatusBarStateController != null && mStatusBarStateController.isDozing();
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
index f8bc2be..ce760cb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
@@ -18,6 +18,7 @@
import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME;
import static com.android.systemui.statusbar.NotificationRemoteInputManager.ENABLE_REMOTE_INPUT;
+import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
import android.view.View;
import android.view.ViewGroup;
@@ -29,6 +30,7 @@
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.statusbar.NotificationMediaManager;
+import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.render.NodeController;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
@@ -118,9 +120,10 @@
/**
* Initialize the controller.
*/
- public void init() {
+ public void init(NotificationEntry entry) {
mActivatableNotificationViewController.init();
mView.initialize(
+ entry,
mAppName,
mNotificationKey,
mExpansionLogger,
@@ -135,7 +138,15 @@
mStatusBarStateController,
mPeopleNotificationIdentifier,
mOnUserInteractionCallback
+
);
+ mStatusBarStateController.addCallback(new StatusBarStateController.StateListener() {
+ @Override
+ public void onStateChanged(int newState) {
+ mView.setOnKeyguard(newState == KEYGUARD);
+ }
+ });
+ mView.setOnKeyguard(mStatusBarStateController.getState() == KEYGUARD);
mView.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
if (mAllowLongPress) {
mView.setLongPressListener((v, x, y, item) -> {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
index 11e698b..d5e5531 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
@@ -42,7 +42,7 @@
private static final float MAX_PULSE_HEIGHT = 100000f;
private final SectionProvider mSectionProvider;
- private ArrayList<ExpandableView> mDraggedViews = new ArrayList<>();
+ private ArrayList<View> mDraggedViews = new ArrayList<>();
private int mScrollY;
private int mAnchorViewIndex;
private int mAnchorViewY;
@@ -164,7 +164,7 @@
}
/** Call when dragging begins. */
- public void onBeginDrag(ExpandableView view) {
+ public void onBeginDrag(View view) {
mDraggedViews.add(view);
}
@@ -172,7 +172,7 @@
mDraggedViews.remove(view);
}
- public ArrayList<ExpandableView> getDraggedViews() {
+ public ArrayList<View> getDraggedViews() {
return mDraggedViews;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index e061472..b1a9efe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -44,7 +44,6 @@
import android.graphics.Color;
import android.graphics.Outline;
import android.graphics.Paint;
-import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
@@ -54,7 +53,6 @@
import android.os.UserHandle;
import android.provider.Settings;
import android.service.notification.NotificationListenerService;
-import android.service.notification.StatusBarNotification;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
@@ -94,11 +92,8 @@
import com.android.systemui.ExpandHelper;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
-import com.android.systemui.SwipeHelper;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
-import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.MenuItem;
-import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.OnMenuEventListener;
import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.DragDownHelper.DragDownCallback;
@@ -185,13 +180,12 @@
* gap is drawn between them). In this case we don't want to round their corners.
*/
private static final int DISTANCE_BETWEEN_ADJACENT_SECTIONS_PX = 1;
- private OnMenuEventListener mMenuEventListener;
private KeyguardBypassEnabledProvider mKeyguardBypassEnabledProvider;
private final DynamicPrivacyController mDynamicPrivacyController;
private final SysuiStatusBarStateController mStatusbarStateController;
private ExpandHelper mExpandHelper;
- private final NotificationSwipeHelper mSwipeHelper;
+ private NotificationSwipeHelper mSwipeHelper;
private int mCurrentStackHeight = Integer.MAX_VALUE;
private final Paint mBackgroundPaint = new Paint();
private final boolean mShouldDrawNotificationBackground;
@@ -244,7 +238,7 @@
/**
* The algorithm which calculates the properties for our children
*/
- protected final StackScrollAlgorithm mStackScrollAlgorithm;
+ private final StackScrollAlgorithm mStackScrollAlgorithm;
private final AmbientState mAmbientState;
private NotificationGroupManager mGroupManager;
@@ -609,31 +603,9 @@
mExpandHelper.setEventSource(this);
mExpandHelper.setScrollAdapter(mScrollAdapter);
- // TODO: move swipe helper into controller.
- // The anonymous proxy through to mMenuEventListener is temporary until more can be moved
- // into the controller.
- mSwipeHelper = new NotificationSwipeHelper(SwipeHelper.X, mNotificationCallback,
- getContext(), new OnMenuEventListener() {
- @Override
- public void onMenuClicked(View row, int x, int y, MenuItem menu) {
- mMenuEventListener.onMenuClicked(row, x, y, menu);
- }
-
- @Override
- public void onMenuReset(View row) {
- mMenuEventListener.onMenuReset(row);
- }
-
- @Override
- public void onMenuShown(View row) {
- mMenuEventListener.onMenuShown(row);
- }
- }, mFalsingManager);
mStackScrollAlgorithm = createStackScrollAlgorithm(context);
mShouldDrawNotificationBackground =
res.getBoolean(R.bool.config_drawNotificationBackground);
- mFadeNotificationsOnDismiss =
- res.getBoolean(R.bool.config_fadeNotificationsOnDismiss);
setOutlineProvider(mOutlineProvider);
// Blocking helper manager wants to know the expanded state, update as well.
@@ -1004,14 +976,16 @@
}
private void reinitView() {
- initView(getContext(), mKeyguardBypassEnabledProvider);
+ initView(getContext(), mKeyguardBypassEnabledProvider, mSwipeHelper);
}
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
void initView(Context context,
- KeyguardBypassEnabledProvider keyguardBypassEnabledProvider) {
+ KeyguardBypassEnabledProvider keyguardBypassEnabledProvider,
+ NotificationSwipeHelper swipeHelper) {
mScroller = new OverScroller(getContext());
mKeyguardBypassEnabledProvider = keyguardBypassEnabledProvider;
+ mSwipeHelper = swipeHelper;
setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);
setClipChildren(false);
@@ -1655,7 +1629,7 @@
* @return the child at the given location.
*/
@ShadeViewRefactor(RefactorComponent.COORDINATOR)
- private ExpandableView getChildAtPosition(float touchX, float touchY,
+ ExpandableView getChildAtPosition(float touchX, float touchY,
boolean requireMinHeight, boolean ignoreDecors) {
// find the view under the pointer, accounting for GONE views
final int count = getChildCount();
@@ -1803,7 +1777,7 @@
}
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
- private boolean onKeyguard() {
+ boolean onKeyguard() {
return mStatusBarState == StatusBarState.KEYGUARD;
}
@@ -4384,7 +4358,7 @@
}
@ShadeViewRefactor(RefactorComponent.INPUT)
- private void setSwipingInProgress(boolean swiping) {
+ void setSwipingInProgress(boolean swiping) {
mSwipingInProgress = swiping;
if (swiping) {
requestDisallowInterceptTouchEvent(true);
@@ -4450,7 +4424,7 @@
mStatusBar.resetUserExpandedStates();
clearTemporaryViews();
clearUserLockedViews();
- ArrayList<ExpandableView> draggedViews = mAmbientState.getDraggedViews();
+ ArrayList<View> draggedViews = mAmbientState.getDraggedViews();
if (draggedViews.size() > 0) {
draggedViews.clear();
updateContinuousShadowDrawing();
@@ -4994,6 +4968,10 @@
handleDismissAllClipping();
}
+ boolean getDismissAllInProgress() {
+ return mDismissAllInProgress;
+ }
+
@ShadeViewRefactor(RefactorComponent.ADAPTER)
private void handleDismissAllClipping() {
final int count = getChildCount();
@@ -5507,12 +5485,15 @@
ExpandableView child = (ExpandableView) getTransientView(i);
child.dump(fd, pw, args);
}
- ArrayList<ExpandableView> draggedViews = mAmbientState.getDraggedViews();
+ ArrayList<View> draggedViews = mAmbientState.getDraggedViews();
int draggedCount = draggedViews.size();
pw.println(" Dragged Views: " + draggedCount);
for (int i = 0; i < draggedCount; i++) {
- ExpandableView child = (ExpandableView) draggedViews.get(i);
- child.dump(fd, pw, args);
+ View view = draggedViews.get(i);
+ if (view instanceof ExpandableView) {
+ ExpandableView expandableView = (ExpandableView) view;
+ expandableView.dump(fd, pw, args);
+ }
}
}
@@ -5765,6 +5746,10 @@
requestChildrenUpdate();
}
+ public boolean isFullyAwake() {
+ return mAmbientState.isFullyAwake();
+ }
+
public void wakeUpFromPulse() {
setPulseHeight(getWakeUpHeight());
// Let's place the hidden views at the end of the pulsing notification to make sure we have
@@ -5843,8 +5828,16 @@
}
}
- void setMenuEventListener(OnMenuEventListener menuEventListener) {
- mMenuEventListener = menuEventListener;
+ void addSwipedOutView(View v) {
+ mSwipedOutViews.add(v);
+ }
+
+ void addDraggedView(View view) {
+ mAmbientState.onBeginDrag(view);
+ }
+
+ void removeDraggedView(View view) {
+ mAmbientState.onDragFinished(view);
}
/**
@@ -5914,7 +5907,7 @@
mSectionsManager.updateSectionBoundaries(reason);
}
- private void updateContinuousBackgroundDrawing() {
+ void updateContinuousBackgroundDrawing() {
boolean continuousBackground = !mAmbientState.isFullyAwake()
&& !mAmbientState.getDraggedViews().isEmpty();
if (continuousBackground != mContinuousBackgroundUpdate) {
@@ -5928,7 +5921,7 @@
}
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
- private void updateContinuousShadowDrawing() {
+ void updateContinuousShadowDrawing() {
boolean continuousShadowUpdate = mAnimationRunning
|| !mAmbientState.getDraggedViews().isEmpty();
if (continuousShadowUpdate != mContinuousShadowUpdate) {
@@ -5942,7 +5935,7 @@
}
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
- public void resetExposedMenuView(boolean animate, boolean force) {
+ void resetExposedMenuView(boolean animate, boolean force) {
mSwipeHelper.resetExposedMenuView(animate, force);
}
@@ -6202,195 +6195,7 @@
}
}
-
-
- @ShadeViewRefactor(RefactorComponent.INPUT)
- private final NotificationSwipeHelper.NotificationCallback mNotificationCallback =
- new NotificationSwipeHelper.NotificationCallback() {
- @Override
- public void onDismiss() {
- mNotificationGutsManager.closeAndSaveGuts(true /* removeLeavebehind */,
- false /* force */, false /* removeControls */, -1 /* x */, -1 /* y */,
- false /* resetMenu */);
- }
-
- @Override
- public void onSnooze(StatusBarNotification sbn,
- NotificationSwipeActionHelper.SnoozeOption snoozeOption) {
- mStatusBar.setNotificationSnoozed(sbn, snoozeOption);
- }
-
- @Override
- public void onSnooze(StatusBarNotification sbn, int hours) {
- mStatusBar.setNotificationSnoozed(sbn, hours);
- }
-
- @Override
- public boolean shouldDismissQuickly() {
- return NotificationStackScrollLayout.this.isExpanded() && mAmbientState.isFullyAwake();
- }
-
- @Override
- public void onDragCancelled(View v) {
- setSwipingInProgress(false);
- mFalsingManager.onNotificationStopDismissing();
- }
-
- /**
- * Handles cleanup after the given {@code view} has been fully swiped out (including
- * re-invoking dismiss logic in case the notification has not made its way out yet).
- */
- @Override
- public void onChildDismissed(View view) {
- if (!(view instanceof ActivatableNotificationView)) {
- return;
- }
- ActivatableNotificationView row = (ActivatableNotificationView) view;
- if (!row.isDismissed()) {
- handleChildViewDismissed(view);
- }
- ViewGroup transientContainer = row.getTransientContainer();
- if (transientContainer != null) {
- transientContainer.removeTransientView(view);
- }
- }
-
- /**
- * Starts up notification dismiss and tells the notification, if any, to remove itself from
- * layout.
- *
- * @param view view (e.g. notification) to dismiss from the layout
- */
-
- public void handleChildViewDismissed(View view) {
- setSwipingInProgress(false);
- if (mDismissAllInProgress) {
- return;
- }
-
- boolean isBlockingHelperShown = false;
-
- mAmbientState.onDragFinished(view);
- updateContinuousShadowDrawing();
-
- if (view instanceof ExpandableNotificationRow) {
- ExpandableNotificationRow row = (ExpandableNotificationRow) view;
- if (row.isHeadsUp()) {
- mHeadsUpManager.addSwipedOutNotification(
- row.getEntry().getSbn().getKey());
- }
- isBlockingHelperShown =
- row.performDismissWithBlockingHelper(false /* fromAccessibility */);
- }
-
- if (view instanceof PeopleHubView) {
- mSectionsManager.hidePeopleRow();
- }
-
- if (!isBlockingHelperShown) {
- mSwipedOutViews.add(view);
- }
- mFalsingManager.onNotificationDismissed();
- if (mFalsingManager.shouldEnforceBouncer()) {
- mStatusBar.executeRunnableDismissingKeyguard(
- null,
- null /* cancelAction */,
- false /* dismissShade */,
- true /* afterKeyguardGone */,
- false /* deferred */);
- }
- }
-
- @Override
- public boolean isAntiFalsingNeeded() {
- return onKeyguard();
- }
-
- @Override
- public View getChildAtPosition(MotionEvent ev) {
- View child = NotificationStackScrollLayout.this.getChildAtPosition(
- ev.getX(),
- ev.getY(),
- true /* requireMinHeight */,
- false /* ignoreDecors */);
- if (child instanceof ExpandableNotificationRow) {
- ExpandableNotificationRow row = (ExpandableNotificationRow) child;
- ExpandableNotificationRow parent = row.getNotificationParent();
- if (parent != null && parent.areChildrenExpanded()
- && (parent.areGutsExposed()
- || mSwipeHelper.getExposedMenuView() == parent
- || (parent.getAttachedChildren().size() == 1
- && parent.getEntry().isClearable()))) {
- // In this case the group is expanded and showing the menu for the
- // group, further interaction should apply to the group, not any
- // child notifications so we use the parent of the child. We also do the same
- // if we only have a single child.
- child = parent;
- }
- }
- return child;
- }
-
- @Override
- public void onBeginDrag(View v) {
- mFalsingManager.onNotificationStartDismissing();
- setSwipingInProgress(true);
- mAmbientState.onBeginDrag((ExpandableView) v);
- updateContinuousShadowDrawing();
- updateContinuousBackgroundDrawing();
- requestChildrenUpdate();
- }
-
- @Override
- public void onChildSnappedBack(View animView, float targetLeft) {
- mAmbientState.onDragFinished(animView);
- updateContinuousShadowDrawing();
- updateContinuousBackgroundDrawing();
- if (animView instanceof ExpandableNotificationRow) {
- ExpandableNotificationRow row = (ExpandableNotificationRow) animView;
- if (row.isPinned() && !canChildBeDismissed(row)
- && row.getEntry().getSbn().getNotification().fullScreenIntent
- == null) {
- mHeadsUpManager.removeNotification(row.getEntry().getSbn().getKey(),
- true /* removeImmediately */);
- }
- }
- }
-
- @Override
- public boolean updateSwipeProgress(View animView, boolean dismissable,
- float swipeProgress) {
- // Returning true prevents alpha fading.
- return !mFadeNotificationsOnDismiss;
- }
-
- @Override
- public float getFalsingThresholdFactor() {
- return mStatusBar.isWakeUpComingFromTouch() ? 1.5f : 1.0f;
- }
-
- @Override
- public int getConstrainSwipeStartPosition() {
- NotificationMenuRowPlugin menuRow = mSwipeHelper.getCurrentMenuRow();
- if (menuRow != null) {
- return Math.abs(menuRow.getMenuSnapTarget());
- }
- return 0;
- }
-
- @Override
- public boolean canChildBeDismissed(View v) {
- return NotificationStackScrollLayout.canChildBeDismissed(v);
- }
-
- @Override
- public boolean canChildBeDismissedInDirection(View v, boolean isRightOrDown) {
- //TODO: b/131242807 for why this doesn't do anything with direction
- return canChildBeDismissed(v);
- }
- };
-
- private static boolean canChildBeDismissed(View v) {
+ static boolean canChildBeDismissed(View v) {
if (v instanceof ExpandableNotificationRow) {
ExpandableNotificationRow row = (ExpandableNotificationRow) v;
if (row.isBlockingHelperShowingAndTranslationFinished()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
index ca78b2a..73b4cad 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
@@ -18,11 +18,14 @@
import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME;
+import android.content.res.Resources;
import android.graphics.Point;
import android.graphics.PointF;
import android.provider.Settings;
+import android.service.notification.StatusBarNotification;
import android.util.Log;
import android.view.Display;
+import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowInsets;
@@ -31,8 +34,12 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.systemui.R;
+import com.android.systemui.SwipeHelper;
import com.android.systemui.colorextraction.SysuiColorExtractor;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.media.KeyguardMediaController;
+import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.OnMenuEventListener;
import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
@@ -89,13 +96,20 @@
private final ConfigurationController mConfigurationController;
private final ZenModeController mZenModeController;
private final MetricsLogger mMetricsLogger;
+ private final FalsingManager mFalsingManager;
+ private final NotificationSectionsManager mNotificationSectionsManager;
+ private final Resources mResources;
+ private final NotificationSwipeHelper.Builder mNotificationSwipeHelperBuilder;
private final KeyguardMediaController mKeyguardMediaController;
private final SysuiStatusBarStateController mStatusBarStateController;
private final KeyguardBypassController mKeyguardBypassController;
private final SysuiColorExtractor mColorExtractor;
private final NotificationLockscreenUserManager mLockscreenUserManager;
+ // TODO: StatusBar should be encapsulated behind a Controller
+ private final StatusBar mStatusBar;
private NotificationStackScrollLayout mView;
+ private boolean mFadeNotificationsOnDismiss;
private final NotificationListContainerImpl mNotificationListContainer =
new NotificationListContainerImpl();
@@ -238,6 +252,194 @@
}
};
+ private final NotificationSwipeHelper.NotificationCallback mNotificationCallback =
+ new NotificationSwipeHelper.NotificationCallback() {
+
+ @Override
+ public void onDismiss() {
+ mNotificationGutsManager.closeAndSaveGuts(true /* removeLeavebehind */,
+ false /* force */, false /* removeControls */, -1 /* x */, -1 /* y */,
+ false /* resetMenu */);
+ }
+
+ @Override
+ public void onSnooze(StatusBarNotification sbn,
+ NotificationSwipeActionHelper.SnoozeOption snoozeOption) {
+ mStatusBar.setNotificationSnoozed(sbn, snoozeOption);
+ }
+
+ @Override
+ public void onSnooze(StatusBarNotification sbn, int hours) {
+ mStatusBar.setNotificationSnoozed(sbn, hours);
+ }
+
+ @Override
+ public boolean shouldDismissQuickly() {
+ return mView.isExpanded() && mView.isFullyAwake();
+ }
+
+ @Override
+ public void onDragCancelled(View v) {
+ mView.setSwipingInProgress(false);
+ mFalsingManager.onNotificationStopDismissing();
+ }
+
+ /**
+ * Handles cleanup after the given {@code view} has been fully swiped out (including
+ * re-invoking dismiss logic in case the notification has not made its way out yet).
+ */
+ @Override
+ public void onChildDismissed(View view) {
+ if (!(view instanceof ActivatableNotificationView)) {
+ return;
+ }
+ ActivatableNotificationView row = (ActivatableNotificationView) view;
+ if (!row.isDismissed()) {
+ handleChildViewDismissed(view);
+ }
+ ViewGroup transientContainer = row.getTransientContainer();
+ if (transientContainer != null) {
+ transientContainer.removeTransientView(view);
+ }
+ }
+
+ /**
+ * Starts up notification dismiss and tells the notification, if any, to remove
+ * itself from the layout.
+ *
+ * @param view view (e.g. notification) to dismiss from the layout
+ */
+
+ public void handleChildViewDismissed(View view) {
+ mView.setSwipingInProgress(false);
+ if (mView.getDismissAllInProgress()) {
+ return;
+ }
+
+ boolean isBlockingHelperShown = false;
+
+ mView.removeDraggedView(view);
+ mView.updateContinuousShadowDrawing();
+
+ if (view instanceof ExpandableNotificationRow) {
+ ExpandableNotificationRow row = (ExpandableNotificationRow) view;
+ if (row.isHeadsUp()) {
+ mHeadsUpManager.addSwipedOutNotification(
+ row.getEntry().getSbn().getKey());
+ }
+ isBlockingHelperShown =
+ row.performDismissWithBlockingHelper(false /* fromAccessibility */);
+ }
+
+ if (view instanceof PeopleHubView) {
+ mNotificationSectionsManager.hidePeopleRow();
+ }
+
+ if (!isBlockingHelperShown) {
+ mView.addSwipedOutView(view);
+ }
+ mFalsingManager.onNotificationDismissed();
+ if (mFalsingManager.shouldEnforceBouncer()) {
+ mStatusBar.executeRunnableDismissingKeyguard(
+ null,
+ null /* cancelAction */,
+ false /* dismissShade */,
+ true /* afterKeyguardGone */,
+ false /* deferred */);
+ }
+ }
+
+ @Override
+ public boolean isAntiFalsingNeeded() {
+ return mView.onKeyguard();
+ }
+
+ @Override
+ public View getChildAtPosition(MotionEvent ev) {
+ View child = mView.getChildAtPosition(
+ ev.getX(),
+ ev.getY(),
+ true /* requireMinHeight */,
+ false /* ignoreDecors */);
+ if (child instanceof ExpandableNotificationRow) {
+ ExpandableNotificationRow row = (ExpandableNotificationRow) child;
+ ExpandableNotificationRow parent = row.getNotificationParent();
+ if (parent != null && parent.areChildrenExpanded()
+ && (parent.areGutsExposed()
+ || mSwipeHelper.getExposedMenuView() == parent
+ || (parent.getAttachedChildren().size() == 1
+ && parent.getEntry().isClearable()))) {
+ // In this case the group is expanded and showing the menu for the
+ // group, further interaction should apply to the group, not any
+ // child notifications so we use the parent of the child. We also do the
+ // same if we only have a single child.
+ child = parent;
+ }
+ }
+ return child;
+ }
+
+ @Override
+ public void onBeginDrag(View v) {
+ mFalsingManager.onNotificationStartDismissing();
+ mView.setSwipingInProgress(true);
+ mView.addDraggedView(v);
+ mView.updateContinuousShadowDrawing();
+ mView.updateContinuousBackgroundDrawing();
+ mView.requestChildrenUpdate();
+ }
+
+ @Override
+ public void onChildSnappedBack(View animView, float targetLeft) {
+ mView.addDraggedView(animView);
+ mView.updateContinuousShadowDrawing();
+ mView.updateContinuousBackgroundDrawing();
+ if (animView instanceof ExpandableNotificationRow) {
+ ExpandableNotificationRow row = (ExpandableNotificationRow) animView;
+ if (row.isPinned() && !canChildBeDismissed(row)
+ && row.getEntry().getSbn().getNotification().fullScreenIntent
+ == null) {
+ mHeadsUpManager.removeNotification(row.getEntry().getSbn().getKey(),
+ true /* removeImmediately */);
+ }
+ }
+ }
+
+ @Override
+ public boolean updateSwipeProgress(View animView, boolean dismissable,
+ float swipeProgress) {
+ // Returning true prevents alpha fading.
+ return !mFadeNotificationsOnDismiss;
+ }
+
+ @Override
+ public float getFalsingThresholdFactor() {
+ return mStatusBar.isWakeUpComingFromTouch() ? 1.5f : 1.0f;
+ }
+
+ @Override
+ public int getConstrainSwipeStartPosition() {
+ NotificationMenuRowPlugin menuRow = mSwipeHelper.getCurrentMenuRow();
+ if (menuRow != null) {
+ return Math.abs(menuRow.getMenuSnapTarget());
+ }
+ return 0;
+ }
+
+ @Override
+ public boolean canChildBeDismissed(View v) {
+ return NotificationStackScrollLayout.canChildBeDismissed(v);
+ }
+
+ @Override
+ public boolean canChildBeDismissedInDirection(View v, boolean isRightOrDown) {
+ //TODO: b/131242807 for why this doesn't do anything with direction
+ return canChildBeDismissed(v);
+ }
+ };
+
+ private NotificationSwipeHelper mSwipeHelper;
+
@Inject
public NotificationStackScrollLayoutController(
@Named(ALLOW_NOTIFICATION_LONG_PRESS_NAME) boolean allowLongPress,
@@ -253,7 +455,12 @@
ZenModeController zenModeController,
SysuiColorExtractor colorExtractor,
NotificationLockscreenUserManager lockscreenUserManager,
- MetricsLogger metricsLogger) {
+ MetricsLogger metricsLogger,
+ FalsingManager falsingManager,
+ NotificationSectionsManager notificationSectionsManager,
+ @Main Resources resources,
+ NotificationSwipeHelper.Builder notificationSwipeHelperBuilder,
+ StatusBar statusBar) {
mAllowLongPress = allowLongPress;
mNotificationGutsManager = notificationGutsManager;
mHeadsUpManager = headsUpManager;
@@ -268,12 +475,25 @@
mColorExtractor = colorExtractor;
mLockscreenUserManager = lockscreenUserManager;
mMetricsLogger = metricsLogger;
+ mFalsingManager = falsingManager;
+ mNotificationSectionsManager = notificationSectionsManager;
+ mResources = resources;
+ mNotificationSwipeHelperBuilder = notificationSwipeHelperBuilder;
+ mStatusBar = statusBar;
}
public void attach(NotificationStackScrollLayout view) {
mView = view;
mView.setController(this);
- mView.initView(mView.getContext(), mKeyguardBypassController::getBypassEnabled);
+
+ mSwipeHelper = mNotificationSwipeHelperBuilder
+ .setSwipeDirection(SwipeHelper.X)
+ .setNotificationCallback(mNotificationCallback)
+ .setOnMenuEventListener(mMenuEventListener)
+ .build();
+
+ mView.initView(mView.getContext(), mKeyguardBypassController::getBypassEnabled,
+ mSwipeHelper);
mHeadsUpManager.addListener(mNotificationRoundnessManager); // TODO: why is this here?
mDynamicPrivacyController.addListener(mDynamicPrivacyControllerListener);
@@ -281,7 +501,8 @@
mLockscreenUserManager.addUserChangedListener(mLockscreenUserChangeListener);
mView.setCurrentUserid(mLockscreenUserManager.getCurrentUserId());
- mView.setMenuEventListener(mMenuEventListener);
+ mFadeNotificationsOnDismiss = // TODO: this should probably be injected directly
+ mResources.getBoolean(R.bool.config_fadeNotificationsOnDismiss);
mNotificationRoundnessManager.setOnRoundingChangedCallback(mView::invalidate);
mView.addOnExpandedHeightChangedListener(mNotificationRoundnessManager::setExpanded);
@@ -681,6 +902,13 @@
return mView.hasActiveClearableNotifications(selection);
}
+ /**
+ * Set the maximum number of notifications that can currently be displayed
+ */
+ public void setMaxDisplayedNotifications(int maxNotifications) {
+ mNotificationListContainer.setMaxDisplayedNotifications(maxNotifications);
+ }
+
public RemoteInputController.Delegate createDelegate() {
return mView.createDelegate();
}
@@ -861,7 +1089,7 @@
@Override
public NotificationSwipeActionHelper getSwipeActionHelper() {
- return mView.getSwipeActionHelper();
+ return mSwipeHelper;
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java
index d3b8a8c..1e80e88 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java
@@ -19,15 +19,17 @@
import android.animation.Animator;
import android.animation.ValueAnimator;
-import android.content.Context;
+import android.content.res.Resources;
import android.graphics.Rect;
import android.os.Handler;
import android.service.notification.StatusBarNotification;
import android.view.MotionEvent;
import android.view.View;
+import android.view.ViewConfiguration;
import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.SwipeHelper;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
@@ -36,6 +38,8 @@
import java.lang.ref.WeakReference;
+import javax.inject.Inject;
+
class NotificationSwipeHelper extends SwipeHelper implements NotificationSwipeActionHelper {
@VisibleForTesting
@@ -58,10 +62,10 @@
private boolean mPulsing;
NotificationSwipeHelper(
- int swipeDirection, NotificationCallback callback, Context context,
- NotificationMenuRowPlugin.OnMenuEventListener menuListener,
- FalsingManager falsingManager) {
- super(swipeDirection, callback, context, falsingManager);
+ Resources resources, ViewConfiguration viewConfiguration,
+ FalsingManager falsingManager, int swipeDirection, NotificationCallback callback,
+ NotificationMenuRowPlugin.OnMenuEventListener menuListener) {
+ super(swipeDirection, callback, resources, viewConfiguration, falsingManager);
mMenuListener = menuListener;
mCallback = callback;
mFalsingCheck = () -> resetExposedMenuView(true /* animate */, true /* force */);
@@ -74,7 +78,7 @@
public void clearTranslatingParentView() { setTranslatingParentView(null); }
@VisibleForTesting
- protected void setTranslatingParentView(View view) { mTranslatingParentView = view; };
+ protected void setTranslatingParentView(View view) { mTranslatingParentView = view; }
public void setExposedMenuView(View view) {
mMenuExposedView = view;
@@ -90,7 +94,7 @@
@VisibleForTesting
void setCurrentMenuRow(NotificationMenuRowPlugin menuRow) {
- mCurrMenuRowRef = menuRow != null ? new WeakReference(menuRow) : null;
+ mCurrMenuRowRef = menuRow != null ? new WeakReference<>(menuRow) : null;
}
public NotificationMenuRowPlugin getCurrentMenuRow() {
@@ -470,4 +474,42 @@
void onDismiss();
}
+
+ static class Builder {
+ private final Resources mResources;
+ private final ViewConfiguration mViewConfiguration;
+ private final FalsingManager mFalsingManager;
+ private int mSwipeDirection;
+ private NotificationCallback mNotificationCallback;
+ private NotificationMenuRowPlugin.OnMenuEventListener mOnMenuEventListener;
+
+ @Inject
+ Builder(@Main Resources resources, ViewConfiguration viewConfiguration,
+ FalsingManager falsingManager) {
+ mResources = resources;
+ mViewConfiguration = viewConfiguration;
+ mFalsingManager = falsingManager;
+ }
+
+ Builder setSwipeDirection(int swipeDirection) {
+ mSwipeDirection = swipeDirection;
+ return this;
+ }
+
+ Builder setNotificationCallback(NotificationCallback notificationCallback) {
+ mNotificationCallback = notificationCallback;
+ return this;
+ }
+
+ Builder setOnMenuEventListener(
+ NotificationMenuRowPlugin.OnMenuEventListener onMenuEventListener) {
+ mOnMenuEventListener = onMenuEventListener;
+ return this;
+ }
+
+ NotificationSwipeHelper build() {
+ return new NotificationSwipeHelper(mResources, mViewConfiguration, mFalsingManager,
+ mSwipeDirection, mNotificationCallback, mOnMenuEventListener);
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index 5974a53..d83758a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -18,6 +18,7 @@
import static android.view.View.GONE;
+import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
import static com.android.systemui.statusbar.notification.ActivityLaunchAnimator.ExpandAnimationParameters;
import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_ALL;
@@ -31,6 +32,7 @@
import android.app.StatusBarManager;
import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
+import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
@@ -70,6 +72,7 @@
import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.dagger.qualifiers.DisplayId;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.doze.DozeLog;
import com.android.systemui.fragments.FragmentHostManager;
import com.android.systemui.fragments.FragmentHostManager.FragmentListener;
@@ -85,7 +88,6 @@
import com.android.systemui.statusbar.KeyguardAffordanceView;
import com.android.systemui.statusbar.KeyguardIndicationController;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
-import com.android.systemui.statusbar.NotificationShelf;
import com.android.systemui.statusbar.NotificationShelfController;
import com.android.systemui.statusbar.PulseExpansionHandler;
import com.android.systemui.statusbar.RemoteInputController;
@@ -231,7 +233,7 @@
BiometricSourceType biometricSourceType) {
boolean
keyguardOrShadeLocked =
- mBarState == StatusBarState.KEYGUARD
+ mBarState == KEYGUARD
|| mBarState == StatusBarState.SHADE_LOCKED;
if (!running && mFirstBypassAttempt && keyguardOrShadeLocked && !mDozing
&& !mDelayShowingKeyguardStatusBar
@@ -259,6 +261,11 @@
private final MediaHierarchyManager mMediaHierarchyManager;
private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
private final Provider<KeyguardClockSwitchController> mKeyguardClockSwitchControllerProvider;
+ // Maximum # notifications to show on Keyguard; extras will be collapsed in an overflow card.
+ // If there are exactly 1 + mMaxKeyguardNotifications, then still shows all notifications
+ private final int mMaxKeyguardNotifications;
+ // Current max allowed keyguard notifications determined by measuring the panel
+ private int mMaxAllowedKeyguardNotifications;
private KeyguardAffordanceHelper mAffordanceHelper;
private KeyguardUserSwitcher mKeyguardUserSwitcher;
@@ -482,6 +489,7 @@
@Inject
public NotificationPanelViewController(NotificationPanelView view,
+ @Main Resources resources,
InjectionInflationController injectionInflationController,
NotificationWakeUpCoordinator coordinator, PulseExpansionHandler pulseExpansionHandler,
DynamicPrivacyController dynamicPrivacyController,
@@ -584,6 +592,7 @@
mView.getOverlay().add(new DebugDrawable());
}
+ mMaxKeyguardNotifications = resources.getInteger(R.integer.keyguard_max_notification_count);
onFinishInflate();
}
@@ -761,6 +770,20 @@
mKeyguardBottomArea.setUserSetupComplete(mUserSetupComplete);
}
+ private void updateMaxDisplayedNotifications(boolean recompute) {
+ if (recompute) {
+ mMaxAllowedKeyguardNotifications = Math.max(computeMaxKeyguardNotifications(), 1);
+ }
+
+ if (mKeyguardShowing && !mKeyguardBypassController.getBypassEnabled()) {
+ mNotificationStackScrollLayoutController.setMaxDisplayedNotifications(
+ mMaxAllowedKeyguardNotifications);
+ } else {
+ // no max when not on the keyguard
+ mNotificationStackScrollLayoutController.setMaxDisplayedNotifications(-1);
+ }
+ }
+
public void setKeyguardIndicationController(KeyguardIndicationController indicationController) {
mKeyguardIndicationController = indicationController;
mKeyguardIndicationController.setIndicationArea(mKeyguardBottomArea);
@@ -821,7 +844,7 @@
boolean animate = mNotificationStackScrollLayoutController.isAddOrRemoveAnimationPending();
boolean animateClock = animate || mAnimateNextPositionUpdate;
int stackScrollerPadding;
- if (mBarState != StatusBarState.KEYGUARD) {
+ if (mBarState != KEYGUARD) {
stackScrollerPadding = getUnlockedStackScrollerPadding();
} else {
int totalHeight = mView.getHeight();
@@ -865,20 +888,17 @@
}
/**
- * @param maximum the maximum to return at most
* @return the maximum keyguard notifications that can fit on the screen
*/
- public int computeMaxKeyguardNotifications(int maximum) {
+ private int computeMaxKeyguardNotifications() {
float minPadding = mClockPositionAlgorithm.getMinStackScrollerPadding();
int notificationPadding = Math.max(
1, mResources.getDimensionPixelSize(R.dimen.notification_divider_height));
- NotificationShelf shelf = mNotificationShelfController.getView();
- float
- shelfSize =
- shelf.getVisibility() == View.GONE ? 0
- : shelf.getIntrinsicHeight() + notificationPadding;
- float
- availableSpace =
+ float shelfSize =
+ mNotificationShelfController.getVisibility() == View.GONE
+ ? 0
+ : mNotificationShelfController.getIntrinsicHeight() + notificationPadding;
+ float availableSpace =
mNotificationStackScrollLayoutController.getHeight() - minPadding - shelfSize
- Math.max(mIndicationBottomPadding, mAmbientIndicationBottomPadding)
- mKeyguardStatusView.getLogoutButtonHeight();
@@ -908,7 +928,8 @@
availableSpace -= mNotificationStackScrollLayoutController
.calculateGapHeight(previousView, child, count);
previousView = child;
- if (availableSpace >= 0 && count < maximum) {
+ if (availableSpace >= 0
+ && (mMaxKeyguardNotifications == -1 || count < mMaxKeyguardNotifications)) {
count++;
} else if (availableSpace > -shelfSize) {
// if we are exactly the last view, then we can show us still!
@@ -1235,7 +1256,7 @@
float vel = getCurrentQSVelocity();
final int
gesture =
- mBarState == StatusBarState.KEYGUARD ? MetricsEvent.ACTION_LS_QS
+ mBarState == KEYGUARD ? MetricsEvent.ACTION_LS_QS
: MetricsEvent.ACTION_SHADE_QS_PULL;
mLockscreenGestureLogger.write(gesture,
(int) ((y - mInitialTouchY) / mStatusBar.getDisplayDensity()),
@@ -1292,7 +1313,7 @@
private boolean handleQsTouch(MotionEvent event) {
final int action = event.getActionMasked();
if (action == MotionEvent.ACTION_DOWN && getExpandedFraction() == 1f
- && mBarState != StatusBarState.KEYGUARD && !mQsExpanded && mQsExpansionEnabled) {
+ && mBarState != KEYGUARD && !mQsExpanded && mQsExpansionEnabled) {
// Down in the empty area while fully expanded - go to QS.
mQsTracking = true;
@@ -1646,7 +1667,7 @@
mKeyguardStateController.getShortenedFadingAwayDuration()).setInterpolator(
Interpolators.ALPHA_OUT).withEndAction(
mAnimateKeyguardBottomAreaInvisibleEndRunnable).start();
- } else if (statusBarState == StatusBarState.KEYGUARD
+ } else if (statusBarState == KEYGUARD
|| statusBarState == StatusBarState.SHADE_LOCKED) {
mKeyguardBottomArea.setVisibility(View.VISIBLE);
mKeyguardBottomArea.setAlpha(1f);
@@ -1659,8 +1680,8 @@
boolean goingToFullShade) {
mKeyguardStatusView.animate().cancel();
mKeyguardStatusViewAnimating = false;
- if ((!keyguardFadingAway && mBarState == StatusBarState.KEYGUARD
- && statusBarState != StatusBarState.KEYGUARD) || goingToFullShade) {
+ if ((!keyguardFadingAway && mBarState == KEYGUARD
+ && statusBarState != KEYGUARD) || goingToFullShade) {
mKeyguardStatusViewAnimating = true;
mKeyguardStatusView.animate().alpha(0f).setStartDelay(0).setDuration(
160).setInterpolator(Interpolators.ALPHA_OUT).withEndAction(
@@ -1671,14 +1692,14 @@
mKeyguardStateController.getShortenedFadingAwayDuration()).start();
}
} else if (mBarState == StatusBarState.SHADE_LOCKED
- && statusBarState == StatusBarState.KEYGUARD) {
+ && statusBarState == KEYGUARD) {
mKeyguardStatusView.setVisibility(View.VISIBLE);
mKeyguardStatusViewAnimating = true;
mKeyguardStatusView.setAlpha(0f);
mKeyguardStatusView.animate().alpha(1f).setStartDelay(0).setDuration(
320).setInterpolator(Interpolators.ALPHA_IN).withEndAction(
mAnimateKeyguardStatusViewVisibleEndRunnable);
- } else if (statusBarState == StatusBarState.KEYGUARD) {
+ } else if (statusBarState == KEYGUARD) {
if (keyguardFadingAway) {
mKeyguardStatusViewAnimating = true;
mKeyguardStatusView.animate().alpha(0).translationYBy(
@@ -1698,7 +1719,7 @@
private void updateQsState() {
mNotificationStackScrollLayoutController.setQsExpanded(mQsExpanded);
mNotificationStackScrollLayoutController.setScrollingEnabled(
- mBarState != StatusBarState.KEYGUARD && (!mQsExpanded
+ mBarState != KEYGUARD && (!mQsExpanded
|| mQsExpansionFromOverscroll));
updateEmptyShadeView();
@@ -1725,7 +1746,7 @@
updateQsExpansion();
requestScrollerTopPaddingUpdate(false /* animate */);
updateHeaderKeyguardAlpha();
- if (mBarState == StatusBarState.SHADE_LOCKED || mBarState == StatusBarState.KEYGUARD) {
+ if (mBarState == StatusBarState.SHADE_LOCKED || mBarState == KEYGUARD) {
updateKeyguardBottomAreaAlpha();
updateBigClockAlpha();
}
@@ -1767,7 +1788,7 @@
// Upon initialisation when we are not layouted yet we don't want to announce that we
// are fully expanded, hence the != 0.0f check.
return mResources.getString(R.string.accessibility_desc_quick_settings);
- } else if (mBarState == StatusBarState.KEYGUARD) {
+ } else if (mBarState == KEYGUARD) {
return mResources.getString(R.string.accessibility_desc_lock_screen);
} else {
return mResources.getString(R.string.accessibility_desc_notification_shade);
@@ -1785,7 +1806,7 @@
// for a nice motion.
int maxNotificationPadding = getKeyguardNotificationStaticPadding();
int maxQsPadding = mQsMaxExpansionHeight + mQsNotificationTopPadding;
- int max = mBarState == StatusBarState.KEYGUARD ? Math.max(
+ int max = mBarState == KEYGUARD ? Math.max(
maxNotificationPadding, maxQsPadding) : maxQsPadding;
return (int) MathUtils.lerp((float) mQsMinExpansionHeight, (float) max,
getExpandedFraction());
@@ -1973,7 +1994,7 @@
@Override
protected boolean canCollapsePanelOnTouch() {
if (!isInSettings()) {
- return mBarState == StatusBarState.KEYGUARD
+ return mBarState == KEYGUARD
|| mIsPanelCollapseOnQQS
|| mNotificationStackScrollLayoutController.isScrolledToBottom();
} else {
@@ -1983,7 +2004,7 @@
@Override
protected int getMaxPanelHeight() {
- if (mKeyguardBypassController.getBypassEnabled() && mBarState == StatusBarState.KEYGUARD) {
+ if (mKeyguardBypassController.getBypassEnabled() && mBarState == KEYGUARD) {
return getMaxPanelHeightBypass();
} else {
return getMaxPanelHeightNonBypass();
@@ -1992,7 +2013,7 @@
private int getMaxPanelHeightNonBypass() {
int min = mStatusBarMinHeight;
- if (!(mBarState == StatusBarState.KEYGUARD)
+ if (!(mBarState == KEYGUARD)
&& mNotificationStackScrollLayoutController.getNotGoneChildCount() == 0) {
int minHeight = (int) (mQsMinExpansionHeight + getOverExpansionAmount());
min = Math.max(min, minHeight);
@@ -2095,7 +2116,7 @@
int maxHeight = mNotificationStackScrollLayoutController.getHeight() - emptyBottomMargin;
maxHeight += mNotificationStackScrollLayoutController.getTopPaddingOverflow();
- if (mBarState == StatusBarState.KEYGUARD) {
+ if (mBarState == KEYGUARD) {
int
minKeyguardPanelBottom =
mClockPositionAlgorithm.getExpandedClockPosition()
@@ -2132,7 +2153,7 @@
maxQsHeight = (int) mQsSizeChangeAnimator.getAnimatedValue();
}
float totalHeight = Math.max(maxQsHeight,
- mBarState == StatusBarState.KEYGUARD ? mClockPositionResult.stackScrollerPadding
+ mBarState == KEYGUARD ? mClockPositionResult.stackScrollerPadding
: 0) + notificationHeight
+ mNotificationStackScrollLayoutController.getTopPaddingOverflow();
if (totalHeight > mNotificationStackScrollLayoutController.getHeight()) {
@@ -2151,7 +2172,7 @@
&& !mHeadsUpManager.hasPinnedHeadsUp()) {
alpha = getFadeoutAlpha();
}
- if (mBarState == StatusBarState.KEYGUARD && !mHintAnimationRunning
+ if (mBarState == KEYGUARD && !mHintAnimationRunning
&& !mKeyguardBypassController.getBypassEnabled()) {
alpha *= mClockPositionResult.clockAlpha;
}
@@ -2190,14 +2211,14 @@
* Hides the header when notifications are colliding with it.
*/
private void updateHeader() {
- if (mBarState == StatusBarState.KEYGUARD) {
+ if (mBarState == KEYGUARD) {
updateHeaderKeyguardAlpha();
}
updateQsExpansion();
}
protected float getHeaderTranslation() {
- if (mBarState == StatusBarState.KEYGUARD && !mKeyguardBypassController.getBypassEnabled()) {
+ if (mBarState == KEYGUARD && !mKeyguardBypassController.getBypassEnabled()) {
return -mQs.getQsMinExpansionHeight();
}
float appearAmount = mNotificationStackScrollLayoutController
@@ -2227,7 +2248,7 @@
*/
private float getKeyguardContentsAlpha() {
float alpha;
- if (mBarState == StatusBarState.KEYGUARD) {
+ if (mBarState == KEYGUARD) {
// When on Keyguard, we hide the header as soon as we expanded close enough to the
// header
@@ -2376,7 +2397,7 @@
if (mConflictingQsExpansionGesture || mQsExpandImmediate) {
return;
}
- if (mBarState != StatusBarState.KEYGUARD) {
+ if (mBarState != KEYGUARD) {
mNotificationStackScrollLayoutController.setOnHeightChangedListener(null);
if (isPixels) {
mNotificationStackScrollLayoutController.setOverScrolledPixels(
@@ -2398,7 +2419,7 @@
mQsExpandImmediate = true;
mNotificationStackScrollLayoutController.setShouldShowShelfOnly(true);
}
- if (mBarState == StatusBarState.KEYGUARD || mBarState == StatusBarState.SHADE_LOCKED) {
+ if (mBarState == KEYGUARD || mBarState == StatusBarState.SHADE_LOCKED) {
mAffordanceHelper.animateHideLeftRightIcon();
}
mNotificationStackScrollLayoutController.onPanelTrackingStarted();
@@ -2413,7 +2434,7 @@
true /* animate */);
}
mNotificationStackScrollLayoutController.onPanelTrackingStopped();
- if (expand && (mBarState == StatusBarState.KEYGUARD
+ if (expand && (mBarState == KEYGUARD
|| mBarState == StatusBarState.SHADE_LOCKED)) {
if (!mHintAnimationRunning) {
mAffordanceHelper.reset(true);
@@ -2564,7 +2585,7 @@
@Override
protected boolean onMiddleClicked() {
switch (mBarState) {
- case StatusBarState.KEYGUARD:
+ case KEYGUARD:
if (!mDozingOnDown) {
if (mKeyguardBypassController.getBypassEnabled()) {
mUpdateMonitor.requestFaceAuth();
@@ -2579,7 +2600,7 @@
return true;
case StatusBarState.SHADE_LOCKED:
if (!mQsExpanded) {
- mStatusBarStateController.setState(StatusBarState.KEYGUARD);
+ mStatusBarStateController.setState(KEYGUARD);
}
return true;
case StatusBarState.SHADE:
@@ -2750,7 +2771,7 @@
}
private boolean isOnKeyguard() {
- return mBarState == StatusBarState.KEYGUARD;
+ return mBarState == KEYGUARD;
}
public void setPanelScrimMinFraction(float minFraction) {
@@ -2925,7 +2946,7 @@
mBottomAreaShadeAlphaAnimator.cancel();
}
- if (mBarState == StatusBarState.KEYGUARD || mBarState == StatusBarState.SHADE_LOCKED) {
+ if (mBarState == KEYGUARD || mBarState == StatusBarState.SHADE_LOCKED) {
updateDozingVisibilities(animate);
}
@@ -2953,7 +2974,7 @@
public void setAmbientIndicationBottomPadding(int ambientIndicationBottomPadding) {
if (mAmbientIndicationBottomPadding != ambientIndicationBottomPadding) {
mAmbientIndicationBottomPadding = ambientIndicationBottomPadding;
- mStatusBar.updateKeyguardMaxNotifications();
+ updateMaxDisplayedNotifications(true);
}
}
@@ -3057,7 +3078,7 @@
private void updateShowEmptyShadeView() {
boolean
showEmptyShadeView =
- mBarState != StatusBarState.KEYGUARD && !mEntryManager.hasActiveNotifications();
+ mBarState != KEYGUARD && !mEntryManager.hasActiveNotifications();
showEmptyShadeView(showEmptyShadeView);
}
@@ -3127,6 +3148,7 @@
mNotificationStackScrollLayoutController.setScrimController(scrimController);
updateShowEmptyShadeView();
mNotificationShelfController = notificationShelfController;
+ updateMaxDisplayedNotifications(true);
}
public void showTransientIndication(int id) {
@@ -3506,7 +3528,7 @@
@Override
public boolean needsAntiFalsing() {
- return mBarState == StatusBarState.KEYGUARD;
+ return mBarState == KEYGUARD;
}
}
@@ -3619,14 +3641,15 @@
boolean goingToFullShade = mStatusBarStateController.goingToFullShade();
boolean keyguardFadingAway = mKeyguardStateController.isKeyguardFadingAway();
int oldState = mBarState;
- boolean keyguardShowing = statusBarState == StatusBarState.KEYGUARD;
+ boolean keyguardShowing = statusBarState == KEYGUARD;
+
setKeyguardStatusViewVisibility(statusBarState, keyguardFadingAway, goingToFullShade);
setKeyguardBottomAreaVisibility(statusBarState, goingToFullShade);
mBarState = statusBarState;
mKeyguardShowing = keyguardShowing;
- if (oldState == StatusBarState.KEYGUARD && (goingToFullShade
+ if (oldState == KEYGUARD && (goingToFullShade
|| statusBarState == StatusBarState.SHADE_LOCKED)) {
animateKeyguardStatusBarOut();
long
@@ -3635,7 +3658,7 @@
: mKeyguardStateController.calculateGoingToFullShadeDelay();
mQs.animateHeaderSlidingIn(delay);
} else if (oldState == StatusBarState.SHADE_LOCKED
- && statusBarState == StatusBarState.KEYGUARD) {
+ && statusBarState == KEYGUARD) {
animateKeyguardStatusBarIn(StackStateAnimator.ANIMATION_DURATION_STANDARD);
mNotificationStackScrollLayoutController.resetScrollPosition();
// Only animate header if the header is visible. If not, it will partially
@@ -3657,7 +3680,9 @@
if (keyguardShowing) {
updateDozingVisibilities(false /* animate */);
}
- // THe update needs to happen after the headerSlide in above, otherwise the translation
+
+ updateMaxDisplayedNotifications(false);
+ // The update needs to happen after the headerSlide in above, otherwise the translation
// would reset
updateQSPulseExpansion();
maybeAnimateBottomAreaAlpha();
@@ -3713,6 +3738,7 @@
int oldTop, int oldRight, int oldBottom) {
DejankUtils.startDetectingBlockingIpcs("NVP#onLayout");
super.onLayoutChange(v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom);
+ updateMaxDisplayedNotifications(true);
setIsFullWidth(mNotificationStackScrollLayoutController.getWidth() == mView.getWidth());
// Update Clock Pivot
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
index 5abc4261..9ea402d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
@@ -652,6 +652,7 @@
pw.println(TAG + ":");
pw.println(" mKeyguardDisplayMode=" + mKeyguardDisplayMode);
pw.println(mCurrentState);
+ mNotificationShadeView.getViewRootImpl().dump(" ", fd, pw, args);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
index ac329e2..965368e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
@@ -1325,7 +1325,6 @@
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft,
int oldTop, int oldRight, int oldBottom) {
- mStatusBar.onPanelLaidOut();
requestPanelHeightUpdate();
mHasLayoutedSinceDown = true;
if (mUpdateFlingOnLayout) {
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 6e37f90..115d164 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -177,7 +177,7 @@
import com.android.systemui.recents.ScreenPinningRequest;
import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.shared.system.WindowManagerWrapper;
-import com.android.systemui.stackdivider.Divider;
+import com.android.systemui.stackdivider.SplitScreen;
import com.android.systemui.statusbar.AutoHideUiElement;
import com.android.systemui.statusbar.BackDropView;
import com.android.systemui.statusbar.CommandQueue;
@@ -388,7 +388,7 @@
private final Lazy<BiometricUnlockController> mBiometricUnlockControllerLazy;
private final Provider<StatusBarComponent.Builder> mStatusBarComponentBuilder;
private final PluginManager mPluginManager;
- private final Optional<Divider> mDividerOptional;
+ private final Optional<SplitScreen> mSplitScreenOptional;
private final StatusBarNotificationActivityStarter.Builder
mStatusBarNotificationActivityStarterBuilder;
private final ShadeController mShadeController;
@@ -721,7 +721,7 @@
Optional<Recents> recentsOptional,
Provider<StatusBarComponent.Builder> statusBarComponentBuilder,
PluginManager pluginManager,
- Optional<Divider> dividerOptional,
+ Optional<SplitScreen> splitScreenOptional,
LightsOutNotifController lightsOutNotifController,
StatusBarNotificationActivityStarter.Builder
statusBarNotificationActivityStarterBuilder,
@@ -803,7 +803,7 @@
mRecentsOptional = recentsOptional;
mStatusBarComponentBuilder = statusBarComponentBuilder;
mPluginManager = pluginManager;
- mDividerOptional = dividerOptional;
+ mSplitScreenOptional = splitScreenOptional;
mStatusBarNotificationActivityStarterBuilder = statusBarNotificationActivityStarterBuilder;
mShadeController = shadeController;
mSuperStatusBarViewFactory = superStatusBarViewFactory;
@@ -1550,31 +1550,32 @@
if (!mRecentsOptional.isPresent()) {
return false;
}
- Divider divider = null;
- if (mDividerOptional.isPresent()) {
- divider = mDividerOptional.get();
- }
- if (divider == null || !divider.isDividerVisible()) {
- final int navbarPos = WindowManagerWrapper.getInstance().getNavBarPosition(mDisplayId);
- if (navbarPos == NAV_BAR_POS_INVALID) {
- return false;
- }
- int createMode = navbarPos == NAV_BAR_POS_LEFT
- ? SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT
- : SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
- return mRecentsOptional.get().splitPrimaryTask(createMode, null, metricsDockAction);
- } else {
- if (divider.isMinimized() && !divider.isHomeStackResizable()) {
- // Undocking from the minimized state is not supported
- return false;
- } else {
- divider.onUndockingTask();
- if (metricsUndockAction != -1) {
- mMetricsLogger.action(metricsUndockAction);
+
+ if (mSplitScreenOptional.isPresent()) {
+ SplitScreen splitScreen = mSplitScreenOptional.get();
+ if (splitScreen.isDividerVisible()) {
+ if (splitScreen.isMinimized()
+ && !splitScreen.isHomeStackResizable()) {
+ // Undocking from the minimized state is not supported
+ return false;
+ } else {
+ splitScreen.onUndockingTask();
+ if (metricsUndockAction != -1) {
+ mMetricsLogger.action(metricsUndockAction);
+ }
}
+ return true;
}
}
- return true;
+
+ final int navbarPos = WindowManagerWrapper.getInstance().getNavBarPosition(mDisplayId);
+ if (navbarPos == NAV_BAR_POS_INVALID) {
+ return false;
+ }
+ int createMode = navbarPos == NAV_BAR_POS_LEFT
+ ? SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT
+ : SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
+ return mRecentsOptional.get().splitPrimaryTask(createMode, null, metricsDockAction);
}
/**
@@ -3916,14 +3917,14 @@
@Override
public void appTransitionCancelled(int displayId) {
if (displayId == mDisplayId) {
- mDividerOptional.ifPresent(Divider::onAppTransitionFinished);
+ mSplitScreenOptional.ifPresent(splitScreen -> splitScreen.onAppTransitionFinished());
}
}
@Override
public void appTransitionFinished(int displayId) {
if (displayId == mDisplayId) {
- mDividerOptional.ifPresent(Divider::onAppTransitionFinished);
+ mSplitScreenOptional.ifPresent(splitScreen -> splitScreen.onAppTransitionFinished());
}
}
@@ -4221,25 +4222,6 @@
KeyboardShortcuts.dismiss();
}
- /**
- * Called when the notification panel layouts
- */
- public void onPanelLaidOut() {
- updateKeyguardMaxNotifications();
- }
-
- public void updateKeyguardMaxNotifications() {
- if (mState == StatusBarState.KEYGUARD) {
- // Since the number of notifications is determined based on the height of the view, we
- // need to update them.
- int maxBefore = mPresenter.getMaxNotificationsWhileLocked(false /* recompute */);
- int maxNotifications = mPresenter.getMaxNotificationsWhileLocked(true /* recompute */);
- if (maxBefore != maxNotifications) {
- mViewHierarchyManager.updateRowStates();
- }
- }
- }
-
public void executeActionDismissingKeyguard(Runnable action, boolean afterKeyguardGone) {
if (!mDeviceProvisionedController.isDeviceProvisioned()) return;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
index 67adaaa..024a0b1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
@@ -110,7 +110,6 @@
private final AboveShelfObserver mAboveShelfObserver;
private final DozeScrimController mDozeScrimController;
private final ScrimController mScrimController;
- private final Context mContext;
private final KeyguardIndicationController mKeyguardIndicationController;
private final StatusBar mStatusBar;
private final ShadeController mShadeController;
@@ -119,7 +118,6 @@
private final AccessibilityManager mAccessibilityManager;
private final KeyguardManager mKeyguardManager;
private final ActivityLaunchAnimator mActivityLaunchAnimator;
- private final int mMaxAllowedKeyguardNotifications;
private final IStatusBarService mBarService;
private final DynamicPrivacyController mDynamicPrivacyController;
private boolean mReinflateNotificationsOnUserSwitched;
@@ -127,7 +125,6 @@
private TextView mNotificationPanelDebugText;
protected boolean mVrMode;
- private int mMaxKeyguardNotifications;
public StatusBarNotificationPresenter(Context context,
NotificationPanelViewController panel,
@@ -145,7 +142,6 @@
CommandQueue commandQueue,
InitController initController,
NotificationInterruptStateProvider notificationInterruptStateProvider) {
- mContext = context;
mKeyguardStateController = keyguardStateController;
mNotificationPanel = panel;
mHeadsUpManager = headsUp;
@@ -163,8 +159,6 @@
mDozeScrimController = dozeScrimController;
mScrimController = scrimController;
mKeyguardManager = context.getSystemService(KeyguardManager.class);
- mMaxAllowedKeyguardNotifications = context.getResources().getInteger(
- R.integer.keyguard_max_notification_count);
mBarService = IStatusBarService.Stub.asInterface(
ServiceManager.getService(Context.STATUS_BAR_SERVICE));
@@ -397,17 +391,6 @@
}
@Override
- public int getMaxNotificationsWhileLocked(boolean recompute) {
- if (recompute) {
- mMaxKeyguardNotifications = Math.max(1,
- mNotificationPanel.computeMaxKeyguardNotifications(
- mMaxAllowedKeyguardNotifications));
- return mMaxKeyguardNotifications;
- }
- return mMaxKeyguardNotifications;
- }
-
- @Override
public void onUpdateRowStates() {
mNotificationPanel.onUpdateRowStates();
}
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 2768b82..72067d3 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
@@ -46,7 +46,7 @@
import com.android.systemui.recents.Recents;
import com.android.systemui.recents.ScreenPinningRequest;
import com.android.systemui.shared.plugins.PluginManager;
-import com.android.systemui.stackdivider.Divider;
+import com.android.systemui.stackdivider.SplitScreen;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.KeyguardIndicationController;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
@@ -180,7 +180,7 @@
Optional<Recents> recentsOptional,
Provider<StatusBarComponent.Builder> statusBarComponentBuilder,
PluginManager pluginManager,
- Optional<Divider> dividerOptional,
+ Optional<SplitScreen> splitScreenOptional,
LightsOutNotifController lightsOutNotifController,
StatusBarNotificationActivityStarter.Builder
statusBarNotificationActivityStarterBuilder,
@@ -260,7 +260,7 @@
recentsOptional,
statusBarComponentBuilder,
pluginManager,
- dividerOptional,
+ splitScreenOptional,
lightsOutNotifController,
statusBarNotificationActivityStarterBuilder,
shadeController,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
index 33b1a4a..f39acf9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
@@ -39,6 +39,7 @@
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.dump.DumpManager;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -58,6 +59,7 @@
private static final String TAG = "BluetoothController";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+ private final DumpManager mDumpManager;
private final LocalBluetoothManager mLocalBluetoothManager;
private final UserManager mUserManager;
private final int mCurrentUser;
@@ -77,8 +79,13 @@
/**
*/
@Inject
- public BluetoothControllerImpl(Context context, @Background Looper bgLooper,
- @Main Looper mainLooper, @Nullable LocalBluetoothManager localBluetoothManager) {
+ public BluetoothControllerImpl(
+ Context context,
+ DumpManager dumpManager,
+ @Background Looper bgLooper,
+ @Main Looper mainLooper,
+ @Nullable LocalBluetoothManager localBluetoothManager) {
+ mDumpManager = dumpManager;
mLocalBluetoothManager = localBluetoothManager;
mBgHandler = new Handler(bgLooper);
mHandler = new H(mainLooper);
@@ -90,6 +97,7 @@
}
mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
mCurrentUser = ActivityManager.getCurrentUser();
+ mDumpManager.registerDumpable(TAG, this);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java b/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java
index ca9cb08..e7c10f1 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java
@@ -42,7 +42,6 @@
import com.android.systemui.qs.tileimpl.QSFactoryImpl;
import com.android.systemui.recents.Recents;
import com.android.systemui.recents.RecentsImplementation;
-import com.android.systemui.stackdivider.DividerModule;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationLockscreenUserManagerImpl;
@@ -76,7 +75,6 @@
* overridden by the System UI implementation.
*/
@Module(includes = {
- DividerModule.class,
QSModule.class,
WMShellModule.class
},
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
new file mode 100644
index 0000000..4922600
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
@@ -0,0 +1,111 @@
+/*
+ * 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.wmshell;
+
+import static com.android.systemui.shared.system.WindowManagerWrapper.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
+
+import android.app.ActivityManager;
+import android.content.Context;
+
+import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.keyguard.KeyguardUpdateMonitorCallback;
+import com.android.systemui.SystemUI;
+import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.shared.system.ActivityManagerWrapper;
+import com.android.systemui.shared.system.TaskStackChangeListener;
+import com.android.systemui.stackdivider.SplitScreen;
+import com.android.wm.shell.common.DisplayImeController;
+
+import java.util.Optional;
+
+import javax.inject.Inject;
+
+/**
+ * Proxy in SysUiScope to delegate events to controllers in WM Shell library.
+ */
+@SysUISingleton
+public final class WMShell extends SystemUI {
+ private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+ private final DisplayImeController mDisplayImeController;
+ private final Optional<SplitScreen> mSplitScreenOptional;
+
+ @Inject
+ WMShell(Context context, KeyguardUpdateMonitor keyguardUpdateMonitor,
+ DisplayImeController displayImeController,
+ Optional<SplitScreen> splitScreenOptional) {
+ super(context);
+ mKeyguardUpdateMonitor = keyguardUpdateMonitor;
+ mDisplayImeController = displayImeController;
+ mSplitScreenOptional = splitScreenOptional;
+ }
+
+ @Override
+ public void start() {
+ // This is to prevent circular init problem by separating registration step out of its
+ // constructor. And make sure the initialization of DisplayImeController won't depend on
+ // specific feature anymore.
+ mDisplayImeController.startMonitorDisplays();
+
+ mSplitScreenOptional.ifPresent(this::initSplitScreen);
+ }
+
+ private void initSplitScreen(SplitScreen splitScreen) {
+ mKeyguardUpdateMonitor.registerCallback(new KeyguardUpdateMonitorCallback() {
+ @Override
+ public void onKeyguardVisibilityChanged(boolean showing) {
+ // Hide the divider when keyguard is showing. Even though keyguard/statusbar is
+ // above everything, it is actually transparent except for notifications, so
+ // we still need to hide any surfaces that are below it.
+ // TODO(b/148906453): Figure out keyguard dismiss animation for divider view.
+ splitScreen.onKeyguardVisibilityChanged(showing);
+ }
+ });
+
+ ActivityManagerWrapper.getInstance().registerTaskStackListener(
+ new TaskStackChangeListener() {
+ @Override
+ public void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task,
+ boolean homeTaskVisible, boolean clearedTask, boolean wasVisible) {
+ if (!wasVisible || task.configuration.windowConfiguration.getWindowingMode()
+ != WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
+ || !splitScreen.isSplitScreenSupported()) {
+ return;
+ }
+
+ if (splitScreen.isMinimized()) {
+ splitScreen.onUndockingTask();
+ }
+ }
+
+ @Override
+ public void onActivityForcedResizable(String packageName, int taskId,
+ int reason) {
+ splitScreen.onActivityForcedResizable(packageName, taskId, reason);
+ }
+
+ @Override
+ public void onActivityDismissingDockedStack() {
+ splitScreen.onActivityDismissingSplitScreen();
+ }
+
+ @Override
+ public void onActivityLaunchOnSecondaryDisplayFailed() {
+ splitScreen.onActivityLaunchOnSecondaryDisplayFailed();
+ }
+ });
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java
index 18cb7d3..0a3172ce 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java
@@ -24,6 +24,7 @@
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.pip.PipUiEventLogger;
+import com.android.systemui.stackdivider.SplitScreen;
import com.android.systemui.util.DeviceConfigProxy;
import com.android.systemui.util.FloatingContentCoordinator;
import com.android.wm.shell.ShellTaskOrganizer;
@@ -31,6 +32,7 @@
import com.android.wm.shell.common.SystemWindows;
import com.android.wm.shell.common.TransactionPool;
+import dagger.BindsOptionalOf;
import dagger.Module;
import dagger.Provides;
@@ -40,7 +42,7 @@
*/
// TODO(b/162923491): Move most of these dependencies into WMSingleton scope.
@Module
-public class WMShellBaseModule {
+public abstract class WMShellBaseModule {
@SysUISingleton
@Provides
static TransactionPool provideTransactionPool() {
@@ -59,6 +61,7 @@
static DeviceConfigProxy provideDeviceConfigProxy() {
return new DeviceConfigProxy();
}
+
@SysUISingleton
@Provides
static FloatingContentCoordinator provideFloatingContentCoordinator() {
@@ -80,9 +83,12 @@
@SysUISingleton
@Provides
- public ShellTaskOrganizer provideShellTaskOrganizer() {
+ static ShellTaskOrganizer provideShellTaskOrganizer() {
ShellTaskOrganizer organizer = new ShellTaskOrganizer();
organizer.registerOrganizer();
return organizer;
}
+
+ @BindsOptionalOf
+ abstract SplitScreen optionalSplitScreen();
}
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java
index 44bb6ac..7b45476 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java
@@ -16,6 +16,7 @@
package com.android.systemui.wmshell;
+import android.content.Context;
import android.os.Handler;
import android.view.IWindowManager;
@@ -23,8 +24,12 @@
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.pip.phone.PipMenuActivity;
import com.android.systemui.pip.phone.dagger.PipMenuActivityClass;
+import com.android.systemui.stackdivider.SplitScreen;
+import com.android.systemui.stackdivider.SplitScreenController;
+import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayImeController;
+import com.android.wm.shell.common.SystemWindows;
import com.android.wm.shell.common.TransactionPool;
import dagger.Module;
@@ -42,8 +47,7 @@
static DisplayImeController provideDisplayImeController(IWindowManager wmService,
DisplayController displayController, @Main Handler mainHandler,
TransactionPool transactionPool) {
- return new DisplayImeController.Builder(wmService, displayController, mainHandler,
- transactionPool).build();
+ return new DisplayImeController(wmService, displayController, mainHandler, transactionPool);
}
/** TODO(b/150319024): PipMenuActivity will move to a Window */
@@ -53,4 +57,14 @@
static Class<?> providePipMenuActivityClass() {
return PipMenuActivity.class;
}
+
+ @SysUISingleton
+ @Provides
+ static SplitScreen provideSplitScreen(Context context,
+ DisplayController displayController, SystemWindows systemWindows,
+ DisplayImeController displayImeController, @Main Handler handler,
+ TransactionPool transactionPool, ShellTaskOrganizer shellTaskOrganizer) {
+ return new SplitScreenController(context, displayController, systemWindows,
+ displayImeController, handler, transactionPool, shellTaskOrganizer);
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaTimeoutListenerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaTimeoutListenerTest.kt
index 7a8e4f7..f385243 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaTimeoutListenerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaTimeoutListenerTest.kt
@@ -155,6 +155,22 @@
}
@Test
+ fun testOnMediaDataLoaded_migratesKeys_noTimeoutExtension() {
+ // From not playing
+ mediaTimeoutListener.onMediaDataLoaded(KEY, null, mediaData)
+ clearInvocations(mediaController)
+
+ // Migrate, still not playing
+ val playingState = mock(android.media.session.PlaybackState::class.java)
+ `when`(playingState.state).thenReturn(PlaybackState.STATE_PAUSED)
+ `when`(mediaController.playbackState).thenReturn(playingState)
+ mediaTimeoutListener.onMediaDataLoaded("NEWKEY", KEY, mediaData)
+
+ // Never cancels callback, or schedule another one
+ verify(cancellationRunnable, never()).run()
+ }
+
+ @Test
fun testOnPlaybackStateChanged_schedulesTimeout_whenPaused() {
// Assuming we're registered
testOnMediaDataLoaded_registersPlaybackListener()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerTest.java
index 2e4d8a7..57dbac5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerTest.java
@@ -52,7 +52,7 @@
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.recents.Recents;
-import com.android.systemui.stackdivider.Divider;
+import com.android.systemui.stackdivider.SplitScreen;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.phone.ShadeController;
@@ -61,13 +61,13 @@
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
-import java.util.Optional;
-
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.Optional;
+
/** atest NavigationBarControllerTest */
@RunWith(AndroidTestingRunner.class)
@RunWithLooper
@@ -90,13 +90,13 @@
mock(AccessibilityManagerWrapper.class),
mock(DeviceProvisionedController.class),
mock(MetricsLogger.class),
- mock(OverviewProxyService.class),
+ mock(OverviewProxyService.class),
mock(NavigationModeController.class),
mock(StatusBarStateController.class),
mock(SysUiState.class),
mock(BroadcastDispatcher.class),
mock(CommandQueue.class),
- mock(Divider.class),
+ Optional.of(mock(SplitScreen.class)),
Optional.of(mock(Recents.class)),
() -> mock(StatusBar.class),
mock(ShadeController.class),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java
index a643c2d..389c5a0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java
@@ -68,7 +68,7 @@
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.recents.Recents;
-import com.android.systemui.stackdivider.Divider;
+import com.android.systemui.stackdivider.SplitScreen;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.phone.ShadeController;
@@ -121,7 +121,6 @@
mDependency.injectMockDependency(KeyguardStateController.class);
mDependency.injectMockDependency(StatusBarStateController.class);
mDependency.injectMockDependency(NavigationBarController.class);
- mDependency.injectMockDependency(Divider.class);
mOverviewProxyService = mDependency.injectMockDependency(OverviewProxyService.class);
TestableLooper.get(this).runWithLooper(() -> {
mHandler = new Handler();
@@ -224,7 +223,7 @@
mMockSysUiState,
mBroadcastDispatcher,
mCommandQueue,
- mock(Divider.class),
+ Optional.of(mock(SplitScreen.class)),
Optional.of(mock(Recents.class)),
() -> mock(StatusBar.class),
mock(ShadeController.class),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
index 1259d28..d2bf483 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
@@ -19,7 +19,6 @@
import static junit.framework.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
-import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
@@ -219,7 +218,7 @@
mViewHierarchyManager.onDynamicPrivacyChanged();
}
return null;
- }).when(mListContainer).setMaxDisplayedNotifications(anyInt());
+ }).when(mListContainer).onNotificationViewUpdateFinished();
// WHEN we call updateNotificationViews()
mViewHierarchyManager.updateNotificationViews();
@@ -247,7 +246,7 @@
mViewHierarchyManager.onDynamicPrivacyChanged();
}
return null;
- }).when(mListContainer).setMaxDisplayedNotifications(anyInt());
+ }).when(mListContainer).onNotificationViewUpdateFinished();
// WHEN we call updateNotificationViews() and drain the looper
mViewHierarchyManager.updateNotificationViews();
@@ -262,7 +261,6 @@
private class FakeListContainer implements NotificationListContainer {
final LinearLayout mLayout = new LinearLayout(mContext);
final List<View> mRows = Lists.newArrayList();
- private boolean mMakeReentrantCallDuringSetMaxDisplayedNotifications;
@Override
public void setChildTransferInProgress(boolean childTransferInProgress) {}
@@ -322,9 +320,6 @@
@Override
public void setMaxDisplayedNotifications(int maxNotifications) {
- if (mMakeReentrantCallDuringSetMaxDisplayedNotifications) {
- mViewHierarchyManager.onDynamicPrivacyChanged();
- }
}
@Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
index d4718e7..fc0201a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
@@ -346,7 +346,6 @@
setSmartActions(mEntry.getKey(), null);
mEntryManager.updateNotificationRanking(mRankingMap);
- verify(mRow, never()).setEntry(eq(mEntry));
assertNull(mEntry.getSmartActions());
}
@@ -360,7 +359,6 @@
setSmartActions(mEntry.getKey(), new ArrayList<>(Arrays.asList(createAction())));
mEntryManager.updateNotificationRanking(mRankingMap);
- verify(mRow, never()).setEntry(eq(mEntry));
assertEquals(1, mEntry.getSmartActions().size());
assertEquals("action", mEntry.getSmartActions().get(0).title);
}
@@ -375,7 +373,6 @@
setSmartActions(mEntry.getKey(), new ArrayList<>(Arrays.asList(createAction())));
mEntryManager.updateNotificationRanking(mRankingMap);
- verify(mRow, never()).setEntry(eq(mEntry));
assertEquals(1, mEntry.getSmartActions().size());
assertEquals("action", mEntry.getSmartActions().get(0).title);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
index 9a8678f0..df26c5b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
@@ -406,12 +406,12 @@
entry.setRow(row);
mIconManager.createIcons(entry);
- row.setEntry(entry);
mBindPipelineEntryListener.onEntryInit(entry);
mBindPipeline.manageRow(entry, row);
row.initialize(
+ entry,
APP_NAME,
entry.getKey(),
mock(ExpansionLogger.class),
@@ -426,6 +426,7 @@
mStatusBarStateController,
mPeopleNotificationIdentifier,
mock(OnUserInteractionCallback.class));
+
row.setAboveShelfChangedListener(aboveShelf -> { });
mBindStage.getStageParams(entry).requireContentViews(extraInflationFlags);
inflateAndWait(entry);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
index bca7b31..fa9ea6b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
@@ -18,7 +18,6 @@
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;
-import static junit.framework.Assert.assertNull;
import static org.junit.Assert.assertFalse;
import static org.mockito.ArgumentMatchers.any;
@@ -34,12 +33,10 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.metrics.LogMaker;
import android.os.UserHandle;
import android.provider.Settings;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
-import android.view.View;
import androidx.test.annotation.UiThreadTest;
import androidx.test.filters.SmallTest;
@@ -52,6 +49,7 @@
import com.android.systemui.SysuiTestCase;
import com.android.systemui.classifier.FalsingManagerFake;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.EmptyShadeView;
import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.NotificationMediaManager;
@@ -132,6 +130,7 @@
@Mock private NotificationSection mNotificationSection;
@Mock private FeatureFlags mFeatureFlags;
@Mock private SysuiStatusBarStateController mStatusBarStateController;
+ @Mock private NotificationSwipeHelper mNotificationSwipeHelper;
private NotificationEntryManager mEntryManager;
private int mOriginalInterruptionModelSetting;
private UiEventLoggerFake mUiEventLoggerFake = new UiEventLoggerFake();
@@ -216,7 +215,8 @@
mock(NotifCollection.class),
mUiEventLoggerFake
);
- mStackScrollerInternal.initView(getContext(), mKeyguardBypassEnabledProvider);
+ mStackScrollerInternal.initView(getContext(), mKeyguardBypassEnabledProvider,
+ mNotificationSwipeHelper);
mStackScroller = spy(mStackScrollerInternal);
mStackScroller.setShelfController(notificationShelfController);
mStackScroller.setStatusBar(mBar);
@@ -420,31 +420,22 @@
@Test
@UiThreadTest
public void testSetIsBeingDraggedResetsExposedMenu() {
- NotificationSwipeHelper swipeActionHelper =
- (NotificationSwipeHelper) mStackScroller.getSwipeActionHelper();
- swipeActionHelper.setExposedMenuView(new View(mContext));
mStackScroller.setIsBeingDragged(true);
- assertNull(swipeActionHelper.getExposedMenuView());
+ verify(mNotificationSwipeHelper).resetExposedMenuView(true, true);
}
@Test
@UiThreadTest
public void testPanelTrackingStartResetsExposedMenu() {
- NotificationSwipeHelper swipeActionHelper =
- (NotificationSwipeHelper) mStackScroller.getSwipeActionHelper();
- swipeActionHelper.setExposedMenuView(new View(mContext));
mStackScroller.onPanelTrackingStarted();
- assertNull(swipeActionHelper.getExposedMenuView());
+ verify(mNotificationSwipeHelper).resetExposedMenuView(true, true);
}
@Test
@UiThreadTest
public void testDarkModeResetsExposedMenu() {
- NotificationSwipeHelper swipeActionHelper =
- (NotificationSwipeHelper) mStackScroller.getSwipeActionHelper();
- swipeActionHelper.setExposedMenuView(new View(mContext));
mStackScroller.setHideAmount(0.1f, 0.1f);
- assertNull(swipeActionHelper.getExposedMenuView());
+ verify(mNotificationSwipeHelper).resetExposedMenuView(true, true);
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollerControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollerControllerTest.java
index 83d6ac9..4fffd3e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollerControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollerControllerTest.java
@@ -26,6 +26,7 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.content.res.Resources;
import android.metrics.LogMaker;
import android.testing.AndroidTestingRunner;
@@ -36,6 +37,7 @@
import com.android.systemui.SysuiTestCase;
import com.android.systemui.colorextraction.SysuiColorExtractor;
import com.android.systemui.media.KeyguardMediaController;
+import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.OnMenuEventListener;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -47,6 +49,7 @@
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
+import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.ZenModeController;
import com.android.systemui.tuner.TunerService;
@@ -54,6 +57,7 @@
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Answers;
import org.mockito.ArgumentCaptor;
import org.mockito.ArgumentMatcher;
import org.mockito.Mock;
@@ -94,6 +98,18 @@
private NotificationLockscreenUserManager mNotificationLockscreenUserManager;
@Mock
private MetricsLogger mMetricsLogger;
+ @Mock
+ private FalsingManager mFalsingManager;
+ @Mock
+ private NotificationSectionsManager mNotificationSectionsManager;
+ @Mock
+ private Resources mResources;
+ @Mock(answer = Answers.RETURNS_SELF)
+ private NotificationSwipeHelper.Builder mNotificationSwipeHelperBuilder;
+ @Mock
+ private NotificationSwipeHelper mNotificationSwipeHelper;
+ @Mock
+ private StatusBar mStatusBar;
private NotificationStackScrollLayoutController mController;
@@ -101,6 +117,8 @@
public void setUp() {
MockitoAnnotations.initMocks(this);
+ when(mNotificationSwipeHelperBuilder.build()).thenReturn(mNotificationSwipeHelper);
+
mController = new NotificationStackScrollLayoutController(
true,
mNotificationGutsManager,
@@ -115,7 +133,12 @@
mZenModeController,
mColorExtractor,
mNotificationLockscreenUserManager,
- mMetricsLogger
+ mMetricsLogger,
+ mFalsingManager,
+ mNotificationSectionsManager,
+ mResources,
+ mNotificationSwipeHelperBuilder,
+ mStatusBar
);
when(mNotificationStackScrollLayout.isAttachedToWindow()).thenReturn(true);
@@ -233,7 +256,7 @@
ArgumentCaptor.forClass(OnMenuEventListener.class);
mController.attach(mNotificationStackScrollLayout);
- verify(mNotificationStackScrollLayout).setMenuEventListener(
+ verify(mNotificationSwipeHelperBuilder).setOnMenuEventListener(
onMenuEventListenerArgumentCaptor.capture());
OnMenuEventListener onMenuEventListener = onMenuEventListenerArgumentCaptor.getValue();
@@ -255,7 +278,7 @@
ArgumentCaptor.forClass(OnMenuEventListener.class);
mController.attach(mNotificationStackScrollLayout);
- verify(mNotificationStackScrollLayout).setMenuEventListener(
+ verify(mNotificationSwipeHelperBuilder).setOnMenuEventListener(
onMenuEventListenerArgumentCaptor.capture());
OnMenuEventListener onMenuEventListener = onMenuEventListenerArgumentCaptor.getValue();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java
index 323d8bd..0faf5d4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java
@@ -35,6 +35,7 @@
import android.testing.TestableLooper;
import android.view.MotionEvent;
import android.view.View;
+import android.view.ViewConfiguration;
import androidx.test.filters.SmallTest;
@@ -78,7 +79,8 @@
mCallback = mock(NotificationSwipeHelper.NotificationCallback.class);
mListener = mock(NotificationMenuRowPlugin.OnMenuEventListener.class);
mSwipeHelper = spy(new NotificationSwipeHelper(
- SwipeHelper.X, mCallback, mContext, mListener, new FalsingManagerFake()));
+ mContext.getResources(), ViewConfiguration.get(mContext),
+ new FalsingManagerFake(), SwipeHelper.X, mCallback, mListener));
mView = mock(View.class);
mEvent = mock(MotionEvent.class);
mMenuRow = mock(NotificationMenuRowPlugin.class);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
index c9e9d94..04e870d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
@@ -52,6 +52,7 @@
import com.android.internal.util.LatencyTracker;
import com.android.keyguard.KeyguardClockSwitch;
import com.android.keyguard.KeyguardClockSwitchController;
+import com.android.keyguard.KeyguardStatusView;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
@@ -217,6 +218,8 @@
when(mKeyguardBottomArea.getRightView()).thenReturn(mock(KeyguardAffordanceView.class));
when(mView.findViewById(R.id.big_clock_container)).thenReturn(mBigClockContainer);
when(mView.findViewById(R.id.qs_frame)).thenReturn(mQsFrame);
+ when(mView.findViewById(R.id.keyguard_status_view))
+ .thenReturn(mock(KeyguardStatusView.class));
FlingAnimationUtils.Builder flingAnimationUtilsBuilder = new FlingAnimationUtils.Builder(
mDisplayMetrics);
@@ -239,6 +242,7 @@
mStatusBarStateController,
new FalsingManagerFake());
mNotificationPanelViewController = new NotificationPanelViewController(mView,
+ mResources,
mInjectionInflationController,
coordinator, expansionHandler, mDynamicPrivacyController, mKeyguardBypassController,
mFalsingManager, mShadeController,
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 8462386..87aee3f 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
@@ -96,7 +96,7 @@
import com.android.systemui.recents.Recents;
import com.android.systemui.recents.ScreenPinningRequest;
import com.android.systemui.shared.plugins.PluginManager;
-import com.android.systemui.stackdivider.Divider;
+import com.android.systemui.stackdivider.SplitScreen;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.KeyguardIndicationController;
import com.android.systemui.statusbar.NotificationListener;
@@ -238,7 +238,7 @@
@Mock private StatusBarComponent.Builder mStatusBarComponentBuilder;
@Mock private StatusBarComponent mStatusBarComponent;
@Mock private PluginManager mPluginManager;
- @Mock private Divider mDivider;
+ @Mock private SplitScreen mSplitScreen;
@Mock private SuperStatusBarViewFactory mSuperStatusBarViewFactory;
@Mock private LightsOutNotifController mLightsOutNotifController;
@Mock private ViewMediatorCallback mViewMediatorCallback;
@@ -397,7 +397,7 @@
Optional.of(mRecents),
mStatusBarComponentBuilderProvider,
mPluginManager,
- Optional.of(mDivider),
+ Optional.of(mSplitScreen),
mLightsOutNotifController,
mStatusBarNotificationActivityStarterBuilder,
mShadeController,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java
index fbbfa96..3dd36d1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java
@@ -41,6 +41,7 @@
import com.android.settingslib.bluetooth.LocalBluetoothProfile;
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.dump.DumpManager;
import org.junit.Before;
import org.junit.Test;
@@ -58,6 +59,7 @@
private CachedBluetoothDeviceManager mMockDeviceManager;
private LocalBluetoothAdapter mMockAdapter;
private TestableLooper mTestableLooper;
+ private DumpManager mMockDumpManager;
private BluetoothControllerImpl mBluetoothControllerImpl;
private List<CachedBluetoothDevice> mDevices;
@@ -75,8 +77,10 @@
when(mMockBluetoothManager.getEventManager()).thenReturn(mock(BluetoothEventManager.class));
when(mMockBluetoothManager.getProfileManager())
.thenReturn(mock(LocalBluetoothProfileManager.class));
+ mMockDumpManager = mock(DumpManager.class);
mBluetoothControllerImpl = new BluetoothControllerImpl(mContext,
+ mMockDumpManager,
mTestableLooper.getLooper(),
mTestableLooper.getLooper(),
mMockBluetoothManager);
diff --git a/services/core/java/android/content/pm/PackageManagerInternal.java b/services/core/java/android/content/pm/PackageManagerInternal.java
index ad1986a6..cf9324c 100644
--- a/services/core/java/android/content/pm/PackageManagerInternal.java
+++ b/services/core/java/android/content/pm/PackageManagerInternal.java
@@ -302,24 +302,11 @@
String packageName, int userId);
/**
- * Do a straight uid lookup for the given package/application in the given user. This enforces
- * app visibility rules and permissions. Call {@link #getPackageUidInternal} for the internal
- * implementation.
- * @deprecated Use {@link PackageManager#getPackageUid(String, int)}
- * @return The app's uid, or < 0 if the package was not found in that user
- */
- @Deprecated
- public abstract int getPackageUid(String packageName,
- @PackageInfoFlags int flags, int userId);
-
- /**
* Do a straight uid lookup for the given package/application in the given user.
* @see PackageManager#getPackageUidAsUser(String, int, int)
* @return The app's uid, or < 0 if the package was not found in that user
- * TODO(b/148235092): rename this to getPackageUid
*/
- public abstract int getPackageUidInternal(String packageName,
- @PackageInfoFlags int flags, int userId);
+ public abstract int getPackageUid(String packageName, @PackageInfoFlags int flags, int userId);
/**
* Retrieve all of the information we know about a particular package/application.
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index b72985c..27c5d4a 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -2160,7 +2160,7 @@
Slog.i(TAG, "Remounting storage for pid: " + pid);
final String[] sharedPackages =
mPmInternal.getSharedUserPackagesForPackage(packageName, userId);
- final int uid = mPmInternal.getPackageUidInternal(packageName, 0, userId);
+ final int uid = mPmInternal.getPackageUid(packageName, 0 /* flags */, userId);
final String[] packages =
sharedPackages.length != 0 ? sharedPackages : new String[]{packageName};
try {
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 19871f9..eb8308b 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -2106,20 +2106,20 @@
synchronized (mRecords) {
if (validatePhoneId(phoneId)) {
mOutgoingCallEmergencyNumber[phoneId] = emergencyNumber;
- for (Record r : mRecords) {
- if (r.matchPhoneStateListenerEvent(
- PhoneStateListener.LISTEN_OUTGOING_EMERGENCY_CALL)
- && idMatch(r.subId, subId, phoneId)) {
- try {
- r.callback.onOutgoingEmergencyCall(emergencyNumber);
- } catch (RemoteException ex) {
- mRemoveList.add(r.binder);
- }
+ }
+ for (Record r : mRecords) {
+ // Send to all listeners regardless of subscription
+ if (r.matchPhoneStateListenerEvent(
+ PhoneStateListener.LISTEN_OUTGOING_EMERGENCY_CALL)) {
+ try {
+ r.callback.onOutgoingEmergencyCall(emergencyNumber, subId);
+ } catch (RemoteException ex) {
+ mRemoveList.add(r.binder);
}
}
}
- handleRemoveListLocked();
}
+ handleRemoveListLocked();
}
@Override
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 9ab410d..3fddd5a 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -2591,7 +2591,7 @@
if (mCurIntent != null && name.equals(mCurIntent.getComponent())) {
mCurMethod = IInputMethod.Stub.asInterface(service);
final String curMethodPackage = mCurIntent.getComponent().getPackageName();
- final int curMethodUid = mPackageManagerInternal.getPackageUidInternal(
+ final int curMethodUid = mPackageManagerInternal.getPackageUid(
curMethodPackage, 0 /* flags */, mSettings.getCurrentUserId());
if (curMethodUid < 0) {
Slog.e(TAG, "Failed to get UID for package=" + curMethodPackage);
diff --git a/services/core/java/com/android/server/locksettings/BiometricDeferredQueue.java b/services/core/java/com/android/server/locksettings/BiometricDeferredQueue.java
index e3074db..ddd56c8 100644
--- a/services/core/java/com/android/server/locksettings/BiometricDeferredQueue.java
+++ b/services/core/java/com/android/server/locksettings/BiometricDeferredQueue.java
@@ -123,6 +123,10 @@
final VerifyCredentialResponse response = spManager.verifyChallengeInternal(
getGatekeeperService(), userAuthInfo.gatekeeperPassword, challenge,
userAuthInfo.userId);
+ if (response == null) {
+ Slog.wtf(TAG, "VerifyChallenge failed, null response");
+ continue;
+ }
if (response.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK) {
Slog.wtf(TAG, "VerifyChallenge failed, response: "
+ response.getResponseCode());
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index 93352dc..26c3132 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -1090,7 +1090,9 @@
public void setSeparateProfileChallengeEnabled(int userId, boolean enabled,
LockscreenCredential managedUserPassword) {
checkWritePermission(userId);
- if (!mHasSecureLockScreen) {
+ if (!mHasSecureLockScreen
+ && managedUserPassword != null
+ && managedUserPassword.getType() != CREDENTIAL_TYPE_NONE) {
throw new UnsupportedOperationException(
"This operation requires secure lock screen feature.");
}
@@ -1560,7 +1562,8 @@
public boolean setLockCredential(LockscreenCredential credential,
LockscreenCredential savedCredential, int userId) {
- if (!mHasSecureLockScreen) {
+ if (!mHasSecureLockScreen
+ && credential != null && credential.getType() != CREDENTIAL_TYPE_NONE) {
throw new UnsupportedOperationException(
"This operation requires secure lock screen feature");
}
@@ -3423,7 +3426,8 @@
@Override
public boolean setLockCredentialWithToken(LockscreenCredential credential, long tokenHandle,
byte[] token, int userId) {
- if (!mHasSecureLockScreen) {
+ if (!mHasSecureLockScreen
+ && credential != null && credential.getType() != CREDENTIAL_TYPE_NONE) {
throw new UnsupportedOperationException(
"This operation requires secure lock screen feature.");
}
diff --git a/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java b/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java
index 617f687..a234f5a 100644
--- a/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java
+++ b/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java
@@ -605,7 +605,7 @@
private boolean isPlatformSignedAppWithAutomaticProfilesPermission(
String packageName, int[] profileIds) {
for (int userId : profileIds) {
- final int uid = mInjector.getPackageManagerInternal().getPackageUidInternal(
+ final int uid = mInjector.getPackageManagerInternal().getPackageUid(
packageName, /* flags= */ 0, userId);
if (uid == -1) {
continue;
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 28c5e96..ed62362 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -134,6 +134,7 @@
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.util.IndentingPrintWriter;
+import com.android.internal.util.Preconditions;
import com.android.server.LocalServices;
import com.android.server.pm.Installer.InstallerException;
import com.android.server.pm.dex.DexManager;
@@ -1325,6 +1326,7 @@
final int status = intent.getIntExtra(PackageInstaller.EXTRA_STATUS,
PackageInstaller.STATUS_FAILURE);
final int sessionIndex = mChildSessionsRemaining.indexOfKey(sessionId);
+ final String message = intent.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE);
if (PackageInstaller.STATUS_SUCCESS == status) {
mChildSessionsRemaining.removeAt(sessionIndex);
if (mChildSessionsRemaining.size() == 0) {
@@ -1341,10 +1343,9 @@
intent.putExtra(PackageInstaller.EXTRA_SESSION_ID,
PackageInstallerSession.this.sessionId);
mChildSessionsRemaining.clear(); // we're done. Don't send any more.
- try {
- mStatusReceiver.sendIntent(mContext, 0, intent, null, null);
- } catch (IntentSender.SendIntentException ignore) {
- }
+ destroyInternal();
+ dispatchSessionFinished(INSTALL_FAILED_INTERNAL_ERROR,
+ "Child session " + sessionId + " failed: " + message, null);
}
});
}
@@ -1554,12 +1555,28 @@
}
private void onSessionValidationFailure(int error, String detailMessage) {
- // Session is sealed but could not be verified, we need to destroy it.
+ // Session is sealed but could not be validated, we need to destroy it.
destroyInternal();
// Dispatch message to remove session from PackageInstallerService.
dispatchSessionFinished(error, detailMessage, null);
}
+ private void onSessionVerificationFailure(int error, String detailMessage) {
+ Slog.e(TAG, "Failed to verify session " + sessionId + " [" + detailMessage + "]");
+ // Session is sealed and committed but could not be verified, we need to destroy it.
+ destroyInternal();
+ if (isStaged()) {
+ setStagedSessionFailed(
+ SessionInfo.STAGED_SESSION_VERIFICATION_FAILED, detailMessage);
+ // TODO(b/136257624): Remove this once all verification logic has been transferred out
+ // of StagingManager.
+ mStagingManager.notifyVerificationComplete(sessionId);
+ } else {
+ // Dispatch message to remove session from PackageInstallerService.
+ dispatchSessionFinished(error, detailMessage, null);
+ }
+ }
+
private void onStorageUnhealthy() {
final String packageName = getPackageName();
if (TextUtils.isEmpty(packageName)) {
@@ -1680,7 +1697,8 @@
}
if (params.isStaged) {
mStagingManager.commitSession(this);
- destroyInternal();
+ // TODO(b/136257624): CTS test fails if we don't send session finished broadcast, even
+ // though ideally, we just need to send session committed broadcast.
dispatchSessionFinished(PackageManager.INSTALL_SUCCEEDED, "Session staged", null);
return;
}
@@ -1691,14 +1709,30 @@
"APEX packages can only be installed using staged sessions.", null);
return;
}
+ verify();
+ }
+ /**
+ * Resumes verification process for non-final committed staged session.
+ *
+ * Useful if a device gets rebooted before verification is complete and we need to restart the
+ * verification.
+ */
+ void verifyStagedSession() {
+ assertCallerIsOwnerOrRootOrSystemLocked();
+ Preconditions.checkArgument(isCommitted());
+ Preconditions.checkArgument(isStaged());
+ Preconditions.checkArgument(!mStagedSessionApplied && !mStagedSessionFailed);
+
+ verify();
+ }
+
+ private void verify() {
try {
verifyNonStaged();
} catch (PackageManagerException e) {
final String completeMsg = ExceptionUtils.getCompleteMessage(e);
- Slog.e(TAG, "Commit of session " + sessionId + " failed: " + completeMsg);
- destroyInternal();
- dispatchSessionFinished(e.error, completeMsg, null);
+ onSessionVerificationFailure(e.error, completeMsg);
}
}
@@ -1846,7 +1880,9 @@
@GuardedBy("mLock")
private PackageManagerService.VerificationParams makeVerificationParamsLocked()
throws PackageManagerException {
- if (!params.isMultiPackage) {
+ // TODO(b/136257624): Some logic in this if block probably belongs in
+ // makeInstallParams().
+ if (!params.isMultiPackage && !isApexInstallation()) {
Objects.requireNonNull(mPackageName);
Objects.requireNonNull(mSigningDetails);
Objects.requireNonNull(mResolvedBaseFile);
@@ -1923,8 +1959,7 @@
if (returnCode == PackageManager.INSTALL_SUCCEEDED) {
onVerificationComplete();
} else {
- destroyInternal();
- dispatchSessionFinished(returnCode, msg, extras);
+ onSessionVerificationFailure(returnCode, msg);
}
}
};
@@ -1946,9 +1981,13 @@
}
private void onVerificationComplete() {
- if ((params.installFlags & PackageManager.INSTALL_DRY_RUN) != 0) {
- destroyInternal();
- dispatchSessionFinished(PackageManager.INSTALL_SUCCEEDED, "Dry run", new Bundle());
+ // Staged sessions will be installed later during boot
+ if (isStaged()) {
+ // TODO(b/136257624): Remove this once all verification logic has been transferred out
+ // of StagingManager.
+ mStagingManager.notifyPreRebootVerification_Apk_Complete(sessionId);
+ // TODO(b/136257624): We also need to destroy internals for verified staged session,
+ // otherwise file descriptors are never closed for verified staged session until reboot
return;
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 3b98d24..c05bc45 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -5806,10 +5806,6 @@
private void updateSequenceNumberLP(PackageSetting pkgSetting, int[] userList) {
for (int i = userList.length - 1; i >= 0; --i) {
final int userId = userList[i];
- // don't add instant app to the list of updates
- if (pkgSetting.getInstantApp(userId)) {
- continue;
- }
SparseArray<String> changedPackages = mChangedPackages.get(userId);
if (changedPackages == null) {
changedPackages = new SparseArray<>();
@@ -5854,6 +5850,11 @@
for (int i = sequenceNumber; i < mChangedPackagesSequenceNumber; i++) {
final String packageName = changedPackages.get(i);
if (packageName != null) {
+ // Filter out the changes if the calling package should not be able to see it.
+ final PackageSetting ps = mSettings.mPackages.get(packageName);
+ if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
+ continue;
+ }
packageNames.add(packageName);
}
}
@@ -15200,6 +15201,13 @@
}
public void handleStartCopy() {
+ if ((installFlags & PackageManager.INSTALL_APEX) != 0) {
+ // Apex packages get verified in StagingManager currently.
+ // TODO(b/136257624): Move apex verification logic out of StagingManager
+ mRet = INSTALL_SUCCEEDED;
+ return;
+ }
+
PackageInfoLite pkgLite = PackageManagerServiceUtils.getMinimalPackageInfo(mContext,
origin.resolvedPath, installFlags, packageAbiOverride);
@@ -24603,12 +24611,6 @@
@Override
public int getPackageUid(String packageName, int flags, int userId) {
return PackageManagerService.this
- .getPackageUid(packageName, flags, userId);
- }
-
- @Override
- public int getPackageUidInternal(String packageName, int flags, int userId) {
- return PackageManagerService.this
.getPackageUidInternal(packageName, flags, userId, Process.SYSTEM_UID);
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 21f14db..4d2e22a 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -3197,12 +3197,24 @@
return 0;
}
+ private long getFileStatSize(File file) {
+ final ParcelFileDescriptor pfd = openFileForSystem(file.getPath(), "r");
+ if (pfd == null) {
+ throw new IllegalArgumentException("Error: Can't open file: " + file.getPath());
+ }
+ try {
+ return pfd.getStatSize();
+ } finally {
+ IoUtils.closeQuietly(pfd);
+ }
+ }
+
private void processArgForLocalFile(String arg, PackageInstaller.Session session) {
final String inPath = arg;
final File file = new File(inPath);
final String name = file.getName();
- final long size = file.length();
+ final long size = getFileStatSize(file);
final Metadata metadata = Metadata.forLocalFile(inPath);
byte[] v4signatureBytes = null;
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index d545bd4..659e2a3 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -4551,6 +4551,7 @@
? "true" : "false");
pw.print(prefix); pw.print(" primaryCpuAbi="); pw.println(ps.primaryCpuAbiString);
pw.print(prefix); pw.print(" secondaryCpuAbi="); pw.println(ps.secondaryCpuAbiString);
+ pw.print(prefix); pw.print(" cpuAbiOverride="); pw.println(ps.cpuAbiOverrideString);
}
pw.print(prefix); pw.print(" versionCode="); pw.print(ps.versionCode);
if (pkg != null) {
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index 700f7be..8412077 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -3301,7 +3301,7 @@
final long token = Binder.clearCallingIdentity();
try {
- int packageUid = mPackageManagerInternal.getPackageUidInternal(packageName,
+ int packageUid = mPackageManagerInternal.getPackageUid(packageName,
PackageManager.MATCH_DIRECT_BOOT_AUTO, userId);
// Grant read uri permission to the caller on behalf of the shortcut owner. All
// granted permissions are revoked when the default launcher changes, or when
diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java
index 105a9b0..dfdf115 100644
--- a/services/core/java/com/android/server/pm/StagingManager.java
+++ b/services/core/java/com/android/server/pm/StagingManager.java
@@ -1299,6 +1299,20 @@
return session;
}
+ // TODO(b/136257624): Temporary API to let PMS communicate with StagingManager. When all
+ // verification logic is extraced out of StagingManager into PMS, we can remove
+ // this.
+ void notifyVerificationComplete(int sessionId) {
+ mPreRebootVerificationHandler.onPreRebootVerificationComplete(sessionId);
+ }
+
+ // TODO(b/136257624): Temporary API to let PMS communicate with StagingManager. When all
+ // verification logic is extraced out of StagingManager into PMS, we can remove
+ // this.
+ void notifyPreRebootVerification_Apk_Complete(int sessionId) {
+ mPreRebootVerificationHandler.notifyPreRebootVerification_Apk_Complete(sessionId);
+ }
+
private final class PreRebootVerificationHandler extends Handler {
// Hold session ids before handler gets ready to do the verification.
private IntArray mPendingSessionIds;
@@ -1500,25 +1514,16 @@
}
/**
- * Pre-reboot verification state for apk files:
- * <p><ul>
- * <li>performs a dry-run install of apk</li>
- * </ul></p>
+ * Pre-reboot verification state for apk files. Session is sent to
+ * {@link PackageManagerService} for verification and it notifies back the result via
+ * {@link #notifyPreRebootVerification_Apk_Complete(int)}
*/
private void handlePreRebootVerification_Apk(@NonNull PackageInstallerSession session) {
if (!sessionContainsApk(session)) {
notifyPreRebootVerification_Apk_Complete(session.sessionId);
return;
}
-
- try {
- Slog.d(TAG, "Running a pre-reboot verification for APKs in session "
- + session.sessionId + " by performing a dry-run install");
- // verifyApksInSession will notify the handler when APK verification is complete
- verifyApksInSession(session);
- } catch (PackageManagerException e) {
- onPreRebootVerificationFailure(session, e.error, e.getMessage());
- }
+ session.verifyStagedSession();
}
private void verifyApksInSession(PackageInstallerSession session)
diff --git a/services/core/java/com/android/server/uri/UriGrantsManagerService.java b/services/core/java/com/android/server/uri/UriGrantsManagerService.java
index a106dc6..0b0bb70 100644
--- a/services/core/java/com/android/server/uri/UriGrantsManagerService.java
+++ b/services/core/java/com/android/server/uri/UriGrantsManagerService.java
@@ -258,7 +258,7 @@
final int callingUid = Binder.getCallingUid();
final int callingUserId = UserHandle.getUserId(callingUid);
final PackageManagerInternal pm = LocalServices.getService(PackageManagerInternal.class);
- final int packageUid = pm.getPackageUidInternal(packageName,
+ final int packageUid = pm.getPackageUid(packageName,
MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
if (packageUid != callingUid) {
throw new SecurityException(
@@ -336,7 +336,7 @@
if (toPackage != null) {
mAmInternal.enforceCallingPermission(FORCE_PERSISTABLE_URI_PERMISSIONS,
"takePersistableUriPermission");
- uid = mPmInternal.getPackageUidInternal(toPackage, 0, userId);
+ uid = mPmInternal.getPackageUid(toPackage, 0 /* flags */, userId);
} else {
enforceNotIsolatedCaller("takePersistableUriPermission");
uid = Binder.getCallingUid();
@@ -401,7 +401,7 @@
if (toPackage != null) {
mAmInternal.enforceCallingPermission(FORCE_PERSISTABLE_URI_PERMISSIONS,
"releasePersistableUriPermission");
- uid = mPmInternal.getPackageUidInternal(toPackage, 0, userId);
+ uid = mPmInternal.getPackageUid(toPackage, 0 /* flags */ , userId);
} else {
enforceNotIsolatedCaller("releasePersistableUriPermission");
uid = Binder.getCallingUid();
@@ -600,7 +600,7 @@
if (needed != null) {
targetUid = needed.targetUid;
} else {
- targetUid = mPmInternal.getPackageUidInternal(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
+ targetUid = mPmInternal.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
targetUserId);
if (targetUid < 0) {
if (DEBUG) Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
@@ -690,7 +690,7 @@
final ProviderInfo pi = getProviderInfo(uri.getAuthority(), sourceUserId,
MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
if (pi != null && sourcePkg.equals(pi.packageName)) {
- int targetUid = mPmInternal.getPackageUidInternal(
+ int targetUid = mPmInternal.getPackageUid(
targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
if (targetUid != -1) {
final GrantUri grantUri = new GrantUri(sourceUserId, uri,
@@ -787,7 +787,7 @@
if (targetPkg == null) {
throw new NullPointerException("targetPkg");
}
- int targetUid = mPmInternal.getPackageUidInternal(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
+ int targetUid = mPmInternal.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
targetUserId);
targetUid = checkGrantUriPermissionUnlocked(callingUid, targetPkg, grantUri, modeFlags,
@@ -1108,7 +1108,7 @@
int targetUid = lastTargetUid;
if (targetUid < 0 && targetPkg != null) {
- targetUid = mPmInternal.getPackageUidInternal(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
+ targetUid = mPmInternal.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
UserHandle.getUserId(callingUid));
if (targetUid < 0) {
if (DEBUG) Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg);
@@ -1462,7 +1462,8 @@
boolean printed = false;
int dumpUid = -2;
if (dumpPackage != null) {
- dumpUid = mPmInternal.getPackageUidInternal(dumpPackage, MATCH_ANY_USER, 0);
+ dumpUid = mPmInternal.getPackageUid(dumpPackage,
+ MATCH_ANY_USER, 0 /* userId */);
}
for (int i = 0; i < mGrantedUriPermissions.size(); i++) {
int uid = mGrantedUriPermissions.keyAt(i);
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateService.java b/services/core/java/com/android/server/webkit/WebViewUpdateService.java
index 9bbeb72..90a153b 100644
--- a/services/core/java/com/android/server/webkit/WebViewUpdateService.java
+++ b/services/core/java/com/android/server/webkit/WebViewUpdateService.java
@@ -209,8 +209,8 @@
private void grantVisibilityToCaller(String webViewPackageName, int callingUid) {
final PackageManagerInternal pmInternal = LocalServices.getService(
PackageManagerInternal.class);
- final int webviewUid = pmInternal.getPackageUidInternal(
- webViewPackageName, 0, UserHandle.getUserId(callingUid));
+ final int webviewUid = pmInternal.getPackageUid(
+ webViewPackageName, 0 /* flags */, UserHandle.getUserId(callingUid));
pmInternal.grantImplicitAccess(UserHandle.getUserId(callingUid), null,
UserHandle.getAppId(callingUid), webviewUid,
true /*direct*/);
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 9316c46..76473d08 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -2786,8 +2786,7 @@
}
makeFinishingLocked();
- final boolean activityRemoved = destroyImmediately(true /* removeFromApp */,
- "finish-imm:" + reason);
+ final boolean activityRemoved = destroyImmediately("finish-imm:" + reason);
// If the display does not have running activity, the configuration may need to be
// updated for restoring original orientation of the display.
@@ -2835,7 +2834,7 @@
* @return {@code true} if activity was immediately removed from history, {@code false}
* otherwise.
*/
- boolean destroyImmediately(boolean removeFromApp, String reason) {
+ boolean destroyImmediately(String reason) {
if (DEBUG_SWITCH || DEBUG_CLEANUP) {
Slog.v(TAG_SWITCH, "Removing activity from " + reason + ": token=" + this
+ ", app=" + (hasProcess() ? app.mName : "(null)"));
@@ -2857,17 +2856,9 @@
cleanUp(false /* cleanServices */, false /* setState */);
if (hasProcess()) {
- if (removeFromApp) {
- app.removeActivity(this, true /* keepAssociation */);
- if (!app.hasActivities()) {
- mAtmService.clearHeavyWeightProcessIfEquals(app);
- // Update any services we are bound to that might care about whether
- // their client may have activities.
- // No longer have activities, so update LRU list and oom adj.
- app.updateProcessInfo(true /* updateServiceConnectionActivities */,
- false /* activityChange */, true /* updateOomAdj */,
- false /* addPendingTopUid */);
- }
+ app.removeActivity(this, true /* keepAssociation */);
+ if (!app.hasActivities()) {
+ mAtmService.clearHeavyWeightProcessIfEquals(app);
}
boolean skipDestroy = false;
@@ -2934,7 +2925,7 @@
+ " pausing=" + stack.mPausingActivity
+ " for reason " + reason);
}
- return destroyImmediately(true /* removeFromApp */, reason);
+ return destroyImmediately(reason);
}
return false;
}
@@ -4487,16 +4478,40 @@
detachChildren();
}
- if (state == RESUMED) {
- mAtmService.updateBatteryStats(this, true);
- mAtmService.updateActivityUsageStats(this, Event.ACTIVITY_RESUMED);
- } else if (state == PAUSED) {
- mAtmService.updateBatteryStats(this, false);
- mAtmService.updateActivityUsageStats(this, Event.ACTIVITY_PAUSED);
- } else if (state == STOPPED) {
- mAtmService.updateActivityUsageStats(this, Event.ACTIVITY_STOPPED);
- } else if (state == DESTROYED) {
- mAtmService.updateActivityUsageStats(this, Event.ACTIVITY_DESTROYED);
+ switch (state) {
+ case RESUMED:
+ mAtmService.updateBatteryStats(this, true);
+ mAtmService.updateActivityUsageStats(this, Event.ACTIVITY_RESUMED);
+ // Fall through.
+ case STARTED:
+ // Update process info while making an activity from invisible to visible, to make
+ // sure the process state is updated to foreground.
+ if (app != null) {
+ app.updateProcessInfo(false /* updateServiceConnectionActivities */,
+ true /* activityChange */, true /* updateOomAdj */,
+ true /* addPendingTopUid */);
+ }
+ break;
+ case PAUSED:
+ mAtmService.updateBatteryStats(this, false);
+ mAtmService.updateActivityUsageStats(this, Event.ACTIVITY_PAUSED);
+ break;
+ case STOPPED:
+ mAtmService.updateActivityUsageStats(this, Event.ACTIVITY_STOPPED);
+ break;
+ case DESTROYED:
+ mAtmService.updateActivityUsageStats(this, Event.ACTIVITY_DESTROYED);
+ // Fall through.
+ case DESTROYING:
+ if (app != null && !app.hasActivities()) {
+ // Update any services we are bound to that might care about whether
+ // their client may have activities.
+ // No longer have activities, so update LRU list and oom adj.
+ app.updateProcessInfo(true /* updateServiceConnectionActivities */,
+ false /* activityChange */, true /* updateOomAdj */,
+ false /* addPendingTopUid */);
+ }
+ break;
}
}
@@ -4807,14 +4822,6 @@
}
setState(STARTED, "makeActiveIfNeeded");
- // Update process info while making an activity from invisible to visible, to make
- // sure the process state is updated to foreground.
- if (app != null) {
- app.updateProcessInfo(false /* updateServiceConnectionActivities */,
- true /* activityChange */, true /* updateOomAdj */,
- true /* addPendingTopUid */);
- }
-
try {
mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
StartActivityItem.obtain());
@@ -5122,7 +5129,7 @@
if (DEBUG_STATES) Slog.v(TAG_STATES, "Stop failed; moving to STOPPED: " + this);
setState(STOPPED, "stopIfPossible");
if (deferRelaunchUntilPaused) {
- destroyImmediately(true /* removeFromApp */, "stop-except");
+ destroyImmediately("stop-except");
}
}
}
@@ -5163,7 +5170,7 @@
clearOptionsLocked();
} else {
if (deferRelaunchUntilPaused) {
- destroyImmediately(true /* removeFromApp */, "stop-config");
+ destroyImmediately("stop-config");
mRootWindowContainer.resumeFocusedStacksTopActivities();
} else {
mRootWindowContainer.updatePreviousProcess(this);
@@ -7113,7 +7120,7 @@
if (!attachedToProcess()) {
if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
"Config is destroying non-running " + this);
- destroyImmediately(true /* removeFromApp */, "config");
+ destroyImmediately("config");
} else if (mState == PAUSING) {
// A little annoying: we are waiting for this activity to finish pausing. Let's not
// do anything now, but just flag that it needs to be restarted when done pausing.
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index 2c475e0..34f7f79 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -41,10 +41,8 @@
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.os.PowerManager.PARTIAL_WAKE_LOCK;
import static android.os.Process.INVALID_UID;
-import static android.os.Process.SYSTEM_UID;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.view.Display.DEFAULT_DISPLAY;
-import static android.view.Display.TYPE_VIRTUAL;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ALL;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CLEANUP;
@@ -1869,7 +1867,7 @@
for (int i = 0; i < numFinishingActivities; i++) {
final ActivityRecord r = finishingActivities.get(i);
if (r.isInHistory()) {
- r.destroyImmediately(true /* removeFromApp */, "finish-" + reason);
+ r.destroyImmediately("finish-" + reason);
}
}
}
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index f615838..4c93b9e 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -1693,8 +1693,9 @@
// we need to resolve resultTo to a uid as grantImplicitAccess deals explicitly in UIDs
final PackageManagerInternal pmInternal =
mService.getPackageManagerInternalLocked();
- final int resultToUid = pmInternal.getPackageUidInternal(
- mStartActivity.resultTo.info.packageName, 0, mStartActivity.mUserId);
+ final int resultToUid = pmInternal.getPackageUid(
+ mStartActivity.resultTo.info.packageName, 0 /* flags */,
+ mStartActivity.mUserId);
pmInternal.grantImplicitAccess(mStartActivity.mUserId, mIntent,
UserHandle.getAppId(mStartActivity.info.applicationInfo.uid) /*recipient*/,
resultToUid /*visible*/, true /*direct*/);
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 403f225..2adaa52 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -3379,7 +3379,7 @@
if (r == null || !r.isDestroyable()) {
return false;
}
- r.destroyImmediately(true /* removeFromApp */, "app-req");
+ r.destroyImmediately("app-req");
return r.isState(DESTROYING, DESTROYED);
} finally {
Binder.restoreCallingIdentity(origId);
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index aeaffd9..6dfbd21 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -2716,7 +2716,7 @@
+ " resumed=" + r.getStack().mResumedActivity + " pausing="
+ r.getStack().mPausingActivity + " for reason " + mDestroyAllActivitiesReason);
- r.destroyImmediately(true /* removeFromTask */, mDestroyAllActivitiesReason);
+ r.destroyImmediately(mDestroyAllActivitiesReason);
}
// Tries to put all activity stacks to sleep. Returns true if all stacks were
@@ -3124,7 +3124,6 @@
FinishDisabledPackageActivitiesHelper mFinishDisabledPackageActivitiesHelper =
new FinishDisabledPackageActivitiesHelper();
class FinishDisabledPackageActivitiesHelper {
- private boolean mDidSomething;
private String mPackageName;
private Set<String> mFilterByClasses;
private boolean mDoit;
@@ -3132,11 +3131,10 @@
private int mUserId;
private boolean mOnlyRemoveNoProcess;
private Task mLastTask;
- private ComponentName mHomeActivity;
+ private final ArrayList<ActivityRecord> mCollectedActivities = new ArrayList<>();
private void reset(String packageName, Set<String> filterByClasses,
boolean doit, boolean evenPersistent, int userId, boolean onlyRemoveNoProcess) {
- mDidSomething = false;
mPackageName = packageName;
mFilterByClasses = filterByClasses;
mDoit = doit;
@@ -3144,7 +3142,6 @@
mUserId = userId;
mOnlyRemoveNoProcess = onlyRemoveNoProcess;
mLastTask = null;
- mHomeActivity = null;
}
boolean process(String packageName, Set<String> filterByClasses,
@@ -3152,14 +3149,35 @@
reset(packageName, filterByClasses, doit, evenPersistent, userId, onlyRemoveNoProcess);
final PooledFunction f = PooledLambda.obtainFunction(
- FinishDisabledPackageActivitiesHelper::processActivity, this,
+ FinishDisabledPackageActivitiesHelper::collectActivity, this,
PooledLambda.__(ActivityRecord.class));
forAllActivities(f);
f.recycle();
- return mDidSomething;
+
+ boolean didSomething = false;
+ final int size = mCollectedActivities.size();
+ // Keep the finishing order from top to bottom.
+ for (int i = 0; i < size; i++) {
+ final ActivityRecord r = mCollectedActivities.get(i);
+ if (mOnlyRemoveNoProcess) {
+ if (!r.hasProcess()) {
+ didSomething = true;
+ Slog.i(TAG, " Force removing " + r);
+ r.cleanUp(false /* cleanServices */, false /* setState */);
+ r.removeFromHistory("force-stop");
+ }
+ } else {
+ didSomething = true;
+ Slog.i(TAG, " Force finishing " + r);
+ r.finishIfPossible("force-stop", true /* oomAdj */);
+ }
+ }
+ mCollectedActivities.clear();
+
+ return didSomething;
}
- private boolean processActivity(ActivityRecord r) {
+ private boolean collectActivity(ActivityRecord r) {
final boolean sameComponent =
(r.packageName.equals(mPackageName) && (mFilterByClasses == null
|| mFilterByClasses.contains(r.mActivityComponent.getClassName())))
@@ -3176,26 +3194,7 @@
}
return true;
}
- if (r.isActivityTypeHome()) {
- if (mHomeActivity != null && mHomeActivity.equals(r.mActivityComponent)) {
- Slog.i(TAG, "Skip force-stop again " + r);
- return false;
- } else {
- mHomeActivity = r.mActivityComponent;
- }
- }
- if (mOnlyRemoveNoProcess) {
- if (noProcess) {
- mDidSomething = true;
- Slog.i(TAG, " Force removing " + r);
- r.cleanUp(false /* cleanServices */, false /* setState */);
- r.removeFromHistory("force-stop");
- }
- } else {
- mDidSomething = true;
- Slog.i(TAG, " Force finishing " + r);
- r.finishIfPossible("force-stop", true /* oomAdj */);
- }
+ mCollectedActivities.add(r);
mLastTask = r.getTask();
}
diff --git a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
index 3c8036d..25732e7 100644
--- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -101,7 +101,6 @@
private final Transformation mRotateExitTransformation = new Transformation();
private final Transformation mRotateEnterTransformation = new Transformation();
// Complete transformations being applied.
- private final Transformation mEnterTransformation = new Transformation();
private final Matrix mSnapshotInitialMatrix = new Matrix();
private final WindowManagerService mService;
/** Only used for custom animations and not screen rotation. */
@@ -309,8 +308,6 @@
pw.print(" "); mRotateExitTransformation.printShortString(pw); pw.println();
pw.print(prefix); pw.print("mRotateEnterAnimation="); pw.print(mRotateEnterAnimation);
pw.print(" "); mRotateEnterTransformation.printShortString(pw); pw.println();
- pw.print(prefix); pw.print("mEnterTransformation=");
- mEnterTransformation.printShortString(pw); pw.println();
pw.print(prefix); pw.print("mSnapshotInitialMatrix=");
mSnapshotInitialMatrix.dump(pw); pw.println();
pw.print(prefix); pw.print("mForceDefaultOrientation="); pw.print(mForceDefaultOrientation);
@@ -508,10 +505,6 @@
return mCurRotation != mOriginalRotation;
}
- public Transformation getEnterTransformation() {
- return mEnterTransformation;
- }
-
/**
* Utility class that runs a {@link ScreenRotationAnimation} on the {@link
* SurfaceAnimationRunner}.
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 4dbbbc6..e77a535 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -6190,10 +6190,6 @@
next.setState(RESUMED, "resumeTopActivityInnerLocked");
- next.app.updateProcessInfo(false /* updateServiceConnectionActivities */,
- true /* activityChange */, true /* updateOomAdj */,
- true /* addPendingTopUid */);
-
// Have the window manager re-evaluate the orientation of
// the screen based on the new activity order.
boolean notUpdated = true;
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index c714eeb..bb9cf2e 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -941,7 +941,7 @@
final ActivityRecord r = candidates.remove(0);
if (DEBUG_RELEASE) Slog.v(TAG_RELEASE, "Destroying " + r
+ " in state " + r.getState() + " for reason " + reason);
- r.destroyImmediately(true /*removeFromApp*/, reason);
+ r.destroyImmediately(reason);
--maxRelease;
} while (maxRelease > 0);
}
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 0e455d2..69d3821 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -2058,10 +2058,17 @@
// animating... let's do something.
final int left = mWindowFrames.mFrame.left;
final int top = mWindowFrames.mFrame.top;
+
+ // During the transition from pip to fullscreen, the activity windowing mode is set to
+ // fullscreen at the beginning while the task is kept in pinned mode. Skip the move
+ // animation in such case since the transition is handled in SysUI.
+ final boolean hasMovementAnimation = getTask() == null
+ ? getWindowConfiguration().hasMovementAnimations()
+ : getTask().getWindowConfiguration().hasMovementAnimations();
if (mToken.okToAnimate()
&& (mAttrs.privateFlags & PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0
&& !isDragResizing()
- && getWindowConfiguration().hasMovementAnimations()
+ && hasMovementAnimation
&& !mWinAnimator.mLastHidden
&& !mSeamlesslyRotated) {
startMoveAnimation(left, top);
@@ -3562,6 +3569,13 @@
}
void reportResized() {
+ // If the activity is scheduled to relaunch, skip sending the resized to ViewRootImpl now
+ // since it will be destroyed anyway. This also prevents the client from receiving
+ // windowing mode change before it is destroyed.
+ if (mActivityRecord != null && mActivityRecord.isRelaunching()) {
+ return;
+ }
+
if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "wm.reportResized_" + getWindowTag());
}
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 4ff985f..6f48342 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -660,80 +660,7 @@
}
void computeShownFrameLocked() {
- final ScreenRotationAnimation screenRotationAnimation =
- mWin.getDisplayContent().getRotationAnimation();
- final boolean windowParticipatesInScreenRotationAnimation =
- !mWin.mForceSeamlesslyRotate;
- final boolean screenAnimation = screenRotationAnimation != null
- && screenRotationAnimation.isAnimating()
- && windowParticipatesInScreenRotationAnimation;
-
- if (screenAnimation) {
- // cache often used attributes locally
- final Rect frame = mWin.getFrameLw();
- final float tmpFloats[] = mService.mTmpFloats;
- final Matrix tmpMatrix = mWin.mTmpMatrix;
-
- // Compute the desired transformation.
- if (screenRotationAnimation.isRotating()) {
- // If we are doing a screen animation, the global rotation
- // applied to windows can result in windows that are carefully
- // aligned with each other to slightly separate, allowing you
- // to see what is behind them. An unsightly mess. This...
- // thing... magically makes it call good: scale each window
- // slightly (two pixels larger in each dimension, from the
- // window's center).
- final float w = frame.width();
- final float h = frame.height();
- if (w>=1 && h>=1) {
- tmpMatrix.setScale(1 + 2/w, 1 + 2/h, w/2, h/2);
- } else {
- tmpMatrix.reset();
- }
- } else {
- tmpMatrix.reset();
- }
-
- tmpMatrix.postScale(mWin.mGlobalScale, mWin.mGlobalScale);
-
- // WindowState.prepareSurfaces expands for surface insets (in order they don't get
- // clipped by the WindowState surface), so we need to go into the other direction here.
- tmpMatrix.postTranslate(mWin.mAttrs.surfaceInsets.left,
- mWin.mAttrs.surfaceInsets.top);
-
-
- // "convert" it into SurfaceFlinger's format
- // (a 2x2 matrix + an offset)
- // Here we must not transform the position of the surface
- // since it is already included in the transformation.
- //Slog.i(TAG_WM, "Transform: " + matrix);
-
- mHaveMatrix = true;
- tmpMatrix.getValues(tmpFloats);
- mDsDx = tmpFloats[Matrix.MSCALE_X];
- mDtDx = tmpFloats[Matrix.MSKEW_Y];
- mDtDy = tmpFloats[Matrix.MSKEW_X];
- mDsDy = tmpFloats[Matrix.MSCALE_Y];
-
- // Now set the alpha... but because our current hardware
- // can't do alpha transformation on a non-opaque surface,
- // turn it off if we are running an animation that is also
- // transforming since it is more important to have that
- // animation be smooth.
- mShownAlpha = mAlpha;
- if (!mService.mLimitedAlphaCompositing
- || (!PixelFormat.formatHasAlpha(mWin.mAttrs.format)
- || (mWin.isIdentityMatrix(mDsDx, mDtDx, mDtDy, mDsDy)))) {
- mShownAlpha *= screenRotationAnimation.getEnterTransformation().getAlpha();
- }
-
- if ((DEBUG_ANIM || DEBUG) && (mShownAlpha == 1.0 || mShownAlpha == 0.0)) {
- Slog.v(TAG, "computeShownFrameLocked: Animating " + this + " mAlpha=" + mAlpha
- + " screen=" + (screenAnimation
- ? screenRotationAnimation.getEnterTransformation().getAlpha() : "null"));
- }
- return;
- } else if (mIsWallpaper && mService.mRoot.mWallpaperActionPending) {
+ if (mIsWallpaper && mService.mRoot.mWallpaperActionPending) {
return;
} else if (mWin.isDragResizeChanged()) {
// This window is awaiting a relayout because user just started (or ended)
diff --git a/services/incremental/BinderIncrementalService.cpp b/services/incremental/BinderIncrementalService.cpp
index 0ae10b6..41945a2 100644
--- a/services/incremental/BinderIncrementalService.cpp
+++ b/services/incremental/BinderIncrementalService.cpp
@@ -237,11 +237,9 @@
return ok();
}
-binder::Status BinderIncrementalService::isFileRangeLoaded(int32_t storageId,
- const std::string& path, int64_t start,
- int64_t end, bool* _aidl_return) {
- // TODO: implement
- *_aidl_return = false;
+binder::Status BinderIncrementalService::getLoadingProgress(int32_t storageId,
+ float* _aidl_return) {
+ *_aidl_return = mImpl.getLoadingProgress(storageId);
return ok();
}
diff --git a/services/incremental/BinderIncrementalService.h b/services/incremental/BinderIncrementalService.h
index 1015494..8b40350 100644
--- a/services/incremental/BinderIncrementalService.h
+++ b/services/incremental/BinderIncrementalService.h
@@ -66,8 +66,7 @@
int32_t destStorageId, const std::string& destPath,
int32_t* _aidl_return) final;
binder::Status unlink(int32_t storageId, const std::string& path, int32_t* _aidl_return) final;
- binder::Status isFileRangeLoaded(int32_t storageId, const std::string& path, int64_t start,
- int64_t end, bool* _aidl_return) final;
+ binder::Status getLoadingProgress(int32_t storageId, float* _aidl_return) final;
binder::Status getMetadataByPath(int32_t storageId, const std::string& path,
std::vector<uint8_t>* _aidl_return) final;
binder::Status getMetadataById(int32_t storageId, const std::vector<uint8_t>& id,
diff --git a/services/incremental/IncrementalService.cpp b/services/incremental/IncrementalService.cpp
index f7082a9..ba6ae92 100644
--- a/services/incremental/IncrementalService.cpp
+++ b/services/incremental/IncrementalService.cpp
@@ -37,7 +37,6 @@
#include "Metadata.pb.h"
using namespace std::literals;
-namespace fs = std::filesystem;
constexpr const char* kDataUsageStats = "android.permission.LOADER_USAGE_STATS";
constexpr const char* kOpUsage = "android:loader_usage_stats";
@@ -276,6 +275,7 @@
mJni(sm.getJni()),
mLooper(sm.getLooper()),
mTimedQueue(sm.getTimedQueue()),
+ mFs(sm.getFs()),
mIncrementalDir(rootDir) {
CHECK(mVold) << "Vold service is unavailable";
CHECK(mDataLoaderManager) << "DataLoaderManagerService is unavailable";
@@ -283,6 +283,7 @@
CHECK(mJni) << "JNI is unavailable";
CHECK(mLooper) << "Looper is unavailable";
CHECK(mTimedQueue) << "TimedQueue is unavailable";
+ CHECK(mFs) << "Fs is unavailable";
mJobQueue.reserve(16);
mJobProcessor = std::thread([this]() {
@@ -344,7 +345,8 @@
}
dprintf(fd, " storages (%d): {\n", int(mnt.storages.size()));
for (auto&& [storageId, storage] : mnt.storages) {
- dprintf(fd, " [%d] -> [%s]\n", storageId, storage.name.c_str());
+ dprintf(fd, " [%d] -> [%s] (%d %% loaded) \n", storageId, storage.name.c_str(),
+ (int)(getLoadingProgressFromPath(mnt, storage.name.c_str()) * 100));
}
dprintf(fd, " }\n");
@@ -1671,6 +1673,45 @@
return mRunning;
}
+float IncrementalService::getLoadingProgress(StorageId storage) const {
+ std::unique_lock l(mLock);
+ const auto ifs = getIfsLocked(storage);
+ if (!ifs) {
+ LOG(ERROR) << "getLoadingProgress failed, invalid storageId: " << storage;
+ return -EINVAL;
+ }
+ const auto storageInfo = ifs->storages.find(storage);
+ if (storageInfo == ifs->storages.end()) {
+ LOG(ERROR) << "getLoadingProgress failed, no storage: " << storage;
+ return -EINVAL;
+ }
+ l.unlock();
+ return getLoadingProgressFromPath(*ifs, storageInfo->second.name);
+}
+
+float IncrementalService::getLoadingProgressFromPath(const IncFsMount& ifs,
+ std::string_view storagePath) const {
+ size_t totalBlocks = 0, filledBlocks = 0;
+ const auto filePaths = mFs->listFilesRecursive(storagePath);
+ for (const auto& filePath : filePaths) {
+ const auto [filledBlocksCount, totalBlocksCount] =
+ mIncFs->countFilledBlocks(ifs.control, filePath);
+ if (filledBlocksCount < 0) {
+ LOG(ERROR) << "getLoadingProgress failed to get filled blocks count for: " << filePath
+ << " errno: " << filledBlocksCount;
+ return filledBlocksCount;
+ }
+ totalBlocks += totalBlocksCount;
+ filledBlocks += filledBlocksCount;
+ }
+
+ if (totalBlocks == 0) {
+ LOG(ERROR) << "getLoadingProgress failed to get total num of blocks";
+ return -EINVAL;
+ }
+ return (float)filledBlocks / (float)totalBlocks;
+}
+
bool IncrementalService::perfLoggingEnabled() {
static const bool enabled = base::GetBoolProperty("incremental.perflogging", false);
return enabled;
@@ -2029,11 +2070,13 @@
// Healthcheck depends on timestamp of the oldest pending read.
// To get it, we need to re-open a pendingReads FD to get a full list of reads.
- // Additionally we need to re-register for epoll with fresh FDs in case there are no reads.
+ // Additionally we need to re-register for epoll with fresh FDs in case there are no
+ // reads.
const auto now = Clock::now();
const auto kernelTsUs = getOldestPendingReadTs();
if (baseline) {
- // Updating baseline only on looper/epoll callback, i.e. on new set of pending reads.
+ // Updating baseline only on looper/epoll callback, i.e. on new set of pending
+ // reads.
mHealthBase = {now, kernelTsUs};
}
diff --git a/services/incremental/IncrementalService.h b/services/incremental/IncrementalService.h
index a6cc946..cd6bfed 100644
--- a/services/incremental/IncrementalService.h
+++ b/services/incremental/IncrementalService.h
@@ -132,9 +132,7 @@
std::string_view newPath);
int unlink(StorageId storage, std::string_view path);
- bool isRangeLoaded(StorageId storage, FileId file, std::pair<BlockIndex, BlockIndex> range) {
- return false;
- }
+ float getLoadingProgress(StorageId storage) const;
RawMetadata getMetadata(StorageId storage, std::string_view path) const;
RawMetadata getMetadata(StorageId storage, FileId node) const;
@@ -341,6 +339,8 @@
int makeDirs(const IncFsMount& ifs, StorageId storageId, std::string_view path, int mode);
binder::Status applyStorageParams(IncFsMount& ifs, bool enableReadLogs);
+ float getLoadingProgressFromPath(const IncFsMount& ifs, std::string_view path) const;
+
void registerAppOpsCallback(const std::string& packageName);
bool unregisterAppOpsCallback(const std::string& packageName);
void onAppOpChanged(const std::string& packageName);
@@ -363,6 +363,7 @@
const std::unique_ptr<JniWrapper> mJni;
const std::unique_ptr<LooperWrapper> mLooper;
const std::unique_ptr<TimedQueueWrapper> mTimedQueue;
+ const std::unique_ptr<FsWrapper> mFs;
const std::string mIncrementalDir;
mutable std::mutex mLock;
diff --git a/services/incremental/ServiceWrappers.cpp b/services/incremental/ServiceWrappers.cpp
index 99a35ad..1ed46c4 100644
--- a/services/incremental/ServiceWrappers.cpp
+++ b/services/incremental/ServiceWrappers.cpp
@@ -25,6 +25,7 @@
#include <binder/AppOpsManager.h>
#include <utils/String16.h>
+#include <filesystem>
#include <thread>
#include "IncrementalServiceValidation.h"
@@ -165,6 +166,29 @@
FileId getFileId(const Control& control, std::string_view path) const final {
return incfs::getFileId(control, path);
}
+ std::pair<IncFsBlockIndex, IncFsBlockIndex> countFilledBlocks(
+ const Control& control, std::string_view path) const final {
+ const auto fileId = incfs::getFileId(control, path);
+ const auto fd = incfs::openForSpecialOps(control, fileId);
+ int res = fd.get();
+ if (!fd.ok()) {
+ return {res, res};
+ }
+ const auto ranges = incfs::getFilledRanges(res);
+ res = ranges.first;
+ if (res) {
+ return {res, res};
+ }
+ const auto totalBlocksCount = ranges.second.internalRawRanges().endIndex;
+ int filledBlockCount = 0;
+ for (const auto& dataRange : ranges.second.dataRanges()) {
+ filledBlockCount += dataRange.size();
+ }
+ for (const auto& hashRange : ranges.second.hashRanges()) {
+ filledBlockCount += hashRange.size();
+ }
+ return {filledBlockCount, totalBlocksCount};
+ }
ErrorCode link(const Control& control, std::string_view from, std::string_view to) const final {
return incfs::link(control, from, to);
}
@@ -265,6 +289,23 @@
std::thread mThread;
};
+class RealFsWrapper : public FsWrapper {
+public:
+ RealFsWrapper() = default;
+ ~RealFsWrapper() = default;
+
+ std::vector<std::string> listFilesRecursive(std::string_view directoryPath) const final {
+ std::vector<std::string> files;
+ for (const auto& entry : std::filesystem::recursive_directory_iterator(directoryPath)) {
+ if (!entry.is_regular_file()) {
+ continue;
+ }
+ files.push_back(entry.path().c_str());
+ }
+ return files;
+ }
+};
+
RealServiceManager::RealServiceManager(sp<IServiceManager> serviceManager, JNIEnv* env)
: mServiceManager(std::move(serviceManager)), mJvm(RealJniWrapper::getJvm(env)) {}
@@ -316,6 +357,10 @@
return std::make_unique<RealTimedQueueWrapper>(mJvm);
}
+std::unique_ptr<FsWrapper> RealServiceManager::getFs() {
+ return std::make_unique<RealFsWrapper>();
+}
+
static JavaVM* getJavaVm(JNIEnv* env) {
CHECK(env);
JavaVM* jvm = nullptr;
diff --git a/services/incremental/ServiceWrappers.h b/services/incremental/ServiceWrappers.h
index 8cd726fd..82a1704 100644
--- a/services/incremental/ServiceWrappers.h
+++ b/services/incremental/ServiceWrappers.h
@@ -91,6 +91,8 @@
virtual incfs::RawMetadata getMetadata(const Control& control, FileId fileid) const = 0;
virtual incfs::RawMetadata getMetadata(const Control& control, std::string_view path) const = 0;
virtual FileId getFileId(const Control& control, std::string_view path) const = 0;
+ virtual std::pair<IncFsBlockIndex, IncFsBlockIndex> countFilledBlocks(
+ const Control& control, std::string_view path) const = 0;
virtual ErrorCode link(const Control& control, std::string_view from,
std::string_view to) const = 0;
virtual ErrorCode unlink(const Control& control, std::string_view path) const = 0;
@@ -106,7 +108,8 @@
virtual ~AppOpsManagerWrapper() = default;
virtual binder::Status checkPermission(const char* permission, const char* operation,
const char* package) const = 0;
- virtual void startWatchingMode(int32_t op, const String16& packageName, const sp<IAppOpsCallback>& callback) = 0;
+ virtual void startWatchingMode(int32_t op, const String16& packageName,
+ const sp<IAppOpsCallback>& callback) = 0;
virtual void stopWatchingMode(const sp<IAppOpsCallback>& callback) = 0;
};
@@ -134,6 +137,12 @@
virtual void stop() = 0;
};
+class FsWrapper {
+public:
+ virtual ~FsWrapper() = default;
+ virtual std::vector<std::string> listFilesRecursive(std::string_view directoryPath) const = 0;
+};
+
class ServiceManagerWrapper {
public:
virtual ~ServiceManagerWrapper() = default;
@@ -144,6 +153,7 @@
virtual std::unique_ptr<JniWrapper> getJni() = 0;
virtual std::unique_ptr<LooperWrapper> getLooper() = 0;
virtual std::unique_ptr<TimedQueueWrapper> getTimedQueue() = 0;
+ virtual std::unique_ptr<FsWrapper> getFs() = 0;
};
// --- Real stuff ---
@@ -159,6 +169,7 @@
std::unique_ptr<JniWrapper> getJni() final;
std::unique_ptr<LooperWrapper> getLooper() final;
std::unique_ptr<TimedQueueWrapper> getTimedQueue() final;
+ std::unique_ptr<FsWrapper> getFs() final;
private:
template <class INTERFACE>
diff --git a/services/incremental/test/IncrementalServiceTest.cpp b/services/incremental/test/IncrementalServiceTest.cpp
index 1ae9e25..44cef49 100644
--- a/services/incremental/test/IncrementalServiceTest.cpp
+++ b/services/incremental/test/IncrementalServiceTest.cpp
@@ -54,8 +54,10 @@
MOCK_CONST_METHOD1(unmountIncFs, binder::Status(const std::string& dir));
MOCK_CONST_METHOD2(bindMount,
binder::Status(const std::string& sourceDir, const std::string& argetDir));
- MOCK_CONST_METHOD2(setIncFsMountOptions,
- binder::Status(const ::android::os::incremental::IncrementalFileSystemControlParcel&, bool));
+ MOCK_CONST_METHOD2(
+ setIncFsMountOptions,
+ binder::Status(const ::android::os::incremental::IncrementalFileSystemControlParcel&,
+ bool));
void mountIncFsFails() {
ON_CALL(*this, mountIncFs(_, _, _, _))
@@ -80,8 +82,8 @@
}
void setIncFsMountOptionsFails() const {
ON_CALL(*this, setIncFsMountOptions(_, _))
- .WillByDefault(
- Return(binder::Status::fromExceptionCode(1, String8("failed to set options"))));
+ .WillByDefault(Return(
+ binder::Status::fromExceptionCode(1, String8("failed to set options"))));
}
void setIncFsMountOptionsSuccess() {
ON_CALL(*this, setIncFsMountOptions(_, _)).WillByDefault(Return(binder::Status::ok()));
@@ -280,8 +282,12 @@
MOCK_CONST_METHOD2(getMetadata, RawMetadata(const Control& control, FileId fileid));
MOCK_CONST_METHOD2(getMetadata, RawMetadata(const Control& control, std::string_view path));
MOCK_CONST_METHOD2(getFileId, FileId(const Control& control, std::string_view path));
+ MOCK_CONST_METHOD2(countFilledBlocks,
+ std::pair<IncFsBlockIndex, IncFsBlockIndex>(const Control& control,
+ std::string_view path));
MOCK_CONST_METHOD3(link,
- ErrorCode(const Control& control, std::string_view from, std::string_view to));
+ ErrorCode(const Control& control, std::string_view from,
+ std::string_view to));
MOCK_CONST_METHOD2(unlink, ErrorCode(const Control& control, std::string_view path));
MOCK_CONST_METHOD2(openForSpecialOps, base::unique_fd(const Control& control, FileId id));
MOCK_CONST_METHOD1(writeBlocks, ErrorCode(std::span<const DataBlock> blocks));
@@ -293,6 +299,19 @@
void makeFileFails() { ON_CALL(*this, makeFile(_, _, _, _, _)).WillByDefault(Return(-1)); }
void makeFileSuccess() { ON_CALL(*this, makeFile(_, _, _, _, _)).WillByDefault(Return(0)); }
+
+ void countFilledBlocksSuccess() {
+ ON_CALL(*this, countFilledBlocks(_, _)).WillByDefault(Return(std::make_pair(1, 2)));
+ }
+
+ void countFilledBlocksFails() {
+ ON_CALL(*this, countFilledBlocks(_, _)).WillByDefault(Return(std::make_pair(-1, -1)));
+ }
+
+ void countFilledBlocksEmpty() {
+ ON_CALL(*this, countFilledBlocks(_, _)).WillByDefault(Return(std::make_pair(0, 0)));
+ }
+
void openMountSuccess() {
ON_CALL(*this, openMount(_)).WillByDefault(Invoke(this, &MockIncFs::openMountForHealth));
}
@@ -447,6 +466,21 @@
Job mWhat;
};
+class MockFsWrapper : public FsWrapper {
+public:
+ MOCK_CONST_METHOD1(listFilesRecursive, std::vector<std::string>(std::string_view));
+ void hasNoFile() {
+ ON_CALL(*this, listFilesRecursive(_)).WillByDefault(Return(std::vector<std::string>()));
+ }
+ void hasFiles() {
+ ON_CALL(*this, listFilesRecursive(_))
+ .WillByDefault(Invoke(this, &MockFsWrapper::fakeFiles));
+ }
+ std::vector<std::string> fakeFiles(std::string_view directoryPath) {
+ return {"base.apk", "split.apk", "lib/a.so"};
+ }
+};
+
class MockStorageHealthListener : public os::incremental::BnStorageHealthListener {
public:
MOCK_METHOD2(onHealthStatus, binder::Status(int32_t storageId, int32_t status));
@@ -474,23 +508,28 @@
std::unique_ptr<MockAppOpsManager> appOpsManager,
std::unique_ptr<MockJniWrapper> jni,
std::unique_ptr<MockLooperWrapper> looper,
- std::unique_ptr<MockTimedQueueWrapper> timedQueue)
+ std::unique_ptr<MockTimedQueueWrapper> timedQueue,
+ std::unique_ptr<MockFsWrapper> fs)
: mVold(std::move(vold)),
mDataLoaderManager(std::move(dataLoaderManager)),
mIncFs(std::move(incfs)),
mAppOpsManager(std::move(appOpsManager)),
mJni(std::move(jni)),
mLooper(std::move(looper)),
- mTimedQueue(std::move(timedQueue)) {}
+ mTimedQueue(std::move(timedQueue)),
+ mFs(std::move(fs)) {}
std::unique_ptr<VoldServiceWrapper> getVoldService() final { return std::move(mVold); }
std::unique_ptr<DataLoaderManagerWrapper> getDataLoaderManager() final {
return std::move(mDataLoaderManager);
}
std::unique_ptr<IncFsWrapper> getIncFs() final { return std::move(mIncFs); }
- std::unique_ptr<AppOpsManagerWrapper> getAppOpsManager() final { return std::move(mAppOpsManager); }
+ std::unique_ptr<AppOpsManagerWrapper> getAppOpsManager() final {
+ return std::move(mAppOpsManager);
+ }
std::unique_ptr<JniWrapper> getJni() final { return std::move(mJni); }
std::unique_ptr<LooperWrapper> getLooper() final { return std::move(mLooper); }
std::unique_ptr<TimedQueueWrapper> getTimedQueue() final { return std::move(mTimedQueue); }
+ std::unique_ptr<FsWrapper> getFs() final { return std::move(mFs); }
private:
std::unique_ptr<MockVoldService> mVold;
@@ -500,6 +539,7 @@
std::unique_ptr<MockJniWrapper> mJni;
std::unique_ptr<MockLooperWrapper> mLooper;
std::unique_ptr<MockTimedQueueWrapper> mTimedQueue;
+ std::unique_ptr<MockFsWrapper> mFs;
};
// --- IncrementalServiceTest ---
@@ -523,6 +563,8 @@
mLooper = looper.get();
auto timedQueue = std::make_unique<NiceMock<MockTimedQueueWrapper>>();
mTimedQueue = timedQueue.get();
+ auto fs = std::make_unique<NiceMock<MockFsWrapper>>();
+ mFs = fs.get();
mIncrementalService =
std::make_unique<IncrementalService>(MockServiceManager(std::move(vold),
std::move(
@@ -531,12 +573,14 @@
std::move(appOps),
std::move(jni),
std::move(looper),
- std::move(timedQueue)),
+ std::move(timedQueue),
+ std::move(fs)),
mRootDir.path);
mDataLoaderParcel.packageName = "com.test";
mDataLoaderParcel.arguments = "uri";
mDataLoaderManager->unbindFromDataLoaderSuccess();
mIncrementalService->onSystemReady();
+ setupSuccess();
}
void setUpExistingMountDir(const std::string& rootDir) {
@@ -560,6 +604,14 @@
.WillByDefault(Invoke(mIncFs, &MockIncFs::getStorageMetadata));
}
+ void setupSuccess() {
+ mVold->mountIncFsSuccess();
+ mIncFs->makeFileSuccess();
+ mVold->bindMountSuccess();
+ mDataLoaderManager->bindToDataLoaderSuccess();
+ mDataLoaderManager->getDataLoaderSuccess();
+ }
+
protected:
NiceMock<MockVoldService>* mVold = nullptr;
NiceMock<MockIncFs>* mIncFs = nullptr;
@@ -568,6 +620,7 @@
NiceMock<MockJniWrapper>* mJni = nullptr;
NiceMock<MockLooperWrapper>* mLooper = nullptr;
NiceMock<MockTimedQueueWrapper>* mTimedQueue = nullptr;
+ NiceMock<MockFsWrapper>* mFs = nullptr;
NiceMock<MockDataLoader>* mDataLoader = nullptr;
std::unique_ptr<IncrementalService> mIncrementalService;
TemporaryDir mRootDir;
@@ -641,11 +694,6 @@
}
TEST_F(IncrementalServiceTest, testDeleteStorageSuccess) {
- mVold->mountIncFsSuccess();
- mIncFs->makeFileSuccess();
- mVold->bindMountSuccess();
- mDataLoaderManager->bindToDataLoaderSuccess();
- mDataLoaderManager->getDataLoaderSuccess();
EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(1);
EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
@@ -661,11 +709,6 @@
}
TEST_F(IncrementalServiceTest, testDataLoaderDestroyed) {
- mVold->mountIncFsSuccess();
- mIncFs->makeFileSuccess();
- mVold->bindMountSuccess();
- mDataLoaderManager->bindToDataLoaderSuccess();
- mDataLoaderManager->getDataLoaderSuccess();
EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(2);
EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(2);
@@ -682,12 +725,7 @@
}
TEST_F(IncrementalServiceTest, testStartDataLoaderCreate) {
- mVold->mountIncFsSuccess();
- mIncFs->makeFileSuccess();
- mVold->bindMountSuccess();
mDataLoader->initializeCreateOkNoStatus();
- mDataLoaderManager->bindToDataLoaderSuccess();
- mDataLoaderManager->getDataLoaderSuccess();
EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(1);
EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
@@ -705,12 +743,7 @@
}
TEST_F(IncrementalServiceTest, testStartDataLoaderPendingStart) {
- mVold->mountIncFsSuccess();
- mIncFs->makeFileSuccess();
- mVold->bindMountSuccess();
mDataLoader->initializeCreateOkNoStatus();
- mDataLoaderManager->bindToDataLoaderSuccess();
- mDataLoaderManager->getDataLoaderSuccess();
EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(1);
EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(2);
@@ -727,12 +760,7 @@
}
TEST_F(IncrementalServiceTest, testStartDataLoaderCreateUnavailable) {
- mVold->mountIncFsSuccess();
- mIncFs->makeFileSuccess();
- mVold->bindMountSuccess();
mDataLoader->initializeCreateOkNoStatus();
- mDataLoaderManager->bindToDataLoaderSuccess();
- mDataLoaderManager->getDataLoaderSuccess();
EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(1);
EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
@@ -748,14 +776,10 @@
}
TEST_F(IncrementalServiceTest, testStartDataLoaderRecreateOnPendingReads) {
- mVold->mountIncFsSuccess();
- mIncFs->makeFileSuccess();
- mIncFs->openMountSuccess();
mIncFs->waitForPendingReadsSuccess();
- mVold->bindMountSuccess();
+ mIncFs->openMountSuccess();
mDataLoader->initializeCreateOkNoStatus();
- mDataLoaderManager->bindToDataLoaderSuccess();
- mDataLoaderManager->getDataLoaderSuccess();
+
EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(2);
EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(2);
EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(2);
@@ -776,12 +800,8 @@
}
TEST_F(IncrementalServiceTest, testStartDataLoaderUnhealthyStorage) {
- mVold->mountIncFsSuccess();
- mIncFs->makeFileSuccess();
mIncFs->openMountSuccess();
- mVold->bindMountSuccess();
- mDataLoaderManager->bindToDataLoaderSuccess();
- mDataLoaderManager->getDataLoaderSuccess();
+
EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(1);
EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
@@ -906,13 +926,9 @@
}
TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccess) {
- mVold->mountIncFsSuccess();
- mIncFs->makeFileSuccess();
- mVold->bindMountSuccess();
mVold->setIncFsMountOptionsSuccess();
- mDataLoaderManager->bindToDataLoaderSuccess();
- mDataLoaderManager->getDataLoaderSuccess();
mAppOpsManager->checkPermissionSuccess();
+
EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
// We are calling setIncFsMountOptions(true).
@@ -930,13 +946,9 @@
}
TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndDisabled) {
- mVold->mountIncFsSuccess();
- mIncFs->makeFileSuccess();
- mVold->bindMountSuccess();
mVold->setIncFsMountOptionsSuccess();
- mDataLoaderManager->bindToDataLoaderSuccess();
- mDataLoaderManager->getDataLoaderSuccess();
mAppOpsManager->checkPermissionSuccess();
+
EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
// Enabling and then disabling readlogs.
@@ -958,14 +970,10 @@
}
TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndPermissionChanged) {
- mVold->mountIncFsSuccess();
- mIncFs->makeFileSuccess();
- mVold->bindMountSuccess();
mVold->setIncFsMountOptionsSuccess();
- mDataLoaderManager->bindToDataLoaderSuccess();
- mDataLoaderManager->getDataLoaderSuccess();
mAppOpsManager->checkPermissionSuccess();
mAppOpsManager->initializeStartWatchingMode();
+
EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
// We are calling setIncFsMountOptions(true).
@@ -987,12 +995,8 @@
}
TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsCheckPermissionFails) {
- mVold->mountIncFsSuccess();
- mIncFs->makeFileSuccess();
- mVold->bindMountSuccess();
- mDataLoaderManager->bindToDataLoaderSuccess();
- mDataLoaderManager->getDataLoaderSuccess();
mAppOpsManager->checkPermissionFails();
+
EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
// checkPermission fails, no calls to set opitions, start or stop WatchingMode.
@@ -1008,13 +1012,9 @@
}
TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsFails) {
- mVold->mountIncFsSuccess();
- mIncFs->makeFileSuccess();
- mVold->bindMountSuccess();
mVold->setIncFsMountOptionsFails();
- mDataLoaderManager->bindToDataLoaderSuccess();
- mDataLoaderManager->getDataLoaderSuccess();
mAppOpsManager->checkPermissionSuccess();
+
EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
// We are calling setIncFsMountOptions.
@@ -1031,11 +1031,6 @@
}
TEST_F(IncrementalServiceTest, testMakeDirectory) {
- mVold->mountIncFsSuccess();
- mIncFs->makeFileSuccess();
- mVold->bindMountSuccess();
- mDataLoaderManager->bindToDataLoaderSuccess();
- mDataLoaderManager->getDataLoaderSuccess();
TemporaryDir tempDir;
int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
IncrementalService::CreateOptions::CreateNew,
@@ -1055,11 +1050,6 @@
}
TEST_F(IncrementalServiceTest, testMakeDirectories) {
- mVold->mountIncFsSuccess();
- mIncFs->makeFileSuccess();
- mVold->bindMountSuccess();
- mDataLoaderManager->bindToDataLoaderSuccess();
- mDataLoaderManager->getDataLoaderSuccess();
TemporaryDir tempDir;
int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
IncrementalService::CreateOptions::CreateNew,
@@ -1078,4 +1068,51 @@
auto res = mIncrementalService->makeDirs(storageId, dir_path, 0555);
ASSERT_EQ(res, 0);
}
+
+TEST_F(IncrementalServiceTest, testGetLoadingProgressFailsWithNoFile) {
+ mIncFs->countFilledBlocksSuccess();
+ mFs->hasNoFile();
+
+ TemporaryDir tempDir;
+ int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
+ IncrementalService::CreateOptions::CreateNew,
+ {}, {}, {});
+ ASSERT_EQ(-EINVAL, mIncrementalService->getLoadingProgress(storageId));
+}
+
+TEST_F(IncrementalServiceTest, testGetLoadingProgressFailsWithFailedRanges) {
+ mIncFs->countFilledBlocksFails();
+ mFs->hasFiles();
+
+ TemporaryDir tempDir;
+ int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
+ IncrementalService::CreateOptions::CreateNew,
+ {}, {}, {});
+ EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(1);
+ ASSERT_EQ(-1, mIncrementalService->getLoadingProgress(storageId));
+}
+
+TEST_F(IncrementalServiceTest, testGetLoadingProgressFailsWithEmptyRanges) {
+ mIncFs->countFilledBlocksEmpty();
+ mFs->hasFiles();
+
+ TemporaryDir tempDir;
+ int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
+ IncrementalService::CreateOptions::CreateNew,
+ {}, {}, {});
+ EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(3);
+ ASSERT_EQ(-EINVAL, mIncrementalService->getLoadingProgress(storageId));
+}
+
+TEST_F(IncrementalServiceTest, testGetLoadingProgressSuccess) {
+ mIncFs->countFilledBlocksSuccess();
+ mFs->hasFiles();
+
+ TemporaryDir tempDir;
+ int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
+ IncrementalService::CreateOptions::CreateNew,
+ {}, {}, {});
+ EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(3);
+ ASSERT_EQ(0.5, mIncrementalService->getLoadingProgress(storageId));
+}
} // namespace android::os::incremental
diff --git a/services/robotests/src/com/android/server/pm/CrossProfileAppsServiceImplRoboTest.java b/services/robotests/src/com/android/server/pm/CrossProfileAppsServiceImplRoboTest.java
index 4b25890..5fa809f 100644
--- a/services/robotests/src/com/android/server/pm/CrossProfileAppsServiceImplRoboTest.java
+++ b/services/robotests/src/com/android/server/pm/CrossProfileAppsServiceImplRoboTest.java
@@ -204,10 +204,10 @@
CROSS_PROFILE_APP_PACKAGE_NAME, PERSONAL_PROFILE_UID, PERSONAL_PROFILE_USER_ID);
ShadowApplicationPackageManager.setPackageUidAsUser(
CROSS_PROFILE_APP_PACKAGE_NAME, WORK_PROFILE_UID, WORK_PROFILE_USER_ID);
- when(mPackageManagerInternal.getPackageUidInternal(
+ when(mPackageManagerInternal.getPackageUid(
CROSS_PROFILE_APP_PACKAGE_NAME, /* flags= */ 0, PERSONAL_PROFILE_USER_ID))
.thenReturn(PERSONAL_PROFILE_UID);
- when(mPackageManagerInternal.getPackageUidInternal(
+ when(mPackageManagerInternal.getPackageUid(
CROSS_PROFILE_APP_PACKAGE_NAME, /* flags= */ 0, WORK_PROFILE_USER_ID))
.thenReturn(WORK_PROFILE_UID);
}
diff --git a/services/tests/servicestests/src/com/android/server/uri/UriGrantsMockContext.java b/services/tests/servicestests/src/com/android/server/uri/UriGrantsMockContext.java
index d5aee5d..2c719ff 100644
--- a/services/tests/servicestests/src/com/android/server/uri/UriGrantsMockContext.java
+++ b/services/tests/servicestests/src/com/android/server/uri/UriGrantsMockContext.java
@@ -120,17 +120,17 @@
LocalServices.addService(PackageManagerInternal.class, mPmInternal);
for (int userId : new int[] { USER_PRIMARY, USER_SECONDARY }) {
- when(mPmInternal.getPackageUidInternal(eq(PKG_SOCIAL), anyInt(), eq(userId)))
+ when(mPmInternal.getPackageUid(eq(PKG_SOCIAL), anyInt(), eq(userId)))
.thenReturn(UserHandle.getUid(userId, UID_SOCIAL));
- when(mPmInternal.getPackageUidInternal(eq(PKG_CAMERA), anyInt(), eq(userId)))
+ when(mPmInternal.getPackageUid(eq(PKG_CAMERA), anyInt(), eq(userId)))
.thenReturn(UserHandle.getUid(userId, UID_CAMERA));
- when(mPmInternal.getPackageUidInternal(eq(PKG_PRIVATE), anyInt(), eq(userId)))
+ when(mPmInternal.getPackageUid(eq(PKG_PRIVATE), anyInt(), eq(userId)))
.thenReturn(UserHandle.getUid(userId, UID_PRIVATE));
- when(mPmInternal.getPackageUidInternal(eq(PKG_PUBLIC), anyInt(), eq(userId)))
+ when(mPmInternal.getPackageUid(eq(PKG_PUBLIC), anyInt(), eq(userId)))
.thenReturn(UserHandle.getUid(userId, UID_PUBLIC));
- when(mPmInternal.getPackageUidInternal(eq(PKG_FORCE), anyInt(), eq(userId)))
+ when(mPmInternal.getPackageUid(eq(PKG_FORCE), anyInt(), eq(userId)))
.thenReturn(UserHandle.getUid(userId, UID_FORCE));
- when(mPmInternal.getPackageUidInternal(eq(PKG_COMPLEX), anyInt(), eq(userId)))
+ when(mPmInternal.getPackageUid(eq(PKG_COMPLEX), anyInt(), eq(userId)))
.thenReturn(UserHandle.getUid(userId, UID_COMPLEX));
when(mPmInternal.resolveContentProvider(eq(PKG_CAMERA), anyInt(), eq(userId)))
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index 708d802..59f0a79 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -1190,7 +1190,7 @@
assertEquals(DESTROYING, mActivity.getState());
assertTrue(mActivity.finishing);
- verify(mActivity).destroyImmediately(eq(true) /* removeFromApp */, anyString());
+ verify(mActivity).destroyImmediately(anyString());
}
/**
@@ -1214,7 +1214,7 @@
// Verify that the activity was not actually destroyed, but waits for next one to come up
// instead.
- verify(mActivity, never()).destroyImmediately(eq(true) /* removeFromApp */, anyString());
+ verify(mActivity, never()).destroyImmediately(anyString());
assertEquals(FINISHING, mActivity.getState());
assertTrue(mActivity.mStackSupervisor.mFinishingActivities.contains(mActivity));
}
@@ -1238,7 +1238,7 @@
mActivity.completeFinishing("test");
// Verify that the activity is not destroyed immediately, but waits for next one to come up.
- verify(mActivity, never()).destroyImmediately(eq(true) /* removeFromApp */, anyString());
+ verify(mActivity, never()).destroyImmediately(anyString());
assertEquals(FINISHING, mActivity.getState());
assertTrue(mActivity.mStackSupervisor.mFinishingActivities.contains(mActivity));
}
@@ -1250,26 +1250,26 @@
@Test
public void testDestroyImmediately_hadApp_finishing() {
mActivity.finishing = true;
- mActivity.destroyImmediately(false /* removeFromApp */, "test");
+ mActivity.destroyImmediately("test");
assertEquals(DESTROYING, mActivity.getState());
}
/**
* Test that the activity will be moved to destroyed state immediately if it was not marked as
- * finishing before {@link ActivityRecord#destroyImmediately(boolean, String)}.
+ * finishing before {@link ActivityRecord#destroyImmediately(String)}.
*/
@Test
public void testDestroyImmediately_hadApp_notFinishing() {
mActivity.finishing = false;
- mActivity.destroyImmediately(false /* removeFromApp */, "test");
+ mActivity.destroyImmediately("test");
assertEquals(DESTROYED, mActivity.getState());
}
/**
* Test that an activity with no process attached and that is marked as finishing will be
- * removed from task when {@link ActivityRecord#destroyImmediately(boolean, String)} is called.
+ * removed from task when {@link ActivityRecord#destroyImmediately(String)} is called.
*/
@Test
public void testDestroyImmediately_noApp_finishing() {
@@ -1277,7 +1277,7 @@
mActivity.finishing = true;
final Task task = mActivity.getTask();
- mActivity.destroyImmediately(false /* removeFromApp */, "test");
+ mActivity.destroyImmediately("test");
assertEquals(DESTROYED, mActivity.getState());
assertNull(mActivity.getTask());
@@ -1294,7 +1294,7 @@
mActivity.finishing = false;
final Task task = mActivity.getTask();
- mActivity.destroyImmediately(false /* removeFromApp */, "test");
+ mActivity.destroyImmediately("test");
assertEquals(DESTROYED, mActivity.getState());
assertEquals(task, mActivity.getTask());
@@ -1310,7 +1310,7 @@
mActivity.safelyDestroy("test");
- verify(mActivity, never()).destroyImmediately(eq(true) /* removeFromApp */, anyString());
+ verify(mActivity, never()).destroyImmediately(anyString());
}
/**
@@ -1322,7 +1322,7 @@
mActivity.safelyDestroy("test");
- verify(mActivity).destroyImmediately(eq(true) /* removeFromApp */, anyString());
+ verify(mActivity).destroyImmediately(anyString());
}
@Test
@@ -1655,13 +1655,13 @@
assertEquals(0, thirdActivity.getMergedOverrideConfiguration()
.diff(wpc.getRequestedOverrideConfiguration()));
- secondActivity.destroyImmediately(true, "");
+ secondActivity.destroyImmediately("");
assertTrue(wpc.registeredForActivityConfigChanges());
assertEquals(0, thirdActivity.getMergedOverrideConfiguration()
.diff(wpc.getRequestedOverrideConfiguration()));
- firstActivity.destroyImmediately(true, "");
+ firstActivity.destroyImmediately("");
assertTrue(wpc.registeredForActivityConfigChanges());
assertEquals(0, thirdActivity.getMergedOverrideConfiguration()
@@ -1714,6 +1714,27 @@
}
+ @Test
+ public void testProcessInfoUpdateWhenSetState() {
+ spyOn(mActivity.app);
+ verifyProcessInfoUpdate(RESUMED, true /* shouldUpdate */, true /* activityChange */);
+ verifyProcessInfoUpdate(PAUSED, false /* shouldUpdate */, false /* activityChange */);
+ verifyProcessInfoUpdate(STOPPED, false /* shouldUpdate */, false /* activityChange */);
+ verifyProcessInfoUpdate(STARTED, true /* shouldUpdate */, true /* activityChange */);
+
+ mActivity.app.removeActivity(mActivity, true /* keepAssociation */);
+ verifyProcessInfoUpdate(DESTROYING, true /* shouldUpdate */, false /* activityChange */);
+ verifyProcessInfoUpdate(DESTROYED, true /* shouldUpdate */, false /* activityChange */);
+ }
+
+ private void verifyProcessInfoUpdate(ActivityState state, boolean shouldUpdate,
+ boolean activityChange) {
+ reset(mActivity.app);
+ mActivity.setState(state, "test");
+ verify(mActivity.app, times(shouldUpdate ? 1 : 0)).updateProcessInfo(anyBoolean(),
+ eq(activityChange), anyBoolean(), anyBoolean());
+ }
+
/**
* Creates an activity on display. For non-default display request it will also create a new
* display with custom DisplayInfo.
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
index 72899e7..191c33c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
@@ -184,7 +184,7 @@
};
activities[0].detachFromProcess();
activities[1].finishing = true;
- activities[1].destroyImmediately(true /* removeFromApp */, "test");
+ activities[1].destroyImmediately("test");
spyOn(wpc);
doReturn(true).when(wpc).isRemoved();
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 1e5d92b..81aad97 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -1653,8 +1653,8 @@
// If the calling app is asking about itself, continue, else check for permission.
if (packageName.equals(callingPackage)) {
- final int actualCallingUid = mPackageManagerInternal.getPackageUidInternal(
- callingPackage, 0, userId);
+ final int actualCallingUid = mPackageManagerInternal.getPackageUid(
+ callingPackage, /* flags= */ 0, userId);
if (actualCallingUid != callingUid) {
return false;
}
diff --git a/tests/StagedInstallTest/Android.bp b/tests/StagedInstallTest/Android.bp
index 1393e8c..f55d4d4 100644
--- a/tests/StagedInstallTest/Android.bp
+++ b/tests/StagedInstallTest/Android.bp
@@ -35,6 +35,7 @@
"cts-install-lib-host",
],
data: [
+ ":com.android.apex.apkrollback.test_v1",
":com.android.apex.cts.shim.v2_prebuilt",
":TestAppAv1",
],
diff --git a/tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java b/tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java
index 7817239..e5411de 100644
--- a/tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java
+++ b/tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java
@@ -47,11 +47,7 @@
@RunWith(JUnit4.class)
public class StagedInstallInternalTest {
-
- private static final String TAG = StagedInstallInternalTest.class.getSimpleName();
private static final String APK_IN_APEX_TESTAPEX_NAME = "com.android.apex.apkrollback.test";
- private static final TestApp TEST_APEX_WITH_APK_V1 = new TestApp("TestApexWithApkV1",
- APK_IN_APEX_TESTAPEX_NAME, 1, /*isApex*/true, APK_IN_APEX_TESTAPEX_NAME + "_v1.apex");
private static final TestApp TEST_APEX_WITH_APK_V2 = new TestApp("TestApexWithApkV2",
APK_IN_APEX_TESTAPEX_NAME, 2, /*isApex*/true, APK_IN_APEX_TESTAPEX_NAME + "_v2.apex");
diff --git a/wifi/api/current.txt b/wifi/api/current.txt
index 53c3b33..ee7320f 100644
--- a/wifi/api/current.txt
+++ b/wifi/api/current.txt
@@ -487,6 +487,7 @@
method @Nullable public String getPassphrase();
method @Nullable public android.net.wifi.hotspot2.PasspointConfiguration getPasspointConfig();
method @IntRange(from=0) public int getPriority();
+ method public int getPriorityGroup();
method @Nullable public String getSsid();
method public boolean isAppInteractionRequired();
method public boolean isCredentialSharedWithUser();
@@ -513,6 +514,7 @@
method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setIsUserInteractionRequired(boolean);
method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setPasspointConfig(@NonNull android.net.wifi.hotspot2.PasspointConfiguration);
method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setPriority(@IntRange(from=0) int);
+ method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setPriorityGroup(int);
method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setSsid(@NonNull String);
method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setUntrusted(boolean);
method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setWapiEnterpriseConfig(@NonNull android.net.wifi.WifiEnterpriseConfig);
diff --git a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
index 68eb1bb..a3c4ae7 100644
--- a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
+++ b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
@@ -102,10 +102,15 @@
*/
private int mMeteredOverride;
/**
- * Priority of this network among other network suggestions provided by the app.
+ * Priority of this network among other network suggestions from same priority group
+ * provided by the app.
* The lower the number, the higher the priority (i.e value of 0 = highest priority).
*/
private int mPriority;
+ /**
+ * Priority group ID, while suggestion priority will only effect inside the priority group.
+ */
+ private int mPriorityGroup;
/**
* The carrier ID identifies the operator who provides this network configuration.
@@ -165,6 +170,7 @@
mWapiPskPassphrase = null;
mWapiEnterpriseConfig = null;
mIsNetworkUntrusted = false;
+ mPriorityGroup = 0;
}
/**
@@ -329,6 +335,18 @@
}
/**
+ * Set the priority group ID, {@link #setPriority(int)} will only impact the network
+ * suggestions from the same priority group within the same app.
+ *
+ * @param priorityGroup priority group id, if not set default is 0.
+ * @return Instance of {@link Builder} to enable chaining of the builder method.
+ */
+ public @NonNull Builder setPriorityGroup(int priorityGroup) {
+ mPriorityGroup = priorityGroup;
+ return this;
+ }
+
+ /**
* Set the ASCII WAPI passphrase for this network. Needed for authenticating to
* WAPI-PSK networks.
*
@@ -411,8 +429,9 @@
/**
* Specify the priority of this network among other network suggestions provided by the same
- * app (priorities have no impact on suggestions by different apps). The higher the number,
- * the higher the priority (i.e value of 0 = lowest priority).
+ * app (priorities have no impact on suggestions by different apps) and within the same
+ * priority group, see {@link #setPriorityGroup(int)}.
+ * The higher the number, the higher the priority (i.e value of 0 = lowest priority).
* <p>
* <li>If not set, defaults a lower priority than any assigned priority.</li>
*
@@ -696,7 +715,8 @@
mIsAppInteractionRequired,
mIsUserInteractionRequired,
mIsSharedWithUser,
- mIsInitialAutojoinEnabled);
+ mIsInitialAutojoinEnabled,
+ mPriorityGroup);
}
}
@@ -739,6 +759,12 @@
*/
public final boolean isInitialAutoJoinEnabled;
+ /**
+ * Priority group ID.
+ * @hide
+ */
+ public final int priorityGroup;
+
/** @hide */
public WifiNetworkSuggestion() {
this.wifiConfiguration = new WifiConfiguration();
@@ -747,6 +773,7 @@
this.isUserInteractionRequired = false;
this.isUserAllowedToManuallyConnect = true;
this.isInitialAutoJoinEnabled = true;
+ this.priorityGroup = 0;
}
/** @hide */
@@ -755,7 +782,7 @@
boolean isAppInteractionRequired,
boolean isUserInteractionRequired,
boolean isUserAllowedToManuallyConnect,
- boolean isInitialAutoJoinEnabled) {
+ boolean isInitialAutoJoinEnabled, int priorityGroup) {
checkNotNull(networkConfiguration);
this.wifiConfiguration = networkConfiguration;
this.passpointConfiguration = passpointConfiguration;
@@ -764,6 +791,7 @@
this.isUserInteractionRequired = isUserInteractionRequired;
this.isUserAllowedToManuallyConnect = isUserAllowedToManuallyConnect;
this.isInitialAutoJoinEnabled = isInitialAutoJoinEnabled;
+ this.priorityGroup = priorityGroup;
}
public static final @NonNull Creator<WifiNetworkSuggestion> CREATOR =
@@ -776,7 +804,8 @@
in.readBoolean(), // isAppInteractionRequired
in.readBoolean(), // isUserInteractionRequired
in.readBoolean(), // isSharedCredentialWithUser
- in.readBoolean() // isAutojoinEnabled
+ in.readBoolean(), // isAutojoinEnabled
+ in.readInt() // priorityGroup
);
}
@@ -799,6 +828,7 @@
dest.writeBoolean(isUserInteractionRequired);
dest.writeBoolean(isUserAllowedToManuallyConnect);
dest.writeBoolean(isInitialAutoJoinEnabled);
+ dest.writeInt(priorityGroup);
}
@Override
@@ -842,6 +872,7 @@
.append(", isCredentialSharedWithUser=").append(isUserAllowedToManuallyConnect)
.append(", isInitialAutoJoinEnabled=").append(isInitialAutoJoinEnabled)
.append(", isUnTrusted=").append(!wifiConfiguration.trusted)
+ .append(", priorityGroup=").append(priorityGroup)
.append(" ]");
return sb.toString();
}
@@ -962,4 +993,11 @@
}
return WifiInfo.removeDoubleQuotes(wifiConfiguration.preSharedKey);
}
+
+ /**
+ * @see Builder#setPriorityGroup(int)
+ */
+ public int getPriorityGroup() {
+ return priorityGroup;
+ }
}
diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java
index f0839e9..3744a51 100644
--- a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java
@@ -16,7 +16,12 @@
package android.net.wifi;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
import android.net.MacAddress;
import android.net.wifi.hotspot2.PasspointConfiguration;
@@ -39,6 +44,8 @@
private static final String TEST_FQDN = "fqdn";
private static final String TEST_WAPI_CERT_SUITE = "suite";
private static final String TEST_DOMAIN_SUFFIX_MATCH = "domainSuffixMatch";
+ private static final int DEFAULT_PRIORITY_GROUP = 0;
+ private static final int TEST_PRIORITY_GROUP = 1;
/**
* Validate correctness of WifiNetworkSuggestion object created by
@@ -612,7 +619,7 @@
configuration.BSSID = TEST_BSSID;
configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion(
- configuration, null, false, true, true, true);
+ configuration, null, false, true, true, true, TEST_PRIORITY_GROUP);
Parcel parcelW = Parcel.obtain();
suggestion.writeToParcel(parcelW, 0);
@@ -683,14 +690,16 @@
configuration.BSSID = TEST_BSSID;
configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
WifiNetworkSuggestion suggestion =
- new WifiNetworkSuggestion(configuration, null, true, false, true, true);
+ new WifiNetworkSuggestion(configuration, null, true, false, true, true,
+ TEST_PRIORITY_GROUP);
WifiConfiguration configuration1 = new WifiConfiguration();
configuration1.SSID = TEST_SSID;
configuration1.BSSID = TEST_BSSID;
configuration1.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
WifiNetworkSuggestion suggestion1 =
- new WifiNetworkSuggestion(configuration1, null, false, true, true, true);
+ new WifiNetworkSuggestion(configuration1, null, false, true, true, true,
+ DEFAULT_PRIORITY_GROUP);
assertEquals(suggestion, suggestion1);
assertEquals(suggestion.hashCode(), suggestion1.hashCode());
@@ -706,13 +715,15 @@
configuration.SSID = TEST_SSID;
configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
WifiNetworkSuggestion suggestion =
- new WifiNetworkSuggestion(configuration, null, false, false, true, true);
+ new WifiNetworkSuggestion(configuration, null, false, false, true, true,
+ DEFAULT_PRIORITY_GROUP);
WifiConfiguration configuration1 = new WifiConfiguration();
configuration1.SSID = TEST_SSID_1;
configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
WifiNetworkSuggestion suggestion1 =
- new WifiNetworkSuggestion(configuration1, null, false, false, true, true);
+ new WifiNetworkSuggestion(configuration1, null, false, false, true, true,
+ DEFAULT_PRIORITY_GROUP);
assertNotEquals(suggestion, suggestion1);
}
@@ -728,13 +739,15 @@
configuration.BSSID = TEST_BSSID;
configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
WifiNetworkSuggestion suggestion =
- new WifiNetworkSuggestion(configuration, null, false, false, true, true);
+ new WifiNetworkSuggestion(configuration, null, false, false, true, true,
+ DEFAULT_PRIORITY_GROUP);
WifiConfiguration configuration1 = new WifiConfiguration();
configuration1.SSID = TEST_SSID;
configuration1.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
WifiNetworkSuggestion suggestion1 =
- new WifiNetworkSuggestion(configuration1, null, false, false, true, true);
+ new WifiNetworkSuggestion(configuration1, null, false, false, true, true,
+ DEFAULT_PRIORITY_GROUP);
assertNotEquals(suggestion, suggestion1);
}
@@ -749,13 +762,15 @@
configuration.SSID = TEST_SSID;
configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
WifiNetworkSuggestion suggestion =
- new WifiNetworkSuggestion(configuration, null, false, false, true, true);
+ new WifiNetworkSuggestion(configuration, null, false, false, true, true,
+ DEFAULT_PRIORITY_GROUP);
WifiConfiguration configuration1 = new WifiConfiguration();
configuration1.SSID = TEST_SSID;
configuration1.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
WifiNetworkSuggestion suggestion1 =
- new WifiNetworkSuggestion(configuration1, null, false, false, true, true);
+ new WifiNetworkSuggestion(configuration1, null, false, false, true, true,
+ DEFAULT_PRIORITY_GROUP);
assertNotEquals(suggestion, suggestion1);
}