Merge "cameraservice: Migrate all internal String8/String16s to std::string" into udc-qpr-dev-plus-aosp
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
new file mode 100644
index 0000000..16907b3
--- /dev/null
+++ b/AconfigFlags.bp
@@ -0,0 +1,43 @@
+// Copyright (C) 2023 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.
+
+// Aconfig declarations and libraries for the core framework
+java_defaults {
+ name: "framework-minus-apex-aconfig-libraries",
+
+ // Add java_aconfig_libraries to here to add them to the core framework
+ srcs: [
+ ":com.android.hardware.camera2-aconfig-java{.generated_srcjars}",
+ ],
+}
+
+// Default flags for java_aconfig_libraries that go into framework-minus-apex
+// These libraries will not work standalone
+java_defaults {
+ name: "framework-minus-apex-aconfig-java-defaults",
+ sdk_version: "core_platform",
+ libs: ["fake_device_config"],
+}
+
+aconfig_declarations {
+ name: "com.android.hardware.camera2-aconfig",
+ package: "com.android.hardware.camera2",
+ srcs: ["core/java/android/hardware/camera2/camera_platform.aconfig"],
+}
+
+java_aconfig_library {
+ name: "com.android.hardware.camera2-aconfig-java",
+ aconfig_declarations: "com.android.hardware.camera2-aconfig",
+ defaults: ["framework-minus-apex-aconfig-java-defaults"],
+}
diff --git a/Android.bp b/Android.bp
index 773528c..ccff26f 100644
--- a/Android.bp
+++ b/Android.bp
@@ -269,6 +269,7 @@
defaults: [
"framework-aidl-export-defaults",
"latest_android_hardware_soundtrigger3_java_static",
+ "framework-minus-apex-aconfig-libraries",
],
srcs: [
":framework-non-updatable-sources",
@@ -689,6 +690,7 @@
}
build = [
+ "AconfigFlags.bp",
"ProtoLibraries.bp",
"TestProtoLibraries.bp",
]
diff --git a/OWNERS b/OWNERS
index 8ee488d..6c25324 100644
--- a/OWNERS
+++ b/OWNERS
@@ -16,8 +16,6 @@
ogunwale@google.com #{LAST_RESORT_SUGGESTION}
roosa@google.com #{LAST_RESORT_SUGGESTION}
smoreland@google.com #{LAST_RESORT_SUGGESTION}
-svetoslavganov@android.com #{LAST_RESORT_SUGGESTION}
-svetoslavganov@google.com #{LAST_RESORT_SUGGESTION}
yamasani@google.com #{LAST_RESORT_SUGGESTION}
# API changes are already covered by API-Review+1 (http://mdb/android-api-council)
@@ -30,7 +28,7 @@
# Support bulk translation updates
per-file */res*/values*/*.xml = byi@google.com, delphij@google.com
-per-file **.bp,**.mk = hansson@google.com
+per-file **.bp,**.mk = hansson@google.com, joeo@google.com
per-file TestProtoLibraries.bp = file:platform/platform_testing:/libraries/health/OWNERS
per-file TestProtoLibraries.bp = file:platform/tools/tradefederation:/OWNERS
diff --git a/apex/jobscheduler/framework/java/android/app/job/JobInfo.java b/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
index 526e63c..8c47767 100644
--- a/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
+++ b/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
@@ -371,7 +371,7 @@
/**
* Allows this job to run despite doze restrictions as long as the app is in the foreground
- * or on the temporary whitelist
+ * or on the temporary allowlist
* @hide
*/
public static final int FLAG_IMPORTANT_WHILE_FOREGROUND = 1 << 1;
@@ -2042,13 +2042,13 @@
/**
* Setting this to true indicates that this job is important while the scheduling app
- * is in the foreground or on the temporary whitelist for background restrictions.
+ * is in the foreground or on the temporary allowlist for background restrictions.
* This means that the system will relax doze restrictions on this job during this time.
*
* Apps should use this flag only for short jobs that are essential for the app to function
* properly in the foreground.
*
- * Note that once the scheduling app is no longer whitelisted from background restrictions
+ * Note that once the scheduling app is no longer allowlisted from background restrictions
* and in the background, or the job failed due to unsatisfied constraints,
* this job should be expected to behave like other jobs without this flag.
*
diff --git a/apex/jobscheduler/framework/java/android/os/PowerWhitelistManager.java b/apex/jobscheduler/framework/java/android/os/PowerWhitelistManager.java
index 4ce31e9..20da171 100644
--- a/apex/jobscheduler/framework/java/android/os/PowerWhitelistManager.java
+++ b/apex/jobscheduler/framework/java/android/os/PowerWhitelistManager.java
@@ -29,10 +29,10 @@
import java.util.List;
/**
- * Interface to access and modify the permanent and temporary power save whitelist. The two lists
- * are kept separately. Apps placed on the permanent whitelist are only removed via an explicit
- * removeFromWhitelist call. Apps whitelisted by default by the system cannot be removed. Apps
- * placed on the temporary whitelist are removed from that whitelist after a predetermined amount of
+ * Interface to access and modify the permanent and temporary power save allowlist. The two lists
+ * are kept separately. Apps placed on the permanent allowlist are only removed via an explicit
+ * removeFromAllowlist call. Apps whitelisted by default by the system cannot be removed. Apps
+ * placed on the temporary allowlist are removed from that allowlist after a predetermined amount of
* time.
*
* @deprecated Use {@link PowerExemptionManager} instead
@@ -50,18 +50,18 @@
private final PowerExemptionManager mPowerExemptionManager;
/**
- * Indicates that an unforeseen event has occurred and the app should be whitelisted to handle
+ * Indicates that an unforeseen event has occurred and the app should be allowlisted to handle
* it.
*/
public static final int EVENT_UNSPECIFIED = PowerExemptionManager.EVENT_UNSPECIFIED;
/**
- * Indicates that an SMS event has occurred and the app should be whitelisted to handle it.
+ * Indicates that an SMS event has occurred and the app should be allowlisted to handle it.
*/
public static final int EVENT_SMS = PowerExemptionManager.EVENT_SMS;
/**
- * Indicates that an MMS event has occurred and the app should be whitelisted to handle it.
+ * Indicates that an MMS event has occurred and the app should be allowlisted to handle it.
*/
public static final int EVENT_MMS = PowerExemptionManager.EVENT_MMS;
@@ -381,7 +381,7 @@
}
/**
- * Add the specified package to the permanent power save whitelist.
+ * Add the specified package to the permanent power save allowlist.
*
* @deprecated Use {@link PowerExemptionManager#addToPermanentAllowList(String)} instead
*/
@@ -392,7 +392,7 @@
}
/**
- * Add the specified packages to the permanent power save whitelist.
+ * Add the specified packages to the permanent power save allowlist.
*
* @deprecated Use {@link PowerExemptionManager#addToPermanentAllowList(List)} instead
*/
@@ -403,10 +403,10 @@
}
/**
- * Get a list of app IDs of app that are whitelisted. This does not include temporarily
- * whitelisted apps.
+ * Get a list of app IDs of app that are allowlisted. This does not include temporarily
+ * allowlisted apps.
*
- * @param includingIdle Set to true if the app should be whitelisted from device idle as well
+ * @param includingIdle Set to true if the app should be allowlisted from device idle as well
* as other power save restrictions
* @deprecated Use {@link PowerExemptionManager#getAllowListedAppIds(boolean)} instead
* @hide
@@ -418,10 +418,10 @@
}
/**
- * Returns true if the app is whitelisted from power save restrictions. This does not include
- * temporarily whitelisted apps.
+ * Returns true if the app is allowlisted from power save restrictions. This does not include
+ * temporarily allowlisted apps.
*
- * @param includingIdle Set to true if the app should be whitelisted from device
+ * @param includingIdle Set to true if the app should be allowlisted from device
* idle as well as other power save restrictions
* @deprecated Use {@link PowerExemptionManager#isAllowListed(String, boolean)} instead
* @hide
@@ -432,11 +432,11 @@
}
/**
- * Remove an app from the permanent power save whitelist. Only apps that were added via
+ * Remove an app from the permanent power save allowlist. Only apps that were added via
* {@link #addToWhitelist(String)} or {@link #addToWhitelist(List)} will be removed. Apps
- * whitelisted by default by the system cannot be removed.
+ * allowlisted by default by the system cannot be removed.
*
- * @param packageName The app to remove from the whitelist
+ * @param packageName The app to remove from the allowlist
* @deprecated Use {@link PowerExemptionManager#removeFromPermanentAllowList(String)} instead
*/
@Deprecated
@@ -446,10 +446,10 @@
}
/**
- * Add an app to the temporary whitelist for a short amount of time.
+ * Add an app to the temporary allowlist for a short amount of time.
*
- * @param packageName The package to add to the temp whitelist
- * @param durationMs How long to keep the app on the temp whitelist for (in milliseconds)
+ * @param packageName The package to add to the temp allowlist
+ * @param durationMs How long to keep the app on the temp allowlist for (in milliseconds)
* @param reasonCode one of {@link ReasonCode}, use {@link #REASON_UNKNOWN} if not sure.
* @param reason a optional human readable reason string, could be null or empty string.
* @deprecated Use {@link PowerExemptionManager#addToTemporaryAllowList(
@@ -463,10 +463,10 @@
}
/**
- * Add an app to the temporary whitelist for a short amount of time.
+ * Add an app to the temporary allowlist for a short amount of time.
*
- * @param packageName The package to add to the temp whitelist
- * @param durationMs How long to keep the app on the temp whitelist for (in milliseconds)
+ * @param packageName The package to add to the temp allowlist
+ * @param durationMs How long to keep the app on the temp allowlist for (in milliseconds)
* @deprecated Use {@link PowerExemptionManager#addToTemporaryAllowList(
* String, int, String, long)} instead
*/
@@ -478,15 +478,15 @@
}
/**
- * Add an app to the temporary whitelist for a short amount of time for a specific reason. The
- * temporary whitelist is kept separately from the permanent whitelist and apps are
- * automatically removed from the temporary whitelist after a predetermined amount of time.
+ * Add an app to the temporary allowlist for a short amount of time for a specific reason. The
+ * temporary allowlist is kept separately from the permanent allowlist and apps are
+ * automatically removed from the temporary allowlist after a predetermined amount of time.
*
- * @param packageName The package to add to the temp whitelist
- * @param event The reason to add the app to the temp whitelist
- * @param reason A human-readable reason explaining why the app is temp whitelisted. Only
+ * @param packageName The package to add to the temp allowlist
+ * @param event The reason to add the app to the temp allowlist
+ * @param reason A human-readable reason explaining why the app is temp allowlisted. Only
* used for logging purposes. Could be null or empty string.
- * @return The duration (in milliseconds) that the app is whitelisted for
+ * @return The duration (in milliseconds) that the app is allowlisted for
* @deprecated Use {@link PowerExemptionManager#addToTemporaryAllowListForEvent(
* String, int, String, int)} instead
*/
@@ -499,16 +499,16 @@
}
/**
- * Add an app to the temporary whitelist for a short amount of time for a specific reason. The
- * temporary whitelist is kept separately from the permanent whitelist and apps are
- * automatically removed from the temporary whitelist after a predetermined amount of time.
+ * Add an app to the temporary allowlist for a short amount of time for a specific reason. The
+ * temporary allowlist is kept separately from the permanent allowlist and apps are
+ * automatically removed from the temporary allowlist after a predetermined amount of time.
*
- * @param packageName The package to add to the temp whitelist
- * @param event The reason to add the app to the temp whitelist
+ * @param packageName The package to add to the temp allowlist
+ * @param event The reason to add the app to the temp allowlist
* @param reasonCode one of {@link ReasonCode}, use {@link #REASON_UNKNOWN} if not sure.
- * @param reason A human-readable reason explaining why the app is temp whitelisted. Only
+ * @param reason A human-readable reason explaining why the app is temp allowlisted. Only
* used for logging purposes. Could be null or empty string.
- * @return The duration (in milliseconds) that the app is whitelisted for
+ * @return The duration (in milliseconds) that the app is allowlisted for
* @deprecated Use {@link PowerExemptionManager#addToTemporaryAllowListForEvent(
* String, int, String, int)} instead
*/
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index a8b6c0b..782351c 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -1523,6 +1523,7 @@
for (size_t i=0 ; i<pcount ; i++) {
const Animation::Part& part(animation.parts[i]);
const size_t fcount = part.frames.size();
+ glBindTexture(GL_TEXTURE_2D, 0);
// Handle animation package
if (part.animation != nullptr) {
@@ -1599,8 +1600,10 @@
if (r > 0) {
glBindTexture(GL_TEXTURE_2D, frame.tid);
} else {
- glGenTextures(1, &frame.tid);
- glBindTexture(GL_TEXTURE_2D, frame.tid);
+ if (part.count != 1) {
+ glGenTextures(1, &frame.tid);
+ glBindTexture(GL_TEXTURE_2D, frame.tid);
+ }
int w, h;
// Set decoding option to alpha unpremultiplied so that the R, G, B channels
// of transparent pixels are preserved.
diff --git a/cmds/idmap2/libidmap2/XmlParser.cpp b/cmds/idmap2/libidmap2/XmlParser.cpp
index 70822c8..f71e6b9 100644
--- a/cmds/idmap2/libidmap2/XmlParser.cpp
+++ b/cmds/idmap2/libidmap2/XmlParser.cpp
@@ -111,7 +111,7 @@
switch (value.dataType) {
case Res_value::TYPE_STRING: {
if (auto str = parser.getStrings().string8ObjectAt(value.data); str.ok()) {
- return std::string(str->string());
+ return std::string(str->c_str());
}
break;
}
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 9a5247a..ced3554 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -2892,11 +2892,6 @@
}
}
- final Person person = extras.getParcelable(EXTRA_MESSAGING_PERSON, Person.class);
- if (person != null) {
- person.visitUris(visitor);
- }
-
final RemoteInputHistoryItem[] history = extras.getParcelableArray(
Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS,
RemoteInputHistoryItem.class);
@@ -2908,9 +2903,14 @@
}
}
}
- }
- if (isStyle(MessagingStyle.class) && extras != null) {
+ // Extras for MessagingStyle. We visit them even if not isStyle(MessagingStyle), since
+ // Notification Listeners might use directly (without the isStyle check).
+ final Person person = extras.getParcelable(EXTRA_MESSAGING_PERSON, Person.class);
+ if (person != null) {
+ person.visitUris(visitor);
+ }
+
final Parcelable[] messages = extras.getParcelableArray(EXTRA_MESSAGES,
Parcelable.class);
if (!ArrayUtils.isEmpty(messages)) {
@@ -2930,9 +2930,8 @@
}
visitIconUri(visitor, extras.getParcelable(EXTRA_CONVERSATION_ICON, Icon.class));
- }
- if (isStyle(CallStyle.class) & extras != null) {
+ // Extras for CallStyle (same reason for visiting without checking isStyle).
Person callPerson = extras.getParcelable(EXTRA_CALL_PERSON, Person.class);
if (callPerson != null) {
callPerson.visitUris(visitor);
diff --git a/core/java/android/app/search/SearchSession.java b/core/java/android/app/search/SearchSession.java
index 0dbd81e..99b64a0 100644
--- a/core/java/android/app/search/SearchSession.java
+++ b/core/java/android/app/search/SearchSession.java
@@ -104,7 +104,7 @@
mInterface = android.app.search.ISearchUiManager.Stub.asInterface(b);
mSessionId = new SearchSessionId(
context.getPackageName() + ":" + UUID.randomUUID().toString(), context.getUserId());
- // b/175527717 whitelist possible clients of this API
+ // b/175527717 allowlist possible clients of this API
searchContext.setPackageName(context.getPackageName());
try {
mInterface.createSearchSession(searchContext, mSessionId, mToken);
diff --git a/core/java/android/credentials/CredentialManager.java b/core/java/android/credentials/CredentialManager.java
index c2a0062..eedb25b 100644
--- a/core/java/android/credentials/CredentialManager.java
+++ b/core/java/android/credentials/CredentialManager.java
@@ -123,7 +123,7 @@
* credential, display a picker when multiple credentials exist, etc.
* Callers (e.g. browsers) may optionally set origin in {@link GetCredentialRequest} for an
* app different from their own, to be able to get credentials on behalf of that app. They would
- * need additional permission {@link CREDENTIAL_MANAGER_SET_ORIGIN}
+ * need additional permission {@code CREDENTIAL_MANAGER_SET_ORIGIN}
* to use this functionality
*
* @param context the context used to launch any UI needed; use an activity context to make sure
@@ -209,9 +209,9 @@
*
* <p>This API doesn't invoke any UI. It only performs the preparation work so that you can
* later launch the remaining get-credential operation (involves UIs) through the {@link
- * #getCredential(PrepareGetCredentialResponse.PendingGetCredentialHandle, Context,
+ * #getCredential(Context, PrepareGetCredentialResponse.PendingGetCredentialHandle,
* CancellationSignal, Executor, OutcomeReceiver)} API which incurs less latency compared to
- * the {@link #getCredential(GetCredentialRequest, Context, CancellationSignal, Executor,
+ * the {@link #getCredential(Context, GetCredentialRequest, CancellationSignal, Executor,
* OutcomeReceiver)} API that executes the whole operation in one call.
*
* @param request the request specifying type(s) of credentials to get from the user
@@ -261,7 +261,7 @@
* storing the new credential, etc.
* Callers (e.g. browsers) may optionally set origin in {@link CreateCredentialRequest} for an
* app different from their own, to be able to get credentials on behalf of that app. They would
- * need additional permission {@link CREDENTIAL_MANAGER_SET_ORIGIN}
+ * need additional permission {@code CREDENTIAL_MANAGER_SET_ORIGIN}
* to use this functionality
*
* @param context the context used to launch any UI needed; use an activity context to make sure
diff --git a/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java b/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java
index 6baf91d7..ea951a5 100644
--- a/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java
@@ -236,9 +236,10 @@
private static final CameraExtensionManagerGlobal GLOBAL_CAMERA_MANAGER =
new CameraExtensionManagerGlobal();
private final Object mLock = new Object();
- private final int PROXY_SERVICE_DELAY_MS = 1000;
+ private final int PROXY_SERVICE_DELAY_MS = 2000;
private InitializerFuture mInitFuture = null;
private ServiceConnection mConnection = null;
+ private int mConnectionCount = 0;
private ICameraExtensionsProxyService mProxy = null;
private boolean mSupportsAdvancedExtensions = false;
@@ -249,6 +250,15 @@
return GLOBAL_CAMERA_MANAGER;
}
+ private void releaseProxyConnectionLocked(Context ctx) {
+ if (mConnection != null ) {
+ ctx.unbindService(mConnection);
+ mConnection = null;
+ mProxy = null;
+ mConnectionCount = 0;
+ }
+ }
+
private void connectToProxyLocked(Context ctx) {
if (mConnection == null) {
Intent intent = new Intent();
@@ -270,7 +280,6 @@
mConnection = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName component) {
- mInitFuture.setStatus(false);
mConnection = null;
mProxy = null;
}
@@ -348,23 +357,32 @@
public boolean registerClient(Context ctx, IBinder token) {
synchronized (mLock) {
+ boolean ret = false;
connectToProxyLocked(ctx);
if (mProxy == null) {
return false;
}
+ mConnectionCount++;
try {
- return mProxy.registerClient(token);
+ ret = mProxy.registerClient(token);
} catch (RemoteException e) {
Log.e(TAG, "Failed to initialize extension! Extension service does "
+ " not respond!");
}
+ if (!ret) {
+ mConnectionCount--;
+ }
- return false;
+ if (mConnectionCount <= 0) {
+ releaseProxyConnectionLocked(ctx);
+ }
+
+ return ret;
}
}
- public void unregisterClient(IBinder token) {
+ public void unregisterClient(Context ctx, IBinder token) {
synchronized (mLock) {
if (mProxy != null) {
try {
@@ -372,6 +390,11 @@
} catch (RemoteException e) {
Log.e(TAG, "Failed to de-initialize extension! Extension service does"
+ " not respond!");
+ } finally {
+ mConnectionCount--;
+ if (mConnectionCount <= 0) {
+ releaseProxyConnectionLocked(ctx);
+ }
}
}
}
@@ -446,8 +469,8 @@
/**
* @hide
*/
- public static void unregisterClient(IBinder token) {
- CameraExtensionManagerGlobal.get().unregisterClient(token);
+ public static void unregisterClient(Context ctx, IBinder token) {
+ CameraExtensionManagerGlobal.get().unregisterClient(ctx, token);
}
/**
@@ -578,7 +601,7 @@
}
}
} finally {
- unregisterClient(token);
+ unregisterClient(mContext, token);
}
return Collections.unmodifiableList(ret);
@@ -626,7 +649,7 @@
Log.e(TAG, "Failed to query the extension for postview availability! Extension "
+ "service does not respond!");
} finally {
- unregisterClient(token);
+ unregisterClient(mContext, token);
}
return false;
@@ -722,7 +745,7 @@
+ "service does not respond!");
return Collections.emptyList();
} finally {
- unregisterClient(token);
+ unregisterClient(mContext, token);
}
}
@@ -791,7 +814,7 @@
+ " not respond!");
return new ArrayList<>();
} finally {
- unregisterClient(token);
+ unregisterClient(mContext, token);
}
}
@@ -872,7 +895,7 @@
}
}
} finally {
- unregisterClient(token);
+ unregisterClient(mContext, token);
}
} catch (RemoteException e) {
Log.e(TAG, "Failed to query the extension supported sizes! Extension service does"
@@ -957,7 +980,7 @@
Log.e(TAG, "Failed to query the extension capture latency! Extension service does"
+ " not respond!");
} finally {
- unregisterClient(token);
+ unregisterClient(mContext, token);
}
return null;
@@ -998,7 +1021,7 @@
Log.e(TAG, "Failed to query the extension progress callbacks! Extension service does"
+ " not respond!");
} finally {
- unregisterClient(token);
+ unregisterClient(mContext, token);
}
return false;
@@ -1075,7 +1098,7 @@
} catch (RemoteException e) {
throw new IllegalStateException("Failed to query the available capture request keys!");
} finally {
- unregisterClient(token);
+ unregisterClient(mContext, token);
}
return Collections.unmodifiableSet(ret);
@@ -1155,7 +1178,7 @@
} catch (RemoteException e) {
throw new IllegalStateException("Failed to query the available capture result keys!");
} finally {
- unregisterClient(token);
+ unregisterClient(mContext, token);
}
return Collections.unmodifiableSet(ret);
diff --git a/core/java/android/hardware/camera2/camera_platform.aconfig b/core/java/android/hardware/camera2/camera_platform.aconfig
new file mode 100644
index 0000000..67f6300
--- /dev/null
+++ b/core/java/android/hardware/camera2/camera_platform.aconfig
@@ -0,0 +1,8 @@
+package: "com.android.hardware.camera2"
+
+flag {
+ namespace: "camera_platform"
+ name: "initial_test_flag"
+ description: "Flag infrastructure test flag"
+ bug: "292631208"
+}
diff --git a/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java
index e06699b..c7e74c0 100644
--- a/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java
@@ -90,7 +90,7 @@
private final HashMap<Integer, ImageReader> mReaderMap = new HashMap<>();
private RequestProcessor mRequestProcessor = new RequestProcessor();
private final int mSessionId;
- private final IBinder mToken;
+ private IBinder mToken = null;
private Surface mClientRepeatingRequestSurface;
private Surface mClientCaptureSurface;
@@ -103,6 +103,8 @@
private boolean mInitialized;
private boolean mSessionClosed;
+ private final Context mContext;
+
// Lock to synchronize cross-thread access to device public interface
final Object mInterfaceLock;
@@ -113,14 +115,9 @@
public static CameraAdvancedExtensionSessionImpl createCameraAdvancedExtensionSession(
@NonNull android.hardware.camera2.impl.CameraDeviceImpl cameraDevice,
@NonNull Map<String, CameraCharacteristics> characteristicsMap,
- @NonNull Context ctx, @NonNull ExtensionSessionConfiguration config, int sessionId)
+ @NonNull Context ctx, @NonNull ExtensionSessionConfiguration config, int sessionId,
+ @NonNull IBinder token)
throws CameraAccessException, RemoteException {
- final IBinder token = new Binder(TAG + " : " + sessionId);
- boolean success = CameraExtensionCharacteristics.registerClient(ctx, token);
- if (!success) {
- throw new UnsupportedOperationException("Unsupported extension!");
- }
-
String cameraId = cameraDevice.getId();
CameraExtensionCharacteristics extensionChars = new CameraExtensionCharacteristics(ctx,
cameraId, characteristicsMap);
@@ -204,8 +201,9 @@
IAdvancedExtenderImpl extender = CameraExtensionCharacteristics.initializeAdvancedExtension(
config.getExtension());
extender.init(cameraId, characteristicsMapNative);
- CameraAdvancedExtensionSessionImpl ret = new CameraAdvancedExtensionSessionImpl(extender,
- cameraDevice, characteristicsMapNative, repeatingRequestSurface,
+
+ CameraAdvancedExtensionSessionImpl ret = new CameraAdvancedExtensionSessionImpl(ctx,
+ extender, cameraDevice, characteristicsMapNative, repeatingRequestSurface,
burstCaptureSurface, postviewSurface, config.getStateCallback(),
config.getExecutor(), sessionId, token);
@@ -217,13 +215,16 @@
return ret;
}
- private CameraAdvancedExtensionSessionImpl(@NonNull IAdvancedExtenderImpl extender,
+ private CameraAdvancedExtensionSessionImpl(Context ctx,
+ @NonNull IAdvancedExtenderImpl extender,
@NonNull CameraDeviceImpl cameraDevice,
Map<String, CameraMetadataNative> characteristicsMap,
@Nullable Surface repeatingRequestSurface, @Nullable Surface burstCaptureSurface,
@Nullable Surface postviewSurface,
@NonNull StateCallback callback, @NonNull Executor executor,
- int sessionId, @NonNull IBinder token) {
+ int sessionId,
+ @NonNull IBinder token) {
+ mContext = ctx;
mAdvancedExtender = extender;
mCameraDevice = cameraDevice;
mCharacteristicsMap = characteristicsMap;
@@ -578,12 +579,16 @@
mSessionProcessor = null;
}
- CameraExtensionCharacteristics.unregisterClient(mToken);
- if (mInitialized || (mCaptureSession != null)) {
- notifyClose = true;
- CameraExtensionCharacteristics.releaseSession();
+
+ if (mToken != null) {
+ if (mInitialized || (mCaptureSession != null)) {
+ notifyClose = true;
+ CameraExtensionCharacteristics.releaseSession();
+ }
+ CameraExtensionCharacteristics.unregisterClient(mContext, mToken);
}
mInitialized = false;
+ mToken = null;
for (ImageReader reader : mReaderMap.values()) {
reader.close();
diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
index d3bde4b..181ab2c 100644
--- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
@@ -2550,19 +2550,32 @@
HashMap<String, CameraCharacteristics> characteristicsMap = new HashMap<>(
mPhysicalIdsToChars);
characteristicsMap.put(mCameraId, mCharacteristics);
+ boolean initializationFailed = true;
+ IBinder token = new Binder(TAG + " : " + mNextSessionId++);
try {
+ boolean ret = CameraExtensionCharacteristics.registerClient(mContext, token);
+ if (!ret) {
+ token = null;
+ throw new UnsupportedOperationException("Unsupported extension!");
+ }
+
if (CameraExtensionCharacteristics.areAdvancedExtensionsSupported()) {
mCurrentAdvancedExtensionSession =
CameraAdvancedExtensionSessionImpl.createCameraAdvancedExtensionSession(
this, characteristicsMap, mContext, extensionConfiguration,
- mNextSessionId++);
+ mNextSessionId, token);
} else {
mCurrentExtensionSession = CameraExtensionSessionImpl.createCameraExtensionSession(
this, characteristicsMap, mContext, extensionConfiguration,
- mNextSessionId++);
+ mNextSessionId, token);
}
+ initializationFailed = false;
} catch (RemoteException e) {
throw new CameraAccessException(CameraAccessException.CAMERA_ERROR);
+ } finally {
+ if (initializationFailed && (token != null)) {
+ CameraExtensionCharacteristics.unregisterClient(mContext, token);
+ }
}
}
}
diff --git a/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java
index 5d25681..bf77681 100644
--- a/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java
@@ -91,7 +91,7 @@
private final Set<CaptureRequest.Key> mSupportedRequestKeys;
private final Set<CaptureResult.Key> mSupportedResultKeys;
private final ExtensionSessionStatsAggregator mStatsAggregator;
- private final IBinder mToken;
+ private IBinder mToken = null;
private boolean mCaptureResultsSupported;
private CameraCaptureSession mCaptureSession = null;
@@ -119,6 +119,8 @@
// will do so internally.
private boolean mInternalRepeatingRequestEnabled = true;
+ private final Context mContext;
+
// Lock to synchronize cross-thread access to device public interface
final Object mInterfaceLock;
@@ -135,14 +137,9 @@
@NonNull Map<String, CameraCharacteristics> characteristicsMap,
@NonNull Context ctx,
@NonNull ExtensionSessionConfiguration config,
- int sessionId)
+ int sessionId,
+ @NonNull IBinder token)
throws CameraAccessException, RemoteException {
- final IBinder token = new Binder(TAG + " : " + sessionId);
- boolean success = CameraExtensionCharacteristics.registerClient(ctx, token);
- if (!success) {
- throw new UnsupportedOperationException("Unsupported extension!");
- }
-
String cameraId = cameraDevice.getId();
CameraExtensionCharacteristics extensionChars = new CameraExtensionCharacteristics(ctx,
cameraId, characteristicsMap);
@@ -234,6 +231,7 @@
characteristicsMap.get(cameraId).getNativeMetadata());
CameraExtensionSessionImpl session = new CameraExtensionSessionImpl(
+ ctx,
extenders.second,
extenders.first,
supportedPreviewSizes,
@@ -256,7 +254,7 @@
return session;
}
- public CameraExtensionSessionImpl(@NonNull IImageCaptureExtenderImpl imageExtender,
+ public CameraExtensionSessionImpl(Context ctx, @NonNull IImageCaptureExtenderImpl imageExtender,
@NonNull IPreviewExtenderImpl previewExtender,
@NonNull List<Size> previewSizes,
@NonNull android.hardware.camera2.impl.CameraDeviceImpl cameraDevice,
@@ -269,6 +267,7 @@
@NonNull IBinder token,
@NonNull Set<CaptureRequest.Key> requestKeys,
@Nullable Set<CaptureResult.Key> resultKeys) {
+ mContext = ctx;
mImageExtender = imageExtender;
mPreviewExtender = previewExtender;
mCameraDevice = cameraDevice;
@@ -878,12 +877,15 @@
+ " respond!");
}
- CameraExtensionCharacteristics.unregisterClient(mToken);
- if (mInitialized || (mCaptureSession != null)) {
- notifyClose = true;
- CameraExtensionCharacteristics.releaseSession();
+ if (mToken != null) {
+ if (mInitialized || (mCaptureSession != null)) {
+ notifyClose = true;
+ CameraExtensionCharacteristics.releaseSession();
+ }
+ CameraExtensionCharacteristics.unregisterClient(mContext, mToken);
}
mInitialized = false;
+ mToken = null;
if (mRepeatingRequestImageCallback != null) {
mRepeatingRequestImageCallback.close();
diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java
index 94bff89..4700720 100644
--- a/core/java/android/hardware/display/DisplayManagerInternal.java
+++ b/core/java/android/hardware/display/DisplayManagerInternal.java
@@ -370,8 +370,9 @@
/**
* Returns the default size of the surface associated with the display, or null if the surface
- * is not provided for layer mirroring by SurfaceFlinger.
- * Only used for mirroring started from MediaProjection.
+ * is not provided for layer mirroring by SurfaceFlinger. Size is rotated to reflect the current
+ * display device orientation.
+ * Used for mirroring from MediaProjection, or a physical display based on display flags.
*/
public abstract Point getDisplaySurfaceDefaultSize(int displayId);
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index eb471705..509c3b8 100755
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -1560,7 +1560,7 @@
String attestProp = getString(
TextUtils.formatSimple("ro.product.%s_for_attestation", property));
return attestProp.equals(UNKNOWN)
- ? getString(TextUtils.formatSimple("ro.product.vendor.%s", property)) : UNKNOWN;
+ ? getString(TextUtils.formatSimple("ro.product.vendor.%s", property)) : attestProp;
}
private static String[] getStringList(String property, String separator) {
diff --git a/core/java/android/os/DropBoxManager.java b/core/java/android/os/DropBoxManager.java
index 403f55c..cf35460 100644
--- a/core/java/android/os/DropBoxManager.java
+++ b/core/java/android/os/DropBoxManager.java
@@ -364,7 +364,7 @@
}
/**
- * Checks any blacklists (set in system settings) to see whether a certain
+ * Checks any denylists (set in system settings) to see whether a certain
* tag is allowed. Entries with disabled tags will be dropped immediately,
* so you can save the work of actually constructing and sending the data.
*
diff --git a/core/java/android/os/OWNERS b/core/java/android/os/OWNERS
index be7f276..d9a9266 100644
--- a/core/java/android/os/OWNERS
+++ b/core/java/android/os/OWNERS
@@ -10,6 +10,7 @@
# BatteryStats
per-file *BatteryConsumer* = file:/BATTERY_STATS_OWNERS
per-file BatteryManager* = file:/BATTERY_STATS_OWNERS
+per-file PowerMonitor* = file:/BATTERY_STATS_OWNERS
per-file PowerComponents.java = file:/BATTERY_STATS_OWNERS
per-file *Stats* = file:/BATTERY_STATS_OWNERS
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 99b0800..3e5f40c6 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1437,7 +1437,7 @@
/**
* Activity Action: Ask the user to allow an app to ignore battery optimizations (that is,
- * put them on the whitelist of apps shown by
+ * put them on the allowlist of apps shown by
* {@link #ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS}). For an app to use this, it also
* must hold the {@link android.Manifest.permission#REQUEST_IGNORE_BATTERY_OPTIMIZATIONS}
* permission.
@@ -10498,6 +10498,14 @@
"assist_long_press_home_enabled";
/**
+ * Whether press and hold on nav handle can trigger search.
+ *
+ * @hide
+ */
+ public static final String SEARCH_PRESS_HOLD_NAV_HANDLE_ENABLED =
+ "search_press_hold_nav_handle_enabled";
+
+ /**
* Control whether Trust Agents are in active unlock or extend unlock mode.
* @hide
*/
@@ -12195,7 +12203,7 @@
public static final String BUGREPORT_IN_POWER_MENU = "bugreport_in_power_menu";
/**
- * The package name for the custom bugreport handler app. This app must be whitelisted.
+ * The package name for the custom bugreport handler app. This app must be allowlisted.
* This is currently used only by Power Menu short press.
* @deprecated Use {@link android.provider.Settings.Secure#CUSTOM_BUGREPORT_HANDLER_APP}
* instead
@@ -12611,7 +12619,7 @@
"location_background_throttle_proximity_alert_interval_ms";
/**
- * Packages that are whitelisted for background throttling (throttling will not be applied).
+ * Packages that are allowlisted for background throttling (throttling will not be applied).
* @hide
*/
@Readable
@@ -12619,7 +12627,7 @@
"location_background_throttle_package_whitelist";
/**
- * Packages that are whitelisted for ignoring location settings (may retrieve location even
+ * Packages that are allowlisted for ignoring location settings (may retrieve location even
* when user location settings are off), for emergency purposes.
* @deprecated No longer used from Android 12+
* @hide
@@ -13203,7 +13211,7 @@
/**
* List of certificate (hex string representation of the application's certificate - SHA-1
- * or SHA-256) and carrier app package pairs which are whitelisted to prompt the user for
+ * or SHA-256) and carrier app package pairs which are allowlisted to prompt the user for
* install when a sim card with matching UICC carrier privilege rules is inserted. The
* certificate is used as a key, so the certificate encoding here must be the same as the
* certificate encoding used on the SIM.
@@ -16604,7 +16612,7 @@
"enable_adb_incremental_install_default";
/**
- * The packages whitelisted to be run in autofill compatibility mode. The list
+ * The packages allowlisted to be run in autofill compatibility mode. The list
* of packages is {@code ":"} colon delimited, and each entry has the name of the
* package and an optional list of url bar resource ids (the list is delimited by
* brackets&mdash{@code [} and {@code ]}&mdash and is also comma delimited).
@@ -16664,7 +16672,7 @@
public static final String STYLUS_EVER_USED = "stylus_ever_used";
/**
- * Exemptions to the hidden API blacklist.
+ * Exemptions to the hidden API denylist.
*
* @hide
*/
diff --git a/core/java/android/service/notification/NotificationRankingUpdate.java b/core/java/android/service/notification/NotificationRankingUpdate.java
index 75640bd..f3b4c6d 100644
--- a/core/java/android/service/notification/NotificationRankingUpdate.java
+++ b/core/java/android/service/notification/NotificationRankingUpdate.java
@@ -92,6 +92,7 @@
mapParcel.recycle();
if (buffer != null) {
mRankingMapFd.unmap(buffer);
+ mRankingMapFd.close();
}
}
} else {
diff --git a/core/java/android/service/voice/AlwaysOnHotwordDetector.java b/core/java/android/service/voice/AlwaysOnHotwordDetector.java
index 708ebdf..a4989af 100644
--- a/core/java/android/service/voice/AlwaysOnHotwordDetector.java
+++ b/core/java/android/service/voice/AlwaysOnHotwordDetector.java
@@ -67,6 +67,7 @@
import com.android.internal.app.IHotwordRecognitionStatusCallback;
import com.android.internal.app.IVoiceInteractionManagerService;
import com.android.internal.app.IVoiceInteractionSoundTriggerSession;
+import com.android.internal.infra.AndroidFuture;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
@@ -1702,6 +1703,11 @@
Slog.i(TAG, "onProcessRestarted");
mHandler.sendEmptyMessage(MSG_PROCESS_RESTARTED);
}
+
+ @Override
+ public void onOpenFile(String filename, AndroidFuture future) throws RemoteException {
+ throw new UnsupportedOperationException("Hotword cannot access files from the disk.");
+ }
}
void onDetectorRemoteException() {
diff --git a/core/java/android/service/voice/HotwordDetectionService.java b/core/java/android/service/voice/HotwordDetectionService.java
index d9ee859..ccf8b67 100644
--- a/core/java/android/service/voice/HotwordDetectionService.java
+++ b/core/java/android/service/voice/HotwordDetectionService.java
@@ -227,6 +227,12 @@
public void stopDetection() {
HotwordDetectionService.this.onStopDetection();
}
+
+ @Override
+ public void registerRemoteStorageService(IDetectorSessionStorageService
+ detectorSessionStorageService) {
+ throw new UnsupportedOperationException("Hotword cannot access files from the disk.");
+ }
};
@Override
diff --git a/core/java/android/service/voice/IDetectorSessionStorageService.aidl b/core/java/android/service/voice/IDetectorSessionStorageService.aidl
new file mode 100644
index 0000000..592373e
--- /dev/null
+++ b/core/java/android/service/voice/IDetectorSessionStorageService.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.service.voice;
+
+import com.android.internal.infra.AndroidFuture;
+
+/**
+ * @hide
+ */
+oneway interface IDetectorSessionStorageService {
+ /**
+ * Called when a file open request is sent. Only files with the given names under the internal
+ * app storage, i.e., {@link Context#getFilesDir()} can be opened.
+ */
+ void openFile(in String filename, in AndroidFuture future);
+}
diff --git a/core/java/android/service/voice/ISandboxedDetectionService.aidl b/core/java/android/service/voice/ISandboxedDetectionService.aidl
index 098536d..c76ac28 100644
--- a/core/java/android/service/voice/ISandboxedDetectionService.aidl
+++ b/core/java/android/service/voice/ISandboxedDetectionService.aidl
@@ -24,6 +24,7 @@
import android.os.ParcelFileDescriptor;
import android.os.PersistableBundle;
import android.os.SharedMemory;
+import android.service.voice.IDetectorSessionStorageService;
import android.service.voice.IDetectorSessionVisualQueryDetectionCallback;
import android.service.voice.IDspHotwordDetectionCallback;
import android.view.contentcapture.IContentCaptureManager;
@@ -71,4 +72,10 @@
void ping(in IRemoteCallback callback);
void stopDetection();
+
+ /**
+ * Registers the interface stub to talk to the voice interaction service for initialization/
+ * detection unrelated functionalities.
+ */
+ void registerRemoteStorageService(in IDetectorSessionStorageService detectorSessionStorageService);
}
diff --git a/core/java/android/service/voice/SoftwareHotwordDetector.java b/core/java/android/service/voice/SoftwareHotwordDetector.java
index 7ab4faf..88c2111 100644
--- a/core/java/android/service/voice/SoftwareHotwordDetector.java
+++ b/core/java/android/service/voice/SoftwareHotwordDetector.java
@@ -36,6 +36,7 @@
import com.android.internal.app.IHotwordRecognitionStatusCallback;
import com.android.internal.app.IVoiceInteractionManagerService;
+import com.android.internal.infra.AndroidFuture;
import java.io.PrintWriter;
import java.util.concurrent.Executor;
@@ -299,6 +300,11 @@
Binder.withCleanCallingIdentity(() -> mExecutor.execute(
() -> mCallback.onHotwordDetectionServiceRestarted()));
}
+
+ @Override
+ public void onOpenFile(String filename, AndroidFuture future) throws RemoteException {
+ throw new UnsupportedOperationException("Hotword cannot access files from the disk.");
+ }
}
/** @hide */
diff --git a/core/java/android/service/voice/VisualQueryDetectionService.java b/core/java/android/service/voice/VisualQueryDetectionService.java
index cbe7666..d184b1e 100644
--- a/core/java/android/service/voice/VisualQueryDetectionService.java
+++ b/core/java/android/service/voice/VisualQueryDetectionService.java
@@ -40,7 +40,12 @@
import android.view.contentcapture.ContentCaptureManager;
import android.view.contentcapture.IContentCaptureManager;
+import com.android.internal.infra.AndroidFuture;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
import java.util.Objects;
+import java.util.concurrent.ExecutionException;
import java.util.function.IntConsumer;
/**
@@ -86,6 +91,8 @@
private ContentCaptureManager mContentCaptureManager;
@Nullable
private IRecognitionServiceManager mIRecognitionServiceManager;
+ @Nullable
+ private IDetectorSessionStorageService mDetectorSessionStorageService;
private final ISandboxedDetectionService mInterface = new ISandboxedDetectionService.Stub() {
@@ -154,6 +161,12 @@
public void updateRecognitionServiceManager(IRecognitionServiceManager manager) {
mIRecognitionServiceManager = manager;
}
+
+ @Override
+ public void registerRemoteStorageService(IDetectorSessionStorageService
+ detectorSessionStorageService) {
+ mDetectorSessionStorageService = detectorSessionStorageService;
+ }
};
@Override
@@ -323,4 +336,23 @@
}
}
+ /**
+ * Overrides {@link Context#openFileInput} to read files with the given file names under the
+ * internal app storage of the {@link VoiceInteractionService}, i.e., only files stored in
+ * {@link Context#getFilesDir()} can be opened.
+ */
+ @Override
+ public @Nullable FileInputStream openFileInput(@NonNull String filename) throws
+ FileNotFoundException {
+ try {
+ AndroidFuture<ParcelFileDescriptor> future = new AndroidFuture<>();
+ mDetectorSessionStorageService.openFile(filename, future);
+ ParcelFileDescriptor pfd = future.get();
+ return new FileInputStream(pfd.getFileDescriptor());
+ } catch (RemoteException | ExecutionException | InterruptedException e) {
+ Log.w(TAG, "Cannot open file due to remote service failure");
+ throw new FileNotFoundException(e.getMessage());
+ }
+ }
+
}
diff --git a/core/java/android/service/voice/VisualQueryDetector.java b/core/java/android/service/voice/VisualQueryDetector.java
index 93b7964..5d7f478 100644
--- a/core/java/android/service/voice/VisualQueryDetector.java
+++ b/core/java/android/service/voice/VisualQueryDetector.java
@@ -25,6 +25,7 @@
import android.annotation.RequiresPermission;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
+import android.content.Context;
import android.hardware.soundtrigger.SoundTrigger;
import android.media.AudioFormat;
import android.os.Binder;
@@ -37,7 +38,10 @@
import com.android.internal.app.IHotwordRecognitionStatusCallback;
import com.android.internal.app.IVoiceInteractionManagerService;
+import com.android.internal.infra.AndroidFuture;
+import java.io.File;
+import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
@@ -58,17 +62,18 @@
private final Callback mCallback;
private final Executor mExecutor;
+ private final Context mContext;
private final IVoiceInteractionManagerService mManagerService;
private final VisualQueryDetectorInitializationDelegate mInitializationDelegate;
VisualQueryDetector(
IVoiceInteractionManagerService managerService,
- @NonNull @CallbackExecutor Executor executor,
- Callback callback) {
+ @NonNull @CallbackExecutor Executor executor, Callback callback, Context context) {
mManagerService = managerService;
mCallback = callback;
mExecutor = executor;
mInitializationDelegate = new VisualQueryDetectorInitializationDelegate();
+ mContext = context;
}
/**
@@ -245,7 +250,7 @@
@Override
void initialize(@Nullable PersistableBundle options, @Nullable SharedMemory sharedMemory) {
initAndVerifyDetector(options, sharedMemory,
- new InitializationStateListener(mExecutor, mCallback),
+ new InitializationStateListener(mExecutor, mCallback, mContext),
DETECTOR_TYPE_VISUAL_QUERY_DETECTOR);
}
@@ -330,9 +335,12 @@
private final Executor mExecutor;
private final Callback mCallback;
- InitializationStateListener(Executor executor, Callback callback) {
+ private final Context mContext;
+
+ InitializationStateListener(Executor executor, Callback callback, Context context) {
this.mExecutor = executor;
this.mCallback = callback;
+ this.mContext = context;
}
@Override
@@ -426,5 +434,22 @@
!TextUtils.isEmpty(errorMessage) ? errorMessage : "Error data is null");
}));
}
+ @Override
+ public void onOpenFile(String filename, AndroidFuture future) throws RemoteException {
+ Slog.v(TAG, "BinderCallback#onOpenFile " + filename);
+ Binder.withCleanCallingIdentity(() -> mExecutor.execute(() -> {
+ Slog.v(TAG, "onOpenFile: " + filename);
+ File f = new File(mContext.getFilesDir(), filename);
+ ParcelFileDescriptor pfd = null;
+ try {
+ Slog.d(TAG, "opened a file with ParcelFileDescriptor.");
+ pfd = ParcelFileDescriptor.open(f, ParcelFileDescriptor.MODE_READ_ONLY);
+ } catch (FileNotFoundException e) {
+ Slog.e(TAG, "Cannot open file. No ParcelFileDescriptor returned.");
+ } finally {
+ future.complete(pfd);
+ }
+ }));
+ }
}
}
diff --git a/core/java/android/service/voice/VoiceInteractionService.java b/core/java/android/service/voice/VoiceInteractionService.java
index ab9ae0a..de2a99b 100644
--- a/core/java/android/service/voice/VoiceInteractionService.java
+++ b/core/java/android/service/voice/VoiceInteractionService.java
@@ -965,7 +965,7 @@
}
VisualQueryDetector visualQueryDetector =
- new VisualQueryDetector(mSystemService, executor, callback);
+ new VisualQueryDetector(mSystemService, executor, callback, this);
HotwordDetector visualQueryDetectorInitializationDelegate =
visualQueryDetector.getInitializationDelegate();
mActiveDetectors.add(visualQueryDetectorInitializationDelegate);
diff --git a/core/java/android/speech/RecognitionService.java b/core/java/android/speech/RecognitionService.java
index 9656f36..7f313c1 100644
--- a/core/java/android/speech/RecognitionService.java
+++ b/core/java/android/speech/RecognitionService.java
@@ -38,6 +38,7 @@
import android.os.RemoteException;
import android.util.Log;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.function.pooled.PooledLambda;
import java.lang.ref.WeakReference;
@@ -232,39 +233,68 @@
intent,
attributionSource,
new ModelDownloadListener() {
+
+ private final Object mLock = new Object();
+
+ @GuardedBy("mLock")
+ private boolean mIsTerminated = false;
+
@Override
public void onProgress(int completedPercent) {
- try {
- listener.onProgress(completedPercent);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ synchronized (mLock) {
+ if (mIsTerminated) {
+ return;
+ }
+ try {
+ listener.onProgress(completedPercent);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
}
}
@Override
public void onSuccess() {
- try {
- listener.onSuccess();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ synchronized (mLock) {
+ if (mIsTerminated) {
+ return;
+ }
+ mIsTerminated = true;
+ try {
+ listener.onSuccess();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
}
}
@Override
public void onScheduled() {
- try {
- listener.onScheduled();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ synchronized (mLock) {
+ if (mIsTerminated) {
+ return;
+ }
+ mIsTerminated = true;
+ try {
+ listener.onScheduled();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
}
}
@Override
public void onError(int error) {
- try {
- listener.onError(error);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ synchronized (mLock) {
+ if (mIsTerminated) {
+ return;
+ }
+ mIsTerminated = true;
+ try {
+ listener.onError(error);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
}
}
});
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 4b96d74..0b2b6ce 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -375,6 +375,14 @@
public static final int FLAG_REAR = 1 << 13;
/**
+ * Display flag: Indicates that the orientation of this display is not fixed and is coupled to
+ * the orientation of its content.
+ *
+ * @hide
+ */
+ public static final int FLAG_ROTATES_WITH_CONTENT = 1 << 14;
+
+ /**
* Display flag: Indicates that the contents of the display should not be scaled
* to fit the physical screen dimensions. Used for development only to emulate
* devices with smaller physicals screens while preserving density.
diff --git a/core/java/android/view/HandwritingInitiator.java b/core/java/android/view/HandwritingInitiator.java
index 4cfec99..9b34007 100644
--- a/core/java/android/view/HandwritingInitiator.java
+++ b/core/java/android/view/HandwritingInitiator.java
@@ -19,7 +19,10 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
+import android.graphics.Matrix;
import android.graphics.Rect;
+import android.graphics.RectF;
+import android.graphics.Region;
import android.view.inputmethod.InputMethodManager;
import android.widget.TextView;
@@ -78,11 +81,17 @@
private int mConnectionCount = 0;
private final InputMethodManager mImm;
+ private final RectF mTempRectF = new RectF();
+
+ private final Region mTempRegion = new Region();
+
+ private final Matrix mTempMatrix = new Matrix();
+
/**
* The handwrite-able View that is currently the target of a hovering stylus pointer. This is
* used to help determine whether the handwriting PointerIcon should be shown in
* {@link #onResolvePointerIcon(Context, MotionEvent)} so that we can reduce the number of calls
- * to {@link #findBestCandidateView(float, float)}.
+ * to {@link #findBestCandidateView(float, float, boolean)}.
*/
@Nullable
private WeakReference<View> mCachedHoverTarget = null;
@@ -189,8 +198,8 @@
final float y = motionEvent.getY(pointerIndex);
if (largerThanTouchSlop(x, y, mState.mStylusDownX, mState.mStylusDownY)) {
mState.mExceedHandwritingSlop = true;
- View candidateView =
- findBestCandidateView(mState.mStylusDownX, mState.mStylusDownY);
+ View candidateView = findBestCandidateView(mState.mStylusDownX,
+ mState.mStylusDownY, /* isHover */ false);
if (candidateView != null) {
if (candidateView == getConnectedView()) {
if (!candidateView.hasFocus()) {
@@ -398,13 +407,14 @@
final View cachedHoverTarget = getCachedHoverTarget();
if (cachedHoverTarget != null) {
final Rect handwritingArea = getViewHandwritingArea(cachedHoverTarget);
- if (isInHandwritingArea(handwritingArea, hoverX, hoverY, cachedHoverTarget)
+ if (isInHandwritingArea(handwritingArea, hoverX, hoverY, cachedHoverTarget,
+ /* isHover */ true)
&& shouldTriggerStylusHandwritingForView(cachedHoverTarget)) {
return cachedHoverTarget;
}
}
- final View candidateView = findBestCandidateView(hoverX, hoverY);
+ final View candidateView = findBestCandidateView(hoverX, hoverY, /* isHover */ true);
if (candidateView != null) {
mCachedHoverTarget = new WeakReference<>(candidateView);
@@ -434,14 +444,14 @@
* @param y the y coordinates of the stylus event, in the coordinates of the window.
*/
@Nullable
- private View findBestCandidateView(float x, float y) {
+ private View findBestCandidateView(float x, float y, boolean isHover) {
// If the connectedView is not null and do not set any handwriting area, it will check
// whether the connectedView's boundary contains the initial stylus position. If true,
// directly return the connectedView.
final View connectedView = getConnectedView();
if (connectedView != null) {
Rect handwritingArea = getViewHandwritingArea(connectedView);
- if (isInHandwritingArea(handwritingArea, x, y, connectedView)
+ if (isInHandwritingArea(handwritingArea, x, y, connectedView, isHover)
&& shouldTriggerStylusHandwritingForView(connectedView)) {
return connectedView;
}
@@ -455,7 +465,7 @@
for (HandwritableViewInfo viewInfo : handwritableViewInfos) {
final View view = viewInfo.getView();
final Rect handwritingArea = viewInfo.getHandwritingArea();
- if (!isInHandwritingArea(handwritingArea, x, y, view)
+ if (!isInHandwritingArea(handwritingArea, x, y, view, isHover)
|| !shouldTriggerStylusHandwritingForView(view)) {
continue;
}
@@ -551,15 +561,48 @@
* Return true if the (x, y) is inside by the given {@link Rect} with the View's
* handwriting bounds with offsets applied.
*/
- private static boolean isInHandwritingArea(@Nullable Rect handwritingArea,
- float x, float y, View view) {
+ private boolean isInHandwritingArea(@Nullable Rect handwritingArea,
+ float x, float y, View view, boolean isHover) {
if (handwritingArea == null) return false;
- return contains(handwritingArea, x, y,
+ if (!contains(handwritingArea, x, y,
view.getHandwritingBoundsOffsetLeft(),
view.getHandwritingBoundsOffsetTop(),
view.getHandwritingBoundsOffsetRight(),
- view.getHandwritingBoundsOffsetBottom());
+ view.getHandwritingBoundsOffsetBottom())) {
+ return false;
+ }
+
+ // The returned handwritingArea computed by ViewParent#getChildVisibleRect didn't consider
+ // the case where a view is stacking on top of the editor. (e.g. DrawerLayout, popup)
+ // We must check the hit region of the editor again, and avoid the case where another
+ // view on top of the editor is handling MotionEvents.
+ ViewParent parent = view.getParent();
+ if (parent == null) {
+ return true;
+ }
+
+ Region region = mTempRegion;
+ mTempRegion.set(0, 0, view.getWidth(), view.getHeight());
+ Matrix matrix = mTempMatrix;
+ matrix.reset();
+ if (!parent.getChildLocalHitRegion(view, region, matrix, isHover)) {
+ return false;
+ }
+
+ // It's not easy to extend the region by the given handwritingBoundsOffset. Instead, we
+ // create a rectangle surrounding the motion event location and check if this rectangle
+ // overlaps with the hit region of the editor.
+ float left = x - view.getHandwritingBoundsOffsetRight();
+ float top = y - view.getHandwritingBoundsOffsetBottom();
+ float right = Math.max(x + view.getHandwritingBoundsOffsetLeft(), left + 1);
+ float bottom = Math.max(y + view.getHandwritingBoundsOffsetTop(), top + 1);
+ RectF rectF = mTempRectF;
+ rectF.set(left, top, right, bottom);
+ matrix.mapRect(rectF);
+
+ return region.op(Math.round(rectF.left), Math.round(rectF.top),
+ Math.round(rectF.right), Math.round(rectF.bottom), Region.Op.INTERSECT);
}
/**
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 1b1098d..7bdff8c 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -7361,6 +7361,90 @@
}
}
+ /**
+ * @hide
+ */
+ @Override
+ public boolean getChildLocalHitRegion(@NonNull View child, @NonNull Region region,
+ @NonNull Matrix matrix, boolean isHover) {
+ if (!child.hasIdentityMatrix()) {
+ matrix.preConcat(child.getInverseMatrix());
+ }
+
+ final int dx = child.mLeft - mScrollX;
+ final int dy = child.mTop - mScrollY;
+ matrix.preTranslate(-dx, -dy);
+
+ final int width = mRight - mLeft;
+ final int height = mBottom - mTop;
+
+ // Map the bounds of this view into the region's coordinates and clip the region.
+ final RectF rect = mAttachInfo != null ? mAttachInfo.mTmpTransformRect : new RectF();
+ rect.set(0, 0, width, height);
+ matrix.mapRect(rect);
+
+ boolean notEmpty = region.op(Math.round(rect.left), Math.round(rect.top),
+ Math.round(rect.right), Math.round(rect.bottom), Region.Op.INTERSECT);
+
+ if (isHover) {
+ HoverTarget target = mFirstHoverTarget;
+ boolean childIsHit = false;
+ while (target != null) {
+ final HoverTarget next = target.next;
+ if (target.child == child) {
+ childIsHit = true;
+ break;
+ }
+ target = next;
+ }
+ if (!childIsHit) {
+ target = mFirstHoverTarget;
+ while (notEmpty && target != null) {
+ final HoverTarget next = target.next;
+ final View hoveredView = target.child;
+
+ rect.set(hoveredView.mLeft, hoveredView.mTop, hoveredView.mRight,
+ hoveredView.mBottom);
+ matrix.mapRect(rect);
+ notEmpty = region.op(Math.round(rect.left), Math.round(rect.top),
+ Math.round(rect.right), Math.round(rect.bottom), Region.Op.DIFFERENCE);
+ target = next;
+ }
+ }
+ } else {
+ TouchTarget target = mFirstTouchTarget;
+ boolean childIsHit = false;
+ while (target != null) {
+ final TouchTarget next = target.next;
+ if (target.child == child) {
+ childIsHit = true;
+ break;
+ }
+ target = next;
+ }
+ if (!childIsHit) {
+ target = mFirstTouchTarget;
+ while (notEmpty && target != null) {
+ final TouchTarget next = target.next;
+ final View touchedView = target.child;
+
+ rect.set(touchedView.mLeft, touchedView.mTop, touchedView.mRight,
+ touchedView.mBottom);
+ matrix.mapRect(rect);
+ notEmpty = region.op(Math.round(rect.left), Math.round(rect.top),
+ Math.round(rect.right), Math.round(rect.bottom), Region.Op.DIFFERENCE);
+ target = next;
+ }
+ }
+ }
+
+ if (notEmpty && mParent != null) {
+ notEmpty = mParent.getChildLocalHitRegion(this, region, matrix, isHover);
+ }
+ return notEmpty;
+ }
+
+
private static void applyOpToRegionByBounds(Region region, View view, Region.Op op) {
final int[] locationInWindow = new int[2];
view.getLocationInWindow(locationInWindow);
diff --git a/core/java/android/view/ViewParent.java b/core/java/android/view/ViewParent.java
index 1020d2e..54bc348 100644
--- a/core/java/android/view/ViewParent.java
+++ b/core/java/android/view/ViewParent.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.Region;
import android.os.Bundle;
@@ -686,6 +687,36 @@
}
/**
+ * Compute the region where the child can receive the {@link MotionEvent}s from the root view.
+ *
+ * <p> Given region where the child will accept {@link MotionEvent}s.
+ * Modify the region to the unblocked region where the child can receive the
+ * {@link MotionEvent}s from the view root.
+ * </p>
+ *
+ * <p> The given region is always clipped by the bounds of the parent views. When there are
+ * on-going {@link MotionEvent}s, this method also makes use of the event dispatching results to
+ * determine whether a sibling view will also block the child's hit region.
+ * </p>
+ *
+ * @param child a child View, whose hit region we want to compute.
+ * @param region the initial hit region where the child view will handle {@link MotionEvent}s,
+ * defined in the child coordinates. Will be overwritten to the result hit region.
+ * @param matrix the matrix that maps the given child view's coordinates to the region
+ * coordinates. It will be modified to a matrix that maps window coordinates to
+ * the result region's coordinates.
+ * @param isHover if true it will return the hover events' hit region, otherwise it will
+ * return the touch events' hit region.
+ * @return true if the returned region is not empty.
+ * @hide
+ */
+ default boolean getChildLocalHitRegion(@NonNull View child, @NonNull Region region,
+ @NonNull Matrix matrix, boolean isHover) {
+ region.setEmpty();
+ return false;
+ }
+
+ /**
* Unbuffered dispatch has been requested by a child of this view parent.
* This method is called by the View hierarchy to signal ancestors that a View needs to
* request unbuffered dispatch.
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 6edf0e2..c1ce5e0 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -127,6 +127,7 @@
import android.graphics.PorterDuff;
import android.graphics.RecordingCanvas;
import android.graphics.Rect;
+import android.graphics.RectF;
import android.graphics.Region;
import android.graphics.RenderNode;
import android.graphics.drawable.Drawable;
@@ -2393,6 +2394,22 @@
}
@Override
+ public boolean getChildLocalHitRegion(@NonNull View child, @NonNull Region region,
+ @NonNull Matrix matrix, boolean isHover) {
+ if (child != mView) {
+ throw new IllegalArgumentException("child " + child + " is not the root view "
+ + mView + " managed by this ViewRootImpl");
+ }
+
+ RectF rectF = new RectF(0, 0, mWidth, mHeight);
+ matrix.mapRect(rectF);
+ // Note: don't apply scroll offset, because we want to know its
+ // visibility in the virtual canvas being given to the view hierarchy.
+ return region.op(Math.round(rectF.left), Math.round(rectF.top),
+ Math.round(rectF.right), Math.round(rectF.bottom), Region.Op.INTERSECT);
+ }
+
+ @Override
public void bringChildToFront(View child) {
}
diff --git a/core/java/com/android/internal/app/IHotwordRecognitionStatusCallback.aidl b/core/java/com/android/internal/app/IHotwordRecognitionStatusCallback.aidl
index 3801188..ba87caa 100644
--- a/core/java/com/android/internal/app/IHotwordRecognitionStatusCallback.aidl
+++ b/core/java/com/android/internal/app/IHotwordRecognitionStatusCallback.aidl
@@ -22,6 +22,7 @@
import android.service.voice.HotwordRejectedResult;
import android.service.voice.SoundTriggerFailure;
import android.service.voice.VisualQueryDetectionServiceFailure;
+import com.android.internal.infra.AndroidFuture;
/**
* @hide
@@ -113,4 +114,9 @@
/** Called when the hotword detection process is restarted */
void onProcessRestarted();
+
+ /**
+ * Called when a file open request is sent.
+ */
+ void onOpenFile(in String filename, in AndroidFuture future);
}
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index e5d5676..d90d5f8 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -352,7 +352,7 @@
JNIEnv* env;
jmethodID methodId;
- ALOGD("Calling main entry %s", className.string());
+ ALOGD("Calling main entry %s", className.c_str());
env = getJNIEnv();
if (clazz == NULL || env == NULL) {
@@ -361,7 +361,7 @@
methodId = env->GetStaticMethodID(clazz, "main", "([Ljava/lang/String;)V");
if (methodId == NULL) {
- ALOGE("ERROR: could not find method %s.main(String[])\n", className.string());
+ ALOGE("ERROR: could not find method %s.main(String[])\n", className.c_str());
return UNKNOWN_ERROR;
}
@@ -377,7 +377,7 @@
strArray = env->NewObjectArray(numArgs, stringClass, NULL);
for (size_t i = 0; i < numArgs; i++) {
- jstring argStr = env->NewStringUTF(args[i].string());
+ jstring argStr = env->NewStringUTF(args[i].c_str());
env->SetObjectArrayElement(strArray, i, argStr);
}
@@ -1268,7 +1268,7 @@
env->SetObjectArrayElement(strArray, 0, classNameStr);
for (size_t i = 0; i < options.size(); ++i) {
- jstring optionsStr = env->NewStringUTF(options.itemAt(i).string());
+ jstring optionsStr = env->NewStringUTF(options.itemAt(i).c_str());
assert(optionsStr != NULL);
env->SetObjectArrayElement(strArray, i + 1, optionsStr);
}
diff --git a/core/jni/android_content_res_ObbScanner.cpp b/core/jni/android_content_res_ObbScanner.cpp
index de429a0..760037f 100644
--- a/core/jni/android_content_res_ObbScanner.cpp
+++ b/core/jni/android_content_res_ObbScanner.cpp
@@ -52,7 +52,7 @@
env->ReleaseStringUTFChars(file, filePath);
- const char* packageNameStr = obb->getPackageName().string();
+ const char* packageNameStr = obb->getPackageName().c_str();
jstring packageName = env->NewStringUTF(packageNameStr);
if (packageName == NULL) {
diff --git a/core/jni/android_hardware_SensorManager.cpp b/core/jni/android_hardware_SensorManager.cpp
index 9c6a534..deb138f 100644
--- a/core/jni/android_hardware_SensorManager.cpp
+++ b/core/jni/android_hardware_SensorManager.cpp
@@ -150,7 +150,7 @@
return gStringOffsets.emptyString;
}
- ScopedLocalRef<jstring> javaString(env, env->NewStringUTF(string.string()));
+ ScopedLocalRef<jstring> javaString(env, env->NewStringUTF(string.c_str()));
jstring internedString = (jstring)
env->CallObjectMethod(javaString.get(), gStringOffsets.intern);
return internedString;
diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp
index a2205eb..c9a5fa6 100644
--- a/core/jni/android_util_AssetManager.cpp
+++ b/core/jni/android_util_AssetManager.cpp
@@ -273,7 +273,7 @@
if (alloc.length() <= 0) {
return nullptr;
}
- return env->NewStringUTF(alloc.string());
+ return env->NewStringUTF(alloc.c_str());
}
static jint NativeGetGlobalAssetManagerCount(JNIEnv* /*env*/, jobject /*clazz*/) {
@@ -429,7 +429,7 @@
}
for (size_t i = 0; i < file_count; i++) {
- jstring java_string = env->NewStringUTF(asset_dir->getFileName(i).string());
+ jstring java_string = env->NewStringUTF(asset_dir->getFileName(i).c_str());
// Check for errors creating the strings (if malformed or no memory).
if (env->ExceptionCheck()) {
diff --git a/core/jni/android_view_DisplayEventReceiver.cpp b/core/jni/android_view_DisplayEventReceiver.cpp
index 624bd5f..69fc515 100644
--- a/core/jni/android_view_DisplayEventReceiver.cpp
+++ b/core/jni/android_view_DisplayEventReceiver.cpp
@@ -292,7 +292,7 @@
if (status) {
String8 message;
message.appendFormat("Failed to initialize display event receiver. status=%d", status);
- jniThrowRuntimeException(env, message.string());
+ jniThrowRuntimeException(env, message.c_str());
return 0;
}
@@ -316,7 +316,7 @@
if (status) {
String8 message;
message.appendFormat("Failed to schedule next vertical sync pulse. status=%d", status);
- jniThrowRuntimeException(env, message.string());
+ jniThrowRuntimeException(env, message.c_str());
}
}
diff --git a/core/jni/android_view_InputEventSender.cpp b/core/jni/android_view_InputEventSender.cpp
index 15270ef..8d39ddf 100644
--- a/core/jni/android_view_InputEventSender.cpp
+++ b/core/jni/android_view_InputEventSender.cpp
@@ -334,7 +334,7 @@
if (status) {
String8 message;
message.appendFormat("Failed to initialize input event sender. status=%d", status);
- jniThrowRuntimeException(env, message.string());
+ jniThrowRuntimeException(env, message.c_str());
return 0;
}
diff --git a/core/proto/android/providers/settings/secure.proto b/core/proto/android/providers/settings/secure.proto
index a5d287c..481a2fb 100644
--- a/core/proto/android/providers/settings/secure.proto
+++ b/core/proto/android/providers/settings/secure.proto
@@ -137,6 +137,7 @@
optional SettingProto gesture_setup_complete = 9 [ (android.privacy).dest = DEST_AUTOMATIC ];
optional SettingProto touch_gesture_enabled = 10 [ (android.privacy).dest = DEST_AUTOMATIC ];
optional SettingProto long_press_home_enabled = 11 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto search_press_hold_nav_handle_enabled = 12 [ (android.privacy).dest = DEST_AUTOMATIC ];
}
optional Assist assist = 7;
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 5a9a415..48ac601 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -7772,8 +7772,9 @@
android:process=":ui">
</activity>
<activity android:name="com.android.internal.app.PlatLogoActivity"
- android:theme="@style/Theme.Wallpaper.NoTitleBar.Fullscreen"
+ android:theme="@style/Theme.NoTitleBar.Fullscreen"
android:configChanges="orientation|screenSize|screenLayout|keyboardHidden"
+ android:enableOnBackInvokedCallback="true"
android:icon="@drawable/platlogo"
android:process=":ui">
</activity>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index eeaa4c7..57ca210 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -6088,6 +6088,9 @@
<!-- Default value for Settings.ASSIST_TOUCH_GESTURE_ENABLED -->
<bool name="config_assistTouchGestureEnabledDefault">true</bool>
+ <!-- Default value for Settings.SEARCH_PRESS_HOLD_NAV_HANDLE_ENABLED -->
+ <bool name="config_searchPressHoldNavHandleEnabledDefault">true</bool>
+
<!-- The maximum byte size of the information contained in the bundle of
HotwordDetectedResult. -->
<integer translatable="false" name="config_hotwordDetectedResultMaxBundleSize">0</integer>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 9672ffc..85ba663 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -4865,6 +4865,8 @@
<java-symbol type="bool" name="config_assistLongPressHomeEnabledDefault" />
<java-symbol type="bool" name="config_assistTouchGestureEnabledDefault" />
+ <java-symbol type="bool" name="config_searchPressHoldNavHandleEnabledDefault" />
+
<java-symbol type="integer" name="config_hotwordDetectedResultMaxBundleSize" />
<java-symbol type="dimen" name="config_wallpaperDimAmount" />
diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml
index 31755ef..a358c4f 100644
--- a/core/tests/coretests/AndroidManifest.xml
+++ b/core/tests/coretests/AndroidManifest.xml
@@ -1749,6 +1749,15 @@
<category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
</intent-filter>
</activity>
+
+ <activity android:name="android.view.ViewGroupTestActivity"
+ android:label="ViewGroup Test"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
</application>
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
diff --git a/core/tests/coretests/res/layout/viewgroup_test.xml b/core/tests/coretests/res/layout/viewgroup_test.xml
new file mode 100644
index 0000000..04f4f52
--- /dev/null
+++ b/core/tests/coretests/res/layout/viewgroup_test.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2023 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.
+ -->
+
+<!-- Demonstrates adding/removing views from ViewGroup. See corresponding Java code. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/linear_layout"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+ <EditText
+ android:id="@+id/view"
+ android:layout_width="20dp"
+ android:layout_height="10dp"
+ android:text="Hello World!"
+ android:background="#2F00FF00" />
+ <EditText
+ android:id="@+id/view_scale"
+ android:layout_width="20dp"
+ android:layout_height="10dp"
+ android:scaleX="0.5"
+ android:scaleY="2"
+ android:transformPivotX="0dp"
+ android:transformPivotY="0dp"
+ android:text="Hello World!"
+ android:background="#2F00FF00" />
+ <EditText
+ android:id="@+id/view_translate"
+ android:layout_width="20dp"
+ android:layout_height="10dp"
+ android:translationX="10dp"
+ android:translationY="20dp"
+ android:text="Hello World!"
+ android:background="#2F00FF00" />
+ <FrameLayout
+ android:layout_width="20dp"
+ android:layout_height="10dp">
+ <EditText
+ android:id="@+id/view_overlap_bottom"
+ android:layout_width="20dp"
+ android:layout_height="10dp"
+ android:text="Hello World!"/>
+ <Button
+ android:id="@+id/view_overlap_top"
+ android:layout_width="10dp"
+ android:layout_height="10dp"/>
+ </FrameLayout>
+
+ <FrameLayout
+ android:layout_width="20dp"
+ android:layout_height="10dp">
+ <EditText
+ android:id="@+id/view_cover_bottom"
+ android:layout_width="10dp"
+ android:layout_height="10dp"
+ android:text="Hello World!"/>
+ <Button
+ android:id="@+id/view_cover_top"
+ android:layout_width="10dp"
+ android:layout_height="10dp"/>
+ </FrameLayout>
+
+</LinearLayout>
diff --git a/core/tests/coretests/src/android/service/notification/NotificationRankingUpdateTest.java b/core/tests/coretests/src/android/service/notification/NotificationRankingUpdateTest.java
index a84ac55..55ded9c 100644
--- a/core/tests/coretests/src/android/service/notification/NotificationRankingUpdateTest.java
+++ b/core/tests/coretests/src/android/service/notification/NotificationRankingUpdateTest.java
@@ -136,7 +136,11 @@
NotificationListenerService.RankingMap retrievedRankings =
retrievedRankingUpdate.getRankingMap();
assertNotNull(retrievedRankings);
- assertTrue(retrievedRankingUpdate.isFdNotNullAndClosed());
+ // The rankingUpdate file descriptor is only non-null in the new path.
+ if (SystemUiSystemPropertiesFlags.getResolver().isEnabled(
+ SystemUiSystemPropertiesFlags.NotificationFlags.RANKING_UPDATE_ASHMEM)) {
+ assertTrue(retrievedRankingUpdate.isFdNotNullAndClosed());
+ }
NotificationListenerService.Ranking retrievedRanking =
new NotificationListenerService.Ranking();
assertTrue(retrievedRankings.getRanking(TEST_KEY, retrievedRanking));
diff --git a/core/tests/coretests/src/android/view/ViewGroupGetChildLocalHitRegionTest.java b/core/tests/coretests/src/android/view/ViewGroupGetChildLocalHitRegionTest.java
new file mode 100644
index 0000000..60a0a2a
--- /dev/null
+++ b/core/tests/coretests/src/android/view/ViewGroupGetChildLocalHitRegionTest.java
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import static com.google.common.truth.Truth.assertThat;
+
+
+import android.graphics.Matrix;
+import android.graphics.Region;
+import android.platform.test.annotations.Presubmit;
+import android.widget.LinearLayout;
+
+import androidx.test.ext.junit.rules.ActivityScenarioRule;
+import androidx.test.filters.SmallTest;
+
+import com.android.frameworks.coretests.R;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+/**
+ * Test basic functions of ViewGroup.
+ *
+ * Build/Install/Run:
+ * atest FrameworksCoreTests:ViewGroupTest
+ */
+@Presubmit
+@SmallTest
+public class ViewGroupGetChildLocalHitRegionTest {
+ @Rule
+ public ActivityScenarioRule<ViewGroupTestActivity> mScenarioRule =
+ new ActivityScenarioRule<>(ViewGroupTestActivity.class);
+
+ private LinearLayout mRoot;
+ private final int[] mRootLocation = new int[2];
+
+ @Before
+ public void setup() {
+ mScenarioRule.getScenario().onActivity(activity -> {
+ mRoot = activity.findViewById(R.id.linear_layout);
+ mRoot.getLocationInWindow(mRootLocation);
+ });
+ }
+
+ @Test
+ public void testGetChildLocalHitRegion() {
+ assertGetChildLocalHitRegion(R.id.view);
+ }
+
+ @Test
+ public void testGetChildLocalHitRegion_withScale() {
+ assertGetChildLocalHitRegion(R.id.view_scale);
+ }
+
+ @Test
+ public void testGetChildLocalHitRegion_withTranslate() {
+ assertGetChildLocalHitRegion(R.id.view_translate);
+ }
+
+ @Test
+ public void testGetChildLocalHitRegion_overlap_noMotionEvent() {
+ assertGetChildLocalHitRegion(R.id.view_overlap_bottom);
+ }
+ @Test
+ public void testGetChildLocalHitRegion_overlap_withMotionEvent() {
+ // In this case, view_cover_bottom is partially covered by the view_cover_top.
+ // The returned region is the bounds of the bottom view subtract the bounds of the top view.
+ assertGetChildLocalHitRegion(R.id.view_overlap_top, R.id.view_overlap_bottom);
+ }
+
+ @Test
+ public void testGetChildLocalHitRegion_cover_withMotionEvent() {
+ // In this case, view_cover_bottom is completely covered by the view_cover_top.
+ // The returned region is expected to be empty.
+ assertGetChildLocalHitRegionEmpty(R.id.view_cover_top, R.id.view_cover_bottom);
+ }
+
+ private void injectMotionEvent(View view, boolean isHover) {
+ int[] location = new int[2];
+ view.getLocationInWindow(location);
+
+ float x = location[0] + view.getWidth() / 2f;
+ float y = location[1] + view.getHeight() / 2f;
+
+ int action = isHover ? MotionEvent.ACTION_HOVER_ENTER : MotionEvent.ACTION_DOWN;
+ MotionEvent motionEvent = MotionEvent.obtain(/* downtime= */ 0, /* eventTime= */ 0, action,
+ x, y, /* pressure= */ 0, /* size= */ 0, /* metaState= */ 0,
+ /* xPrecision= */ 1, /* yPrecision= */ 1, /* deviceId= */0, /* edgeFlags= */0);
+
+ View rootView = view.getRootView();
+ rootView.dispatchPointerEvent(motionEvent);
+ }
+
+ private void assertGetChildLocalHitRegion(int viewId) {
+ assertGetChildLocalHitRegion(viewId, /* isHover= */ true);
+ assertGetChildLocalHitRegion(viewId, /* isHover= */ false);
+ }
+
+ /**
+ * Assert ViewParent#getChildLocalHitRegion for a single view.
+ * @param viewId the viewId of the tested view.
+ * @param isHover if true, check the hit region of the hover events. Otherwise, check the hit
+ * region of the touch events.
+ */
+ private void assertGetChildLocalHitRegion(int viewId, boolean isHover) {
+ mScenarioRule.getScenario().onActivity(activity -> {
+ View view = activity.findViewById(viewId);
+
+ Matrix actualMatrix = new Matrix();
+ Region actualRegion = new Region(0, 0, view.getWidth(), view.getHeight());
+ boolean actualNotEmpty = view.getParent()
+ .getChildLocalHitRegion(view, actualRegion, actualMatrix, isHover);
+
+ int[] windowLocation = new int[2];
+ view.getLocationInWindow(windowLocation);
+ Matrix expectMatrix = new Matrix();
+ expectMatrix.preScale(1 / view.getScaleX(), 1 / view.getScaleY());
+ expectMatrix.preTranslate(-windowLocation[0], -windowLocation[1]);
+
+ Region expectRegion = new Region(0, 0, view.getWidth(), view.getHeight());
+
+ assertThat(actualNotEmpty).isTrue();
+ assertThat(actualMatrix).isEqualTo(expectMatrix);
+ assertThat(actualRegion).isEqualTo(expectRegion);
+ });
+ }
+
+ private void assertGetChildLocalHitRegion(int viewIdTop, int viewIdBottom) {
+ assertGetChildLocalHitRegion(viewIdTop, viewIdBottom, /* isHover= */ true);
+ assertGetChildLocalHitRegion(viewIdTop, viewIdBottom, /* isHover= */ false);
+ }
+
+ /**
+ * Assert ViewParent#getChildLocalHitRegion of a view that is covered by another view. It will
+ * inject {@link MotionEvent}s to the view on top first and then get the hit region of the
+ * bottom view.
+ *
+ * @param viewIdTop the view id of the test view on top.
+ * @param viewIdBottom the view id of the test view at the bottom.
+ * @param isHover if true, check the hit region of the hover events. Otherwise, check the hit
+ * region of the touch events.
+ */
+ private void assertGetChildLocalHitRegion(int viewIdTop, int viewIdBottom, boolean isHover) {
+ mScenarioRule.getScenario().onActivity(activity -> {
+ View viewTop = activity.findViewById(viewIdTop);
+ View viewBottom = activity.findViewById(viewIdBottom);
+
+ injectMotionEvent(viewTop, isHover);
+
+ Matrix actualMatrix = new Matrix();
+ Region actualRegion = new Region(0, 0, viewBottom.getWidth(), viewBottom.getHeight());
+ boolean actualNotEmpty = viewBottom.getParent()
+ .getChildLocalHitRegion(viewBottom, actualRegion, actualMatrix, isHover);
+
+ int[] windowLocation = new int[2];
+ viewBottom.getLocationInWindow(windowLocation);
+ Matrix expectMatrix = new Matrix();
+ expectMatrix.preTranslate(-windowLocation[0], -windowLocation[1]);
+
+ Region expectRegion = new Region(0, 0, viewBottom.getWidth(), viewBottom.getHeight());
+ expectRegion.op(0, 0, viewTop.getWidth(), viewTop.getHeight(), Region.Op.DIFFERENCE);
+
+ assertThat(actualNotEmpty).isTrue();
+ assertThat(actualMatrix).isEqualTo(expectMatrix);
+ assertThat(actualRegion).isEqualTo(expectRegion);
+ });
+ }
+
+ private void assertGetChildLocalHitRegionEmpty(int viewIdTop, int viewIdBottom) {
+ assertGetChildLocalHitRegionEmpty(viewIdTop, viewIdBottom, /* isHover= */ true);
+ assertGetChildLocalHitRegionEmpty(viewIdTop, viewIdBottom, /* isHover= */ false);
+ }
+
+ /**
+ * Assert ViewParent#getChildLocalHitRegion returns an empty region for a view that is
+ * completely covered by another view. It will inject {@link MotionEvent}s to the view on top
+ * first and then get the hit region of the
+ * bottom view.
+ *
+ * @param viewIdTop the view id of the test view on top.
+ * @param viewIdBottom the view id of the test view at the bottom.
+ * @param isHover if true, check the hit region of the hover events. Otherwise, check the hit
+ * region of the touch events.
+ */
+ private void assertGetChildLocalHitRegionEmpty(int viewIdTop, int viewIdBottom,
+ boolean isHover) {
+ mScenarioRule.getScenario().onActivity(activity -> {
+ View viewTop = activity.findViewById(viewIdTop);
+ View viewBottom = activity.findViewById(viewIdBottom);
+
+ injectMotionEvent(viewTop, isHover);
+
+ Region actualRegion = new Region(0, 0, viewBottom.getWidth(), viewBottom.getHeight());
+ boolean actualNotEmpty = viewBottom.getParent()
+ .getChildLocalHitRegion(viewBottom, actualRegion, new Matrix(), isHover);
+
+ assertThat(actualNotEmpty).isFalse();
+ assertThat(actualRegion.isEmpty()).isTrue();
+ });
+ }
+}
diff --git a/core/tests/coretests/src/android/view/ViewGroupTestActivity.java b/core/tests/coretests/src/android/view/ViewGroupTestActivity.java
new file mode 100644
index 0000000..b94bda5
--- /dev/null
+++ b/core/tests/coretests/src/android/view/ViewGroupTestActivity.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import android.annotation.Nullable;
+import android.app.Activity;
+import android.os.Bundle;
+
+import com.android.frameworks.coretests.R;
+
+public class ViewGroupTestActivity extends Activity {
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.viewgroup_test);
+ }
+}
diff --git a/core/tests/coretests/src/android/view/stylus/HandwritingTestUtil.java b/core/tests/coretests/src/android/view/stylus/HandwritingTestUtil.java
index 388a996..b4c72ca 100644
--- a/core/tests/coretests/src/android/view/stylus/HandwritingTestUtil.java
+++ b/core/tests/coretests/src/android/view/stylus/HandwritingTestUtil.java
@@ -21,7 +21,9 @@
import android.app.Instrumentation;
import android.content.Context;
+import android.graphics.Matrix;
import android.graphics.Rect;
+import android.graphics.Region;
import android.view.View;
import android.view.ViewGroup;
@@ -45,7 +47,7 @@
float handwritingBoundsOffsetRight, float handwritingBoundsOffsetBottom) {
final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
final Context context = instrumentation.getTargetContext();
- // mock a parent so that HandwritingInitiator can get
+ // mock a parent so that HandwritingInitiator can get visible rect and hit region.
final ViewGroup parent = new ViewGroup(context) {
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
@@ -56,6 +58,14 @@
r.set(handwritingArea);
return true;
}
+
+ @Override
+ public boolean getChildLocalHitRegion(View child, Region region, Matrix matrix,
+ boolean isHover) {
+ matrix.reset();
+ region.set(handwritingArea);
+ return true;
+ }
};
View view = spy(new View(context));
diff --git a/libs/WindowManager/Shell/res/layout/bubble_bar_manage_education.xml b/libs/WindowManager/Shell/res/layout/bubble_bar_manage_education.xml
new file mode 100644
index 0000000..a0a06f1
--- /dev/null
+++ b/libs/WindowManager/Shell/res/layout/bubble_bar_manage_education.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2023 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
+ -->
+<com.android.wm.shell.common.bubbles.BubblePopupView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:layout_marginHorizontal="@dimen/bubble_popup_margin_horizontal"
+ android:layout_marginTop="@dimen/bubble_popup_margin_top"
+ android:elevation="@dimen/bubble_manage_menu_elevation"
+ android:gravity="center_horizontal"
+ android:orientation="vertical">
+
+ <ImageView
+ android:layout_width="32dp"
+ android:layout_height="32dp"
+ android:tint="?android:attr/colorAccent"
+ android:contentDescription="@null"
+ android:src="@drawable/pip_ic_settings"/>
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="16dp"
+ android:maxWidth="@dimen/bubble_popup_content_max_width"
+ android:maxLines="1"
+ android:ellipsize="end"
+ android:textAppearance="@android:style/TextAppearance.DeviceDefault.Headline"
+ android:textColor="?android:attr/textColorPrimary"
+ android:text="@string/bubble_bar_education_manage_title"/>
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="16dp"
+ android:maxWidth="@dimen/bubble_popup_content_max_width"
+ android:textAppearance="@android:style/TextAppearance.DeviceDefault"
+ android:textColor="?android:attr/textColorSecondary"
+ android:textAlignment="center"
+ android:text="@string/bubble_bar_education_manage_text"/>
+
+</com.android.wm.shell.common.bubbles.BubblePopupView>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml
index 0502a99..63a9723 100644
--- a/libs/WindowManager/Shell/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/res/values/dimen.xml
@@ -226,6 +226,20 @@
<dimen name="bubble_user_education_padding_end">58dp</dimen>
<!-- Padding between the bubble and the user education text. -->
<dimen name="bubble_user_education_stack_padding">16dp</dimen>
+ <!-- Max width for the bubble popup view. -->
+ <dimen name="bubble_popup_content_max_width">300dp</dimen>
+ <!-- Horizontal margin for the bubble popup view. -->
+ <dimen name="bubble_popup_margin_horizontal">32dp</dimen>
+ <!-- Top margin for the bubble popup view. -->
+ <dimen name="bubble_popup_margin_top">16dp</dimen>
+ <!-- Width for the bubble popup view arrow. -->
+ <dimen name="bubble_popup_arrow_width">12dp</dimen>
+ <!-- Height for the bubble popup view arrow. -->
+ <dimen name="bubble_popup_arrow_height">10dp</dimen>
+ <!-- Corner radius for the bubble popup view arrow. -->
+ <dimen name="bubble_popup_arrow_corner_radius">2dp</dimen>
+ <!-- Padding for the bubble popup view contents. -->
+ <dimen name="bubble_popup_padding">24dp</dimen>
<!-- The size of the caption bar inset at the top of bubble bar expanded view. -->
<dimen name="bubble_bar_expanded_view_caption_height">32dp</dimen>
<!-- The height of the dots shown for the caption menu in the bubble bar expanded view.. -->
diff --git a/libs/WindowManager/Shell/res/values/strings.xml b/libs/WindowManager/Shell/res/values/strings.xml
index 8cbc3d0..00c63d7 100644
--- a/libs/WindowManager/Shell/res/values/strings.xml
+++ b/libs/WindowManager/Shell/res/values/strings.xml
@@ -163,6 +163,11 @@
<!-- [CHAR LIMIT=NONE] Empty overflow subtitle -->
<string name="bubble_overflow_empty_subtitle">Recent bubbles and dismissed bubbles will appear here</string>
+ <!-- Title text for the bubble bar "manage" button tool tip highlighting where users can go to control bubble settings. [CHAR LIMIT=60]-->
+ <string name="bubble_bar_education_manage_title">Control bubbles anytime</string>
+ <!-- Descriptive text for the bubble bar "manage" button tool tip highlighting where users can go to control bubble settings. [CHAR LIMIT=80]-->
+ <string name="bubble_bar_education_manage_text">Tap here to manage which apps and conversations can bubble</string>
+
<!-- [CHAR LIMIT=100] Notification Importance title -->
<string name="notification_bubble_title">Bubble</string>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java
index 7e09c98..ff67110 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java
@@ -60,7 +60,6 @@
/**
* Encapsulates the data and UI elements of a bubble.
*/
-@VisibleForTesting
public class Bubble implements BubbleViewProvider {
private static final String TAG = "Bubble";
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleEducationController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleEducationController.kt
new file mode 100644
index 0000000..e57f02c
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleEducationController.kt
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2023 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.bubbles
+
+import android.content.Context
+import android.util.Log
+import androidx.core.content.edit
+import com.android.wm.shell.bubbles.BubbleDebugConfig.DEBUG_USER_EDUCATION
+import com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_BUBBLES
+import com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME
+
+/** Manages bubble education flags. Provides convenience methods to check the education state */
+class BubbleEducationController(private val context: Context) {
+ private val prefs = context.getSharedPreferences(context.packageName, Context.MODE_PRIVATE)
+
+ /** Whether the user has seen the stack education */
+ @get:JvmName(name = "hasSeenStackEducation")
+ var hasSeenStackEducation: Boolean
+ get() = prefs.getBoolean(PREF_STACK_EDUCATION, false)
+ set(value) = prefs.edit { putBoolean(PREF_STACK_EDUCATION, value) }
+
+ /** Whether the user has seen the expanded view "manage" menu education */
+ @get:JvmName(name = "hasSeenManageEducation")
+ var hasSeenManageEducation: Boolean
+ get() = prefs.getBoolean(PREF_MANAGED_EDUCATION, false)
+ set(value) = prefs.edit { putBoolean(PREF_MANAGED_EDUCATION, value) }
+
+ /** Whether education view should show for the collapsed stack. */
+ fun shouldShowStackEducation(bubble: BubbleViewProvider?): Boolean {
+ val shouldShow = bubble != null &&
+ bubble.isConversationBubble && // show education for conversation bubbles only
+ (!hasSeenStackEducation || BubbleDebugConfig.forceShowUserEducation(context))
+ logDebug("Show stack edu: $shouldShow")
+ return shouldShow
+ }
+
+ /** Whether the educational view should show for the expanded view "manage" menu. */
+ fun shouldShowManageEducation(bubble: BubbleViewProvider?): Boolean {
+ val shouldShow = bubble != null &&
+ bubble.isConversationBubble && // show education for conversation bubbles only
+ (!hasSeenManageEducation || BubbleDebugConfig.forceShowUserEducation(context))
+ logDebug("Show manage edu: $shouldShow")
+ return shouldShow
+ }
+
+ private fun logDebug(message: String) {
+ if (DEBUG_USER_EDUCATION) {
+ Log.d(TAG, message)
+ }
+ }
+
+ companion object {
+ private val TAG = if (TAG_WITH_CLASS_NAME) "BubbleEducationController" else TAG_BUBBLES
+ const val PREF_STACK_EDUCATION: String = "HasSeenBubblesOnboarding"
+ const val PREF_MANAGED_EDUCATION: String = "HasSeenBubblesManageOnboarding"
+ }
+}
+
+/** Convenience extension method to check if the bubble is a conversation bubble */
+private val BubbleViewProvider.isConversationBubble: Boolean
+ get() = if (this is Bubble) isConversation else false
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePopupViewExt.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePopupViewExt.kt
new file mode 100644
index 0000000..bdb09e1
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePopupViewExt.kt
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2023 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.bubbles
+
+import android.graphics.Color
+import com.android.wm.shell.R
+import com.android.wm.shell.common.bubbles.BubblePopupDrawable
+import com.android.wm.shell.common.bubbles.BubblePopupView
+
+/**
+ * A convenience method to setup the [BubblePopupView] with the correct config using local resources
+ */
+fun BubblePopupView.setup() {
+ val attrs =
+ context.obtainStyledAttributes(
+ intArrayOf(
+ com.android.internal.R.attr.materialColorSurface,
+ android.R.attr.dialogCornerRadius
+ )
+ )
+
+ val res = context.resources
+ val config =
+ BubblePopupDrawable.Config(
+ color = attrs.getColor(0, Color.WHITE),
+ cornerRadius = attrs.getDimension(1, 0f),
+ contentPadding = res.getDimensionPixelSize(R.dimen.bubble_popup_padding),
+ arrowWidth = res.getDimension(R.dimen.bubble_popup_arrow_width),
+ arrowHeight = res.getDimension(R.dimen.bubble_popup_arrow_height),
+ arrowRadius = res.getDimension(R.dimen.bubble_popup_arrow_corner_radius)
+ )
+ attrs.recycle()
+ setupBackground(config)
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
index da5974f..8ae12c7 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
@@ -46,7 +46,6 @@
import android.graphics.RectF;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
-import android.os.SystemProperties;
import android.provider.Settings;
import android.util.Log;
import android.view.Choreographer;
@@ -108,12 +107,6 @@
*/
public class BubbleStackView extends FrameLayout
implements ViewTreeObserver.OnComputeInternalInsetsListener {
-
- // LINT.IfChange
- public static final boolean ENABLE_FLING_TO_DISMISS_BUBBLE =
- SystemProperties.getBoolean("persist.wm.debug.fling_to_dismiss_bubble", true);
- // LINT.ThenChange(com/android/launcher3/taskbar/bubbles/BubbleDismissController.java)
-
private static final String TAG = TAG_WITH_CLASS_NAME ? "BubbleStackView" : TAG_BUBBLES;
/** How far the flyout needs to be dragged before it's dismissed regardless of velocity. */
@@ -138,7 +131,7 @@
private static final int EXPANDED_VIEW_ALPHA_ANIMATION_DURATION = 150;
- private static final float SCRIM_ALPHA = 0.6f;
+ private static final float SCRIM_ALPHA = 0.32f;
/** Minimum alpha value for scrim when alpha is being changed via drag */
private static final float MIN_SCRIM_ALPHA_FOR_DRAG = 0.2f;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationController.java
index 33629f9..c20733a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationController.java
@@ -19,7 +19,6 @@
import static android.view.View.LAYOUT_DIRECTION_RTL;
import static com.android.wm.shell.bubbles.BubblePositioner.NUM_VISIBLE_WHEN_RESTING;
-import static com.android.wm.shell.bubbles.BubbleStackView.ENABLE_FLING_TO_DISMISS_BUBBLE;
import android.content.res.Resources;
import android.graphics.Path;
@@ -355,7 +354,6 @@
mMagnetizedBubbleDraggingOut.setMagnetListener(listener);
mMagnetizedBubbleDraggingOut.setHapticsEnabled(true);
mMagnetizedBubbleDraggingOut.setFlingToTargetMinVelocity(FLING_TO_DISMISS_MIN_VELOCITY);
- mMagnetizedBubbleDraggingOut.setFlingToTargetEnabled(ENABLE_FLING_TO_DISMISS_BUBBLE);
}
private void springBubbleTo(View bubble, float x, float y) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/StackAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/StackAnimationController.java
index 5533842..4bb1ab4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/StackAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/StackAnimationController.java
@@ -17,7 +17,6 @@
package com.android.wm.shell.bubbles.animation;
import static com.android.wm.shell.bubbles.BubblePositioner.NUM_VISIBLE_WHEN_RESTING;
-import static com.android.wm.shell.bubbles.BubbleStackView.ENABLE_FLING_TO_DISMISS_BUBBLE;
import android.content.ContentResolver;
import android.content.res.Resources;
@@ -1026,7 +1025,6 @@
};
mMagnetizedStack.setHapticsEnabled(true);
mMagnetizedStack.setFlingToTargetMinVelocity(FLING_TO_DISMISS_MIN_VELOCITY);
- mMagnetizedStack.setFlingToTargetEnabled(ENABLE_FLING_TO_DISMISS_BUBBLE);
}
final ContentResolver contentResolver = mLayout.getContext().getContentResolver();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java
index 6b6d6ba..79f188a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java
@@ -39,7 +39,6 @@
import com.android.wm.shell.bubbles.Bubbles;
import com.android.wm.shell.taskview.TaskView;
-import java.util.function.Consumer;
import java.util.function.Supplier;
/**
@@ -48,6 +47,18 @@
* {@link BubbleController#isShowingAsBubbleBar()}
*/
public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskViewHelper.Listener {
+ /**
+ * The expanded view listener notifying the {@link BubbleBarLayerView} about the internal
+ * actions and events
+ */
+ public interface Listener {
+ /** Called when the task view task is first created. */
+ void onTaskCreated();
+ /** Called when expanded view needs to un-bubble the given conversation */
+ void onUnBubbleConversation(String bubbleKey);
+ /** Called when expanded view task view back button pressed */
+ void onBackPressed();
+ }
private static final String TAG = BubbleBarExpandedView.class.getSimpleName();
private static final int INVALID_TASK_ID = -1;
@@ -57,7 +68,7 @@
private BubbleTaskViewHelper mBubbleTaskViewHelper;
private BubbleBarMenuViewController mMenuViewController;
private @Nullable Supplier<Rect> mLayerBoundsSupplier;
- private @Nullable Consumer<String> mUnBubbleConversationCallback;
+ private @Nullable Listener mListener;
private BubbleBarHandleView mHandleView = new BubbleBarHandleView(getContext());
private @Nullable TaskView mTaskView;
@@ -145,15 +156,13 @@
mMenuViewController.setListener(new BubbleBarMenuViewController.Listener() {
@Override
public void onMenuVisibilityChanged(boolean visible) {
- if (mTaskView == null || mLayerBoundsSupplier == null) return;
- // Updates the obscured touchable region for the task surface.
- mTaskView.setObscuredTouchRect(visible ? mLayerBoundsSupplier.get() : null);
+ setObscured(visible);
}
@Override
public void onUnBubbleConversation(Bubble bubble) {
- if (mUnBubbleConversationCallback != null) {
- mUnBubbleConversationCallback.accept(bubble.getKey());
+ if (mListener != null) {
+ mListener.onUnBubbleConversation(bubble.getKey());
}
}
@@ -231,6 +240,9 @@
public void onTaskCreated() {
setContentVisibility(true);
updateHandleColor(false /* animated */);
+ if (mListener != null) {
+ mListener.onTaskCreated();
+ }
}
@Override
@@ -240,7 +252,8 @@
@Override
public void onBackPressed() {
- mController.collapseStack();
+ if (mListener == null) return;
+ mListener.onBackPressed();
}
/** Cleans up task view, should be called when the bubble is no longer active. */
@@ -254,6 +267,18 @@
mMenuViewController.hideMenu(false /* animated */);
}
+ /**
+ * Hides the current modal menu view or collapses the bubble stack.
+ * Called from {@link BubbleBarLayerView}
+ */
+ public void hideMenuOrCollapse() {
+ if (mMenuViewController.isMenuVisible()) {
+ mMenuViewController.hideMenu(/* animated = */ true);
+ } else {
+ mController.collapseStack();
+ }
+ }
+
/** Updates the bubble shown in the expanded view. */
public void update(Bubble bubble) {
mBubbleTaskViewHelper.update(bubble);
@@ -270,10 +295,16 @@
mLayerBoundsSupplier = supplier;
}
- /** Sets the function to call to un-bubble the given conversation. */
- public void setUnBubbleConversationCallback(
- @Nullable Consumer<String> unBubbleConversationCallback) {
- mUnBubbleConversationCallback = unBubbleConversationCallback;
+ /** Sets expanded view listener */
+ void setListener(@Nullable Listener listener) {
+ mListener = listener;
+ }
+
+ /** Sets whether the view is obscured by some modal view */
+ void setObscured(boolean obscured) {
+ if (mTaskView == null || mLayerBoundsSupplier == null) return;
+ // Updates the obscured touchable region for the task surface.
+ mTaskView.setObscuredTouchRect(obscured ? mLayerBoundsSupplier.get() : null);
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java
index bc04bfc..8f11253 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java
@@ -52,6 +52,7 @@
private final BubbleController mBubbleController;
private final BubblePositioner mPositioner;
private final BubbleBarAnimationHelper mAnimationHelper;
+ private final BubbleEducationViewController mEducationViewController;
private final View mScrimView;
@Nullable
@@ -80,6 +81,10 @@
mAnimationHelper = new BubbleBarAnimationHelper(context,
this, mPositioner);
+ mEducationViewController = new BubbleEducationViewController(context, (boolean visible) -> {
+ if (mExpandedView == null) return;
+ mExpandedView.setObscured(visible);
+ });
mScrimView = new View(getContext());
mScrimView.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
@@ -90,9 +95,7 @@
mScrimView.setBackgroundDrawable(new ColorDrawable(
getResources().getColor(android.R.color.system_neutral1_1000)));
- setOnClickListener(view -> {
- mBubbleController.collapseStack();
- });
+ setOnClickListener(view -> hideMenuOrCollapse());
}
@Override
@@ -108,6 +111,7 @@
getViewTreeObserver().removeOnComputeInternalInsetsListener(this);
if (mExpandedView != null) {
+ mEducationViewController.hideManageEducation(/* animated = */ false);
removeView(mExpandedView);
mExpandedView = null;
}
@@ -162,14 +166,27 @@
final int width = mPositioner.getExpandedViewWidthForBubbleBar(isOverflowExpanded);
final int height = mPositioner.getExpandedViewHeightForBubbleBar(isOverflowExpanded);
mExpandedView.setVisibility(GONE);
- mExpandedView.setUnBubbleConversationCallback(mUnBubbleConversationCallback);
+ mExpandedView.setY(mPositioner.getExpandedViewBottomForBubbleBar() - height);
mExpandedView.setLayerBoundsSupplier(() -> new Rect(0, 0, getWidth(), getHeight()));
- mExpandedView.setUnBubbleConversationCallback(bubbleKey -> {
- if (mUnBubbleConversationCallback != null) {
- mUnBubbleConversationCallback.accept(bubbleKey);
+ mExpandedView.setListener(new BubbleBarExpandedView.Listener() {
+ @Override
+ public void onTaskCreated() {
+ mEducationViewController.maybeShowManageEducation(b, mExpandedView);
+ }
+
+ @Override
+ public void onUnBubbleConversation(String bubbleKey) {
+ if (mUnBubbleConversationCallback != null) {
+ mUnBubbleConversationCallback.accept(bubbleKey);
+ }
+ }
+
+ @Override
+ public void onBackPressed() {
+ hideMenuOrCollapse();
}
});
- mExpandedView.setY(mPositioner.getExpandedViewBottomForBubbleBar() - height);
+
addView(mExpandedView, new FrameLayout.LayoutParams(width, height));
}
@@ -193,6 +210,7 @@
public void collapse() {
mIsExpanded = false;
final BubbleBarExpandedView viewToRemove = mExpandedView;
+ mEducationViewController.hideManageEducation(/* animated = */ true);
mAnimationHelper.animateCollapse(() -> removeView(viewToRemove));
mBubbleController.getSysuiProxy().onStackExpandChanged(false);
mExpandedView = null;
@@ -206,6 +224,17 @@
mUnBubbleConversationCallback = unBubbleConversationCallback;
}
+ /** Hides the current modal education/menu view, expanded view or collapses the bubble stack */
+ private void hideMenuOrCollapse() {
+ if (mEducationViewController.isManageEducationVisible()) {
+ mEducationViewController.hideManageEducation(/* animated = */ true);
+ } else if (isExpanded() && mExpandedView != null) {
+ mExpandedView.hideMenuOrCollapse();
+ } else {
+ mBubbleController.collapseStack();
+ }
+ }
+
/** Updates the expanded view size and position. */
private void updateExpandedView() {
if (mExpandedView == null) return;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuViewController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuViewController.java
index 8be140c..81e7582 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuViewController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuViewController.java
@@ -56,6 +56,11 @@
SpringForce.STIFFNESS_MEDIUM, SpringForce.DAMPING_RATIO_LOW_BOUNCY);
}
+ /** Tells if the menu is visible or being animated */
+ boolean isMenuVisible() {
+ return mMenuView != null && mMenuView.getVisibility() == View.VISIBLE;
+ }
+
/** Sets menu actions listener */
void setListener(@Nullable Listener listener) {
mListener = listener;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleEducationViewController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleEducationViewController.kt
new file mode 100644
index 0000000..7b39c6f
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleEducationViewController.kt
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2023 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.bubbles.bar
+
+import android.content.Context
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.core.view.doOnLayout
+import androidx.dynamicanimation.animation.DynamicAnimation
+import androidx.dynamicanimation.animation.SpringForce
+import com.android.wm.shell.R
+import com.android.wm.shell.animation.PhysicsAnimator
+import com.android.wm.shell.bubbles.BubbleEducationController
+import com.android.wm.shell.bubbles.BubbleViewProvider
+import com.android.wm.shell.bubbles.setup
+import com.android.wm.shell.common.bubbles.BubblePopupView
+
+/** Manages bubble education presentation and animation */
+class BubbleEducationViewController(private val context: Context, private val listener: Listener) {
+ interface Listener {
+ fun onManageEducationVisibilityChanged(isVisible: Boolean)
+ }
+
+ private var rootView: ViewGroup? = null
+ private var educationView: BubblePopupView? = null
+ private var animator: PhysicsAnimator<BubblePopupView>? = null
+
+ private val springConfig by lazy {
+ PhysicsAnimator.SpringConfig(
+ SpringForce.STIFFNESS_MEDIUM,
+ SpringForce.DAMPING_RATIO_LOW_BOUNCY
+ )
+ }
+
+ private val controller by lazy { BubbleEducationController(context) }
+
+ /** Whether the education view is visible or being animated */
+ val isManageEducationVisible: Boolean
+ get() = educationView != null && rootView != null
+
+ /**
+ * Show manage bubble education if hasn't been shown before
+ *
+ * @param bubble the bubble used for the manage education check
+ * @param root the view to show manage education in
+ */
+ fun maybeShowManageEducation(bubble: BubbleViewProvider, root: ViewGroup) {
+ if (!controller.shouldShowManageEducation(bubble)) return
+ showManageEducation(root)
+ }
+
+ /**
+ * Hide the manage education view if visible
+ *
+ * @param animated whether should hide with animation
+ */
+ fun hideManageEducation(animated: Boolean) {
+ rootView?.let {
+ fun cleanUp() {
+ it.removeView(educationView)
+ rootView = null
+ listener.onManageEducationVisibilityChanged(isVisible = false)
+ }
+
+ if (animated) {
+ animateTransition(show = false, ::cleanUp)
+ } else {
+ cleanUp()
+ }
+ }
+ }
+
+ /**
+ * Show manage education with animation
+ *
+ * @param root the view to show manage education in
+ */
+ private fun showManageEducation(root: ViewGroup) {
+ hideManageEducation(animated = false)
+ if (educationView == null) {
+ val eduView = createEducationView(root)
+ educationView = eduView
+ animator = createAnimation(eduView)
+ }
+ root.addView(educationView)
+ rootView = root
+ animateTransition(show = true) {
+ controller.hasSeenManageEducation = true
+ listener.onManageEducationVisibilityChanged(isVisible = true)
+ }
+ }
+
+ /**
+ * Animate show/hide transition for the education view
+ *
+ * @param show whether to show or hide the view
+ * @param endActions a closure to be called when the animation completes
+ */
+ private fun animateTransition(show: Boolean, endActions: () -> Unit) {
+ animator?.let { animator ->
+ animator
+ .spring(DynamicAnimation.ALPHA, if (show) 1f else 0f)
+ .spring(DynamicAnimation.SCALE_X, if (show) 1f else EDU_SCALE_HIDDEN)
+ .spring(DynamicAnimation.SCALE_Y, if (show) 1f else EDU_SCALE_HIDDEN)
+ .withEndActions(endActions)
+ .start()
+ } ?: endActions()
+ }
+
+ private fun createEducationView(root: ViewGroup): BubblePopupView {
+ val view =
+ LayoutInflater.from(context).inflate(R.layout.bubble_bar_manage_education, root, false)
+ as BubblePopupView
+
+ return view.apply {
+ setup()
+ alpha = 0f
+ pivotY = 0f
+ scaleX = EDU_SCALE_HIDDEN
+ scaleY = EDU_SCALE_HIDDEN
+ doOnLayout { it.pivotX = it.width / 2f }
+ setOnClickListener { hideManageEducation(animated = true) }
+ }
+ }
+
+ private fun createAnimation(view: BubblePopupView): PhysicsAnimator<BubblePopupView> {
+ val animator = PhysicsAnimator.getInstance(view)
+ animator.setDefaultSpringConfig(springConfig)
+ return animator
+ }
+
+ companion object {
+ private const val EDU_SCALE_HIDDEN = 0.5f
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubblePopupDrawable.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubblePopupDrawable.kt
new file mode 100644
index 0000000..8b5283d
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubblePopupDrawable.kt
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2023 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.common.bubbles
+
+import android.annotation.ColorInt
+import android.graphics.Canvas
+import android.graphics.ColorFilter
+import android.graphics.Matrix
+import android.graphics.Outline
+import android.graphics.Paint
+import android.graphics.Path
+import android.graphics.Rect
+import android.graphics.RectF
+import android.graphics.drawable.Drawable
+import kotlin.math.atan
+import kotlin.math.cos
+import kotlin.math.sin
+import kotlin.properties.Delegates
+
+/** A drawable for the [BubblePopupView] that draws a popup background with a directional arrow */
+class BubblePopupDrawable(private val config: Config) : Drawable() {
+ /** The direction of the arrow in the popup drawable */
+ enum class ArrowDirection {
+ UP,
+ DOWN
+ }
+
+ /** The arrow position on the side of the popup bubble */
+ sealed class ArrowPosition {
+ object Start : ArrowPosition()
+ object Center : ArrowPosition()
+ object End : ArrowPosition()
+ class Custom(val value: Float) : ArrowPosition()
+ }
+
+ /** The configuration for drawable features */
+ data class Config(
+ @ColorInt val color: Int,
+ val cornerRadius: Float,
+ val contentPadding: Int,
+ val arrowWidth: Float,
+ val arrowHeight: Float,
+ val arrowRadius: Float
+ )
+
+ /**
+ * The direction of the arrow in the popup drawable. It affects the content padding and requires
+ * it to be updated in the view.
+ */
+ var arrowDirection: ArrowDirection by
+ Delegates.observable(ArrowDirection.UP) { _, _, _ -> requestPathUpdate() }
+
+ /**
+ * Arrow position along the X axis and its direction. The position is adjusted to the content
+ * corner radius when applied so it doesn't go into rounded corner area
+ */
+ var arrowPosition: ArrowPosition by
+ Delegates.observable(ArrowPosition.Center) { _, _, _ -> requestPathUpdate() }
+
+ private val path = Path()
+ private val paint = Paint()
+ private var shouldUpdatePath = true
+
+ init {
+ paint.color = config.color
+ paint.style = Paint.Style.FILL
+ paint.isAntiAlias = true
+ }
+
+ override fun draw(canvas: Canvas) {
+ updatePathIfNeeded()
+ canvas.drawPath(path, paint)
+ }
+
+ override fun onBoundsChange(bounds: Rect?) {
+ requestPathUpdate()
+ }
+
+ /** Should be applied to the view padding if arrow direction changes */
+ override fun getPadding(padding: Rect): Boolean {
+ padding.set(
+ config.contentPadding,
+ config.contentPadding,
+ config.contentPadding,
+ config.contentPadding
+ )
+ when (arrowDirection) {
+ ArrowDirection.UP -> padding.top += config.arrowHeight.toInt()
+ ArrowDirection.DOWN -> padding.bottom += config.arrowHeight.toInt()
+ }
+ return true
+ }
+
+ override fun getOutline(outline: Outline) {
+ updatePathIfNeeded()
+ outline.setPath(path)
+ }
+
+ override fun getOpacity(): Int {
+ return paint.alpha
+ }
+
+ override fun setAlpha(alpha: Int) {
+ paint.alpha = alpha
+ }
+
+ override fun setColorFilter(colorFilter: ColorFilter?) {
+ paint.colorFilter = colorFilter
+ }
+
+ /** Schedules path update for the next redraw */
+ private fun requestPathUpdate() {
+ shouldUpdatePath = true
+ }
+
+ /** Updates the path if required, when bounds or arrow direction/position changes */
+ private fun updatePathIfNeeded() {
+ if (shouldUpdatePath) {
+ updatePath()
+ shouldUpdatePath = false
+ }
+ }
+
+ /** Updates the path value using the current bounds, config, arrow direction and position */
+ private fun updatePath() {
+ if (bounds.isEmpty) return
+ // Reset the path state
+ path.reset()
+ // The content rect where the filled rounded rect will be drawn
+ val contentRect = RectF(bounds)
+ when (arrowDirection) {
+ ArrowDirection.UP -> {
+ // Add rounded arrow pointing up to the path
+ addRoundedArrowPositioned(path, arrowPosition)
+ // Inset content rect by the arrow size from the top
+ contentRect.top += config.arrowHeight
+ }
+ ArrowDirection.DOWN -> {
+ val matrix = Matrix()
+ // Flip the path with the matrix to draw arrow pointing down
+ matrix.setScale(1f, -1f, bounds.width() / 2f, bounds.height() / 2f)
+ path.transform(matrix)
+ // Add rounded arrow with the flipped matrix applied, will point down
+ addRoundedArrowPositioned(path, arrowPosition)
+ // Restore the path matrix to the original state with inverted matrix
+ matrix.invert(matrix)
+ path.transform(matrix)
+ // Inset content rect by the arrow size from the bottom
+ contentRect.bottom -= config.arrowHeight
+ }
+ }
+ // Add the content area rounded rect
+ path.addRoundRect(contentRect, config.cornerRadius, config.cornerRadius, Path.Direction.CW)
+ }
+
+ /** Add a rounded arrow pointing up in the horizontal position on the canvas */
+ private fun addRoundedArrowPositioned(path: Path, position: ArrowPosition) {
+ val matrix = Matrix()
+ var translationX = positionValue(position) - config.arrowWidth / 2
+ // Offset to position between rounded corners of the content view
+ translationX = translationX.coerceIn(config.cornerRadius,
+ bounds.width() - config.cornerRadius - config.arrowWidth)
+ // Translate to add the arrow in the center horizontally
+ matrix.setTranslate(-translationX, 0f)
+ path.transform(matrix)
+ // Add rounded arrow
+ addRoundedArrow(path)
+ // Restore the path matrix to the original state with inverted matrix
+ matrix.invert(matrix)
+ path.transform(matrix)
+ }
+
+ /** Adds a rounded arrow pointing up to the path, can be flipped if needed */
+ private fun addRoundedArrow(path: Path) {
+ // Theta is half of the angle inside the triangle tip
+ val thetaTan = config.arrowWidth / (config.arrowHeight * 2f)
+ val theta = atan(thetaTan)
+ val thetaDeg = Math.toDegrees(theta.toDouble()).toFloat()
+ // The center Y value of the circle for the triangle tip
+ val tipCircleCenterY = config.arrowRadius / sin(theta)
+ // The length from triangle tip to intersection point with the circle
+ val tipIntersectionSideLength = config.arrowRadius / thetaTan
+ // The offset from the top to the point of intersection
+ val intersectionTopOffset = tipIntersectionSideLength * cos(theta)
+ // The offset from the center to the point of intersection
+ val intersectionCenterOffset = tipIntersectionSideLength * sin(theta)
+ // The center X of the triangle
+ val arrowCenterX = config.arrowWidth / 2f
+
+ // Set initial position in bottom left of the arrow
+ path.moveTo(0f, config.arrowHeight)
+ // Add the left side of the triangle
+ path.lineTo(arrowCenterX - intersectionCenterOffset, intersectionTopOffset)
+ // Add the arc from the left to the right side of the triangle
+ path.arcTo(
+ /* left = */ arrowCenterX - config.arrowRadius,
+ /* top = */ tipCircleCenterY - config.arrowRadius,
+ /* right = */ arrowCenterX + config.arrowRadius,
+ /* bottom = */ tipCircleCenterY + config.arrowRadius,
+ /* startAngle = */ 180 + thetaDeg,
+ /* sweepAngle = */ 180 - (2 * thetaDeg),
+ /* forceMoveTo = */ false
+ )
+ // Add the right side of the triangle
+ path.lineTo(config.arrowWidth, config.arrowHeight)
+ // Close the path
+ path.close()
+ }
+
+ /** The value of the arrow position provided the position and current bounds */
+ private fun positionValue(position: ArrowPosition): Float {
+ return when (position) {
+ is ArrowPosition.Start -> 0f
+ is ArrowPosition.Center -> bounds.width().toFloat() / 2f
+ is ArrowPosition.End -> bounds.width().toFloat()
+ is ArrowPosition.Custom -> position.value
+ }
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubblePopupView.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubblePopupView.kt
new file mode 100644
index 0000000..f8a4946
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubblePopupView.kt
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2023 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.common.bubbles
+
+import android.content.Context
+import android.graphics.Rect
+import android.util.AttributeSet
+import android.widget.LinearLayout
+
+/** A popup container view that uses [BubblePopupDrawable] as a background */
+open class BubblePopupView
+@JvmOverloads
+constructor(
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = 0,
+ defStyleRes: Int = 0
+) : LinearLayout(context, attrs, defStyleAttr, defStyleRes) {
+ private var popupDrawable: BubblePopupDrawable? = null
+
+ /**
+ * Sets up the popup drawable with the config provided. Required to remove dependency on local
+ * resources
+ */
+ fun setupBackground(config: BubblePopupDrawable.Config) {
+ popupDrawable = BubblePopupDrawable(config)
+ background = popupDrawable
+ forceLayout()
+ }
+
+ /**
+ * Sets the arrow direction for the background drawable and updates the padding to fit the
+ * content inside of the popup drawable
+ */
+ fun setArrowDirection(direction: BubblePopupDrawable.ArrowDirection) {
+ popupDrawable?.let {
+ it.arrowDirection = direction
+ val padding = Rect()
+ if (it.getPadding(padding)) {
+ setPadding(padding.left, padding.top, padding.right, padding.bottom)
+ }
+ }
+ }
+
+ /** Sets the arrow position for the background drawable and triggers redraw */
+ fun setArrowPosition(position: BubblePopupDrawable.ArrowPosition) {
+ popupDrawable?.let {
+ it.arrowPosition = position
+ invalidate()
+ }
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipMediaController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipMediaController.kt
new file mode 100644
index 0000000..2719cd2
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipMediaController.kt
@@ -0,0 +1,365 @@
+/*
+ * Copyright (C) 2023 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.common.pip
+
+import android.annotation.DrawableRes
+import android.annotation.StringRes
+import android.app.PendingIntent
+import android.app.RemoteAction
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import android.graphics.drawable.Icon
+import android.media.MediaMetadata
+import android.media.session.MediaController
+import android.media.session.MediaSession
+import android.media.session.MediaSessionManager
+import android.media.session.PlaybackState
+import android.os.Handler
+import android.os.HandlerExecutor
+import android.os.UserHandle
+import com.android.wm.shell.R
+import com.android.wm.shell.pip.PipUtils
+import java.util.function.Consumer
+
+/**
+ * Interfaces with the [MediaSessionManager] to compose the right set of actions to show (only
+ * if there are no actions from the PiP activity itself). The active media controller is only set
+ * when there is a media session from the top PiP activity.
+ */
+class PipMediaController(private val mContext: Context, private val mMainHandler: Handler) {
+ /**
+ * A listener interface to receive notification on changes to the media actions.
+ */
+ interface ActionListener {
+ /**
+ * Called when the media actions changed.
+ */
+ fun onMediaActionsChanged(actions: List<RemoteAction?>?)
+ }
+
+ /**
+ * A listener interface to receive notification on changes to the media metadata.
+ */
+ interface MetadataListener {
+ /**
+ * Called when the media metadata changed.
+ */
+ fun onMediaMetadataChanged(metadata: MediaMetadata?)
+ }
+
+ /**
+ * A listener interface to receive notification on changes to the media session token.
+ */
+ interface TokenListener {
+ /**
+ * Called when the media session token changed.
+ */
+ fun onMediaSessionTokenChanged(token: MediaSession.Token?)
+ }
+
+ private val mHandlerExecutor: HandlerExecutor = HandlerExecutor(mMainHandler)
+ private val mMediaSessionManager: MediaSessionManager?
+ private var mMediaController: MediaController? = null
+ private val mPauseAction: RemoteAction
+ private val mPlayAction: RemoteAction
+ private val mNextAction: RemoteAction
+ private val mPrevAction: RemoteAction
+ private val mMediaActionReceiver: BroadcastReceiver = object : BroadcastReceiver() {
+ override fun onReceive(context: Context, intent: Intent) {
+ if (mMediaController == null) {
+ // no active media session, bail early.
+ return
+ }
+ when (intent.action) {
+ ACTION_PLAY -> mMediaController!!.transportControls.play()
+ ACTION_PAUSE -> mMediaController!!.transportControls.pause()
+ ACTION_NEXT -> mMediaController!!.transportControls.skipToNext()
+ ACTION_PREV -> mMediaController!!.transportControls.skipToPrevious()
+ }
+ }
+ }
+ private val mPlaybackChangedListener: MediaController.Callback =
+ object : MediaController.Callback() {
+ override fun onPlaybackStateChanged(state: PlaybackState?) {
+ notifyActionsChanged()
+ }
+
+ override fun onMetadataChanged(metadata: MediaMetadata?) {
+ notifyMetadataChanged(metadata)
+ }
+ }
+ private val mSessionsChangedListener =
+ MediaSessionManager.OnActiveSessionsChangedListener { controllers: List<MediaController>? ->
+ resolveActiveMediaController(controllers)
+ }
+ private val mActionListeners = ArrayList<ActionListener>()
+ private val mMetadataListeners = ArrayList<MetadataListener>()
+ private val mTokenListeners = ArrayList<TokenListener>()
+
+ init {
+ val mediaControlFilter = IntentFilter()
+ mediaControlFilter.addAction(ACTION_PLAY)
+ mediaControlFilter.addAction(ACTION_PAUSE)
+ mediaControlFilter.addAction(ACTION_NEXT)
+ mediaControlFilter.addAction(ACTION_PREV)
+ mContext.registerReceiverForAllUsers(
+ mMediaActionReceiver, mediaControlFilter,
+ SYSTEMUI_PERMISSION, mMainHandler, Context.RECEIVER_EXPORTED
+ )
+
+ // Creates the standard media buttons that we may show.
+ mPauseAction = getDefaultRemoteAction(
+ R.string.pip_pause,
+ R.drawable.pip_ic_pause_white, ACTION_PAUSE
+ )
+ mPlayAction = getDefaultRemoteAction(
+ R.string.pip_play,
+ R.drawable.pip_ic_play_arrow_white, ACTION_PLAY
+ )
+ mNextAction = getDefaultRemoteAction(
+ R.string.pip_skip_to_next,
+ R.drawable.pip_ic_skip_next_white, ACTION_NEXT
+ )
+ mPrevAction = getDefaultRemoteAction(
+ R.string.pip_skip_to_prev,
+ R.drawable.pip_ic_skip_previous_white, ACTION_PREV
+ )
+ mMediaSessionManager = mContext.getSystemService(
+ MediaSessionManager::class.java
+ )
+ }
+
+ /**
+ * Handles when an activity is pinned.
+ */
+ fun onActivityPinned() {
+ // Once we enter PiP, try to find the active media controller for the top most activity
+ resolveActiveMediaController(
+ mMediaSessionManager!!.getActiveSessionsForUser(
+ null,
+ UserHandle.CURRENT
+ )
+ )
+ }
+
+ /**
+ * Adds a new media action listener.
+ */
+ fun addActionListener(listener: ActionListener) {
+ if (!mActionListeners.contains(listener)) {
+ mActionListeners.add(listener)
+ listener.onMediaActionsChanged(mediaActions)
+ }
+ }
+
+ /**
+ * Removes a media action listener.
+ */
+ fun removeActionListener(listener: ActionListener) {
+ listener.onMediaActionsChanged(emptyList<RemoteAction>())
+ mActionListeners.remove(listener)
+ }
+
+ /**
+ * Adds a new media metadata listener.
+ */
+ fun addMetadataListener(listener: MetadataListener) {
+ if (!mMetadataListeners.contains(listener)) {
+ mMetadataListeners.add(listener)
+ listener.onMediaMetadataChanged(mediaMetadata)
+ }
+ }
+
+ /**
+ * Removes a media metadata listener.
+ */
+ fun removeMetadataListener(listener: MetadataListener) {
+ listener.onMediaMetadataChanged(null)
+ mMetadataListeners.remove(listener)
+ }
+
+ /**
+ * Adds a new token listener.
+ */
+ fun addTokenListener(listener: TokenListener) {
+ if (!mTokenListeners.contains(listener)) {
+ mTokenListeners.add(listener)
+ listener.onMediaSessionTokenChanged(token)
+ }
+ }
+
+ /**
+ * Removes a token listener.
+ */
+ fun removeTokenListener(listener: TokenListener) {
+ listener.onMediaSessionTokenChanged(null)
+ mTokenListeners.remove(listener)
+ }
+
+ private val token: MediaSession.Token?
+ get() = if (mMediaController == null) {
+ null
+ } else mMediaController!!.sessionToken
+ private val mediaMetadata: MediaMetadata?
+ get() = if (mMediaController != null) mMediaController!!.metadata else null
+
+ private val mediaActions: List<RemoteAction?>
+ /**
+ * Gets the set of media actions currently available.
+ */
+ get() {
+ if (mMediaController == null) {
+ return emptyList<RemoteAction>()
+ }
+ // Cache the PlaybackState since it's a Binder call.
+ // Safe because mMediaController is guaranteed non-null here.
+ val playbackState: PlaybackState = mMediaController!!.playbackState
+ ?: return emptyList<RemoteAction>()
+ val mediaActions = ArrayList<RemoteAction?>()
+ val isPlaying = playbackState.isActive
+ val actions = playbackState.actions
+
+ // Prev action
+ mPrevAction.isEnabled =
+ actions and PlaybackState.ACTION_SKIP_TO_PREVIOUS != 0L
+ mediaActions.add(mPrevAction)
+
+ // Play/pause action
+ if (!isPlaying && actions and PlaybackState.ACTION_PLAY != 0L) {
+ mediaActions.add(mPlayAction)
+ } else if (isPlaying && actions and PlaybackState.ACTION_PAUSE != 0L) {
+ mediaActions.add(mPauseAction)
+ }
+
+ // Next action
+ mNextAction.isEnabled =
+ actions and PlaybackState.ACTION_SKIP_TO_NEXT != 0L
+ mediaActions.add(mNextAction)
+ return mediaActions
+ }
+
+ /** @return Default [RemoteAction] sends broadcast back to SysUI.
+ */
+ private fun getDefaultRemoteAction(
+ @StringRes titleAndDescription: Int,
+ @DrawableRes icon: Int,
+ action: String
+ ): RemoteAction {
+ val titleAndDescriptionStr = mContext.getString(titleAndDescription)
+ val intent = Intent(action)
+ intent.setPackage(mContext.packageName)
+ return RemoteAction(
+ Icon.createWithResource(mContext, icon),
+ titleAndDescriptionStr, titleAndDescriptionStr,
+ PendingIntent.getBroadcast(
+ mContext, 0 /* requestCode */, intent,
+ PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
+ )
+ )
+ }
+
+ /**
+ * Re-registers the session listener for the current user.
+ */
+ fun registerSessionListenerForCurrentUser() {
+ mMediaSessionManager!!.removeOnActiveSessionsChangedListener(mSessionsChangedListener)
+ mMediaSessionManager.addOnActiveSessionsChangedListener(
+ null, UserHandle.CURRENT,
+ mHandlerExecutor, mSessionsChangedListener
+ )
+ }
+
+ /**
+ * Tries to find and set the active media controller for the top PiP activity.
+ */
+ private fun resolveActiveMediaController(controllers: List<MediaController>?) {
+ if (controllers != null) {
+ val topActivity = PipUtils.getTopPipActivity(mContext).first
+ if (topActivity != null) {
+ for (i in controllers.indices) {
+ val controller = controllers[i]
+ if (controller.packageName == topActivity.packageName) {
+ setActiveMediaController(controller)
+ return
+ }
+ }
+ }
+ }
+ setActiveMediaController(null)
+ }
+
+ /**
+ * Sets the active media controller for the top PiP activity.
+ */
+ private fun setActiveMediaController(controller: MediaController?) {
+ if (controller != mMediaController) {
+ if (mMediaController != null) {
+ mMediaController!!.unregisterCallback(mPlaybackChangedListener)
+ }
+ mMediaController = controller
+ controller?.registerCallback(mPlaybackChangedListener, mMainHandler)
+ notifyActionsChanged()
+ notifyMetadataChanged(mediaMetadata)
+ notifyTokenChanged(token)
+
+ // TODO(winsonc): Consider if we want to close the PIP after a timeout (like on TV)
+ }
+ }
+
+ /**
+ * Notifies all listeners that the actions have changed.
+ */
+ private fun notifyActionsChanged() {
+ if (mActionListeners.isNotEmpty()) {
+ val actions = mediaActions
+ mActionListeners.forEach(
+ Consumer { l: ActionListener -> l.onMediaActionsChanged(actions) })
+ }
+ }
+
+ /**
+ * Notifies all listeners that the metadata have changed.
+ */
+ private fun notifyMetadataChanged(metadata: MediaMetadata?) {
+ if (mMetadataListeners.isNotEmpty()) {
+ mMetadataListeners.forEach(Consumer { l: MetadataListener ->
+ l.onMediaMetadataChanged(
+ metadata
+ )
+ })
+ }
+ }
+
+ private fun notifyTokenChanged(token: MediaSession.Token?) {
+ if (mTokenListeners.isNotEmpty()) {
+ mTokenListeners.forEach(Consumer { l: TokenListener ->
+ l.onMediaSessionTokenChanged(
+ token
+ )
+ })
+ }
+ }
+
+ companion object {
+ private const val SYSTEMUI_PERMISSION = "com.android.systemui.permission.SELF"
+ private const val ACTION_PLAY = "com.android.wm.shell.pip.PLAY"
+ private const val ACTION_PAUSE = "com.android.wm.shell.pip.PAUSE"
+ private const val ACTION_NEXT = "com.android.wm.shell.pip.NEXT"
+ private const val ACTION_PREV = "com.android.wm.shell.pip.PREV"
+ }
+}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipUiEventLogger.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipUiEventLogger.kt
new file mode 100644
index 0000000..642dacc
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipUiEventLogger.kt
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2023 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.common.pip
+
+import android.app.TaskInfo
+import android.content.pm.PackageManager
+import com.android.internal.logging.UiEvent
+import com.android.internal.logging.UiEventLogger
+
+/**
+ * Helper class that ends PiP log to UiEvent, see also go/uievent
+ */
+class PipUiEventLogger(
+ private val mUiEventLogger: UiEventLogger,
+ private val mPackageManager: PackageManager
+) {
+ private var mPackageName: String? = null
+ private var mPackageUid = INVALID_PACKAGE_UID
+ fun setTaskInfo(taskInfo: TaskInfo?) {
+ if (taskInfo?.topActivity != null) {
+ // safe because topActivity is guaranteed non-null here
+ mPackageName = taskInfo.topActivity!!.packageName
+ mPackageUid = getUid(mPackageName!!, taskInfo.userId)
+ } else {
+ mPackageName = null
+ mPackageUid = INVALID_PACKAGE_UID
+ }
+ }
+
+ /**
+ * Sends log via UiEvent, reference go/uievent for how to debug locally
+ */
+ fun log(event: PipUiEventEnum?) {
+ if (mPackageName == null || mPackageUid == INVALID_PACKAGE_UID) {
+ return
+ }
+ mUiEventLogger.log(event!!, mPackageUid, mPackageName)
+ }
+
+ private fun getUid(packageName: String, userId: Int): Int {
+ var uid = INVALID_PACKAGE_UID
+ try {
+ uid = mPackageManager.getApplicationInfoAsUser(
+ packageName, 0 /* ApplicationInfoFlags */, userId
+ ).uid
+ } catch (e: PackageManager.NameNotFoundException) {
+ // do nothing.
+ }
+ return uid
+ }
+
+ /**
+ * Enums for logging the PiP events to UiEvent
+ */
+ enum class PipUiEventEnum(private val mId: Int) : UiEventLogger.UiEventEnum {
+ @UiEvent(doc = "Activity enters picture-in-picture mode")
+ PICTURE_IN_PICTURE_ENTER(603),
+
+ @UiEvent(doc = "Activity enters picture-in-picture mode with auto-enter-pip API")
+ PICTURE_IN_PICTURE_AUTO_ENTER(1313),
+
+ @UiEvent(doc = "Activity enters picture-in-picture mode from content-pip API")
+ PICTURE_IN_PICTURE_ENTER_CONTENT_PIP(1314),
+
+ @UiEvent(doc = "Expands from picture-in-picture to fullscreen")
+ PICTURE_IN_PICTURE_EXPAND_TO_FULLSCREEN(604),
+
+ @UiEvent(doc = "Removes picture-in-picture by tap close button")
+ PICTURE_IN_PICTURE_TAP_TO_REMOVE(605),
+
+ @UiEvent(doc = "Removes picture-in-picture by drag to dismiss area")
+ PICTURE_IN_PICTURE_DRAG_TO_REMOVE(606),
+
+ @UiEvent(doc = "Shows picture-in-picture menu")
+ PICTURE_IN_PICTURE_SHOW_MENU(607),
+
+ @UiEvent(doc = "Hides picture-in-picture menu")
+ PICTURE_IN_PICTURE_HIDE_MENU(608),
+
+ @UiEvent(
+ doc = "Changes the aspect ratio of picture-in-picture window. This is inherited" +
+ " from previous Tron-based logging and currently not in use."
+ )
+ PICTURE_IN_PICTURE_CHANGE_ASPECT_RATIO(609),
+
+ @UiEvent(doc = "User resize of the picture-in-picture window")
+ PICTURE_IN_PICTURE_RESIZE(610),
+
+ @UiEvent(doc = "User unstashed picture-in-picture")
+ PICTURE_IN_PICTURE_STASH_UNSTASHED(709),
+
+ @UiEvent(doc = "User stashed picture-in-picture to the left side")
+ PICTURE_IN_PICTURE_STASH_LEFT(710),
+
+ @UiEvent(doc = "User stashed picture-in-picture to the right side")
+ PICTURE_IN_PICTURE_STASH_RIGHT(711),
+
+ @UiEvent(doc = "User taps on the settings button in PiP menu")
+ PICTURE_IN_PICTURE_SHOW_SETTINGS(933),
+
+ @UiEvent(doc = "Closes PiP with app-provided close action")
+ PICTURE_IN_PICTURE_CUSTOM_CLOSE(1058);
+
+ override fun getId(): Int {
+ return mId
+ }
+ }
+
+ companion object {
+ private const val INVALID_PACKAGE_UID = -1
+ }
+}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenConstants.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenConstants.java
index ef93a33..be1b9b1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenConstants.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenConstants.java
@@ -16,6 +16,7 @@
package com.android.wm.shell.common.split;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
@@ -60,7 +61,8 @@
public static final int[] CONTROLLED_WINDOWING_MODES =
{WINDOWING_MODE_FULLSCREEN, WINDOWING_MODE_UNDEFINED};
public static final int[] CONTROLLED_WINDOWING_MODES_WHEN_ACTIVE =
- {WINDOWING_MODE_FULLSCREEN, WINDOWING_MODE_UNDEFINED, WINDOWING_MODE_MULTI_WINDOW};
+ {WINDOWING_MODE_FULLSCREEN, WINDOWING_MODE_UNDEFINED, WINDOWING_MODE_MULTI_WINDOW,
+ WINDOWING_MODE_FREEFORM};
/** Flag applied to a transition change to identify it as a divider bar for animation. */
public static final int FLAG_IS_DIVIDER_BAR = FLAG_FIRST_CUSTOM;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java
index 54f8984..7bf0893 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java
@@ -230,8 +230,10 @@
// The user aspect ratio button should not be handled when a new TaskInfo is
// sent because of a double tap or when in multi-window mode.
if (taskInfo.getWindowingMode() != WINDOWING_MODE_FULLSCREEN) {
- mUserAspectRatioSettingsLayout.release();
- mUserAspectRatioSettingsLayout = null;
+ if (mUserAspectRatioSettingsLayout != null) {
+ mUserAspectRatioSettingsLayout.release();
+ mUserAspectRatioSettingsLayout = null;
+ }
return;
}
if (!taskInfo.isFromLetterboxDoubleTap) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
index 1a84f4b..aafd9fd 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
@@ -20,6 +20,7 @@
import android.app.ActivityTaskManager;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.os.Handler;
import android.os.SystemProperties;
import android.view.IWindowManager;
@@ -56,6 +57,8 @@
import com.android.wm.shell.common.annotations.ShellBackgroundThread;
import com.android.wm.shell.common.annotations.ShellMainThread;
import com.android.wm.shell.common.annotations.ShellSplashscreenThread;
+import com.android.wm.shell.common.pip.PipMediaController;
+import com.android.wm.shell.common.pip.PipUiEventLogger;
import com.android.wm.shell.compatui.CompatUIConfiguration;
import com.android.wm.shell.compatui.CompatUIController;
import com.android.wm.shell.compatui.CompatUIShellCommandHandler;
@@ -319,6 +322,24 @@
return Optional.empty();
}
+ //
+ // PiP (optional feature)
+ //
+
+ @WMSingleton
+ @Provides
+ static PipUiEventLogger providePipUiEventLogger(UiEventLogger uiEventLogger,
+ PackageManager packageManager) {
+ return new PipUiEventLogger(uiEventLogger, packageManager);
+ }
+
+ @WMSingleton
+ @Provides
+ static PipMediaController providePipMediaController(Context context,
+ @ShellMainThread Handler mainHandler) {
+ return new PipMediaController(context, mainHandler);
+ }
+
//
// Bubbles (optional feature)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip1Module.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip1Module.java
index 9bf973f..24ef44a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip1Module.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip1Module.java
@@ -32,6 +32,8 @@
import com.android.wm.shell.common.annotations.ShellMainThread;
import com.android.wm.shell.common.pip.PhoneSizeSpecSource;
import com.android.wm.shell.common.pip.PipAppOpsListener;
+import com.android.wm.shell.common.pip.PipMediaController;
+import com.android.wm.shell.common.pip.PipUiEventLogger;
import com.android.wm.shell.common.pip.SizeSpecSource;
import com.android.wm.shell.dagger.WMShellBaseModule;
import com.android.wm.shell.dagger.WMSingleton;
@@ -41,7 +43,6 @@
import com.android.wm.shell.pip.PipBoundsAlgorithm;
import com.android.wm.shell.pip.PipBoundsState;
import com.android.wm.shell.pip.PipDisplayLayoutState;
-import com.android.wm.shell.pip.PipMediaController;
import com.android.wm.shell.pip.PipParamsChangedForwarder;
import com.android.wm.shell.pip.PipSnapAlgorithm;
import com.android.wm.shell.pip.PipSurfaceTransactionHelper;
@@ -49,7 +50,6 @@
import com.android.wm.shell.pip.PipTransition;
import com.android.wm.shell.pip.PipTransitionController;
import com.android.wm.shell.pip.PipTransitionState;
-import com.android.wm.shell.pip.PipUiEventLogger;
import com.android.wm.shell.pip.PipUtils;
import com.android.wm.shell.pip.phone.PhonePipKeepClearAlgorithm;
import com.android.wm.shell.pip.phone.PhonePipMenuController;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip1SharedModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip1SharedModule.java
index e8fae24..c4ca501 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip1SharedModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip1SharedModule.java
@@ -17,15 +17,9 @@
package com.android.wm.shell.dagger.pip;
import android.content.Context;
-import android.content.pm.PackageManager;
-import android.os.Handler;
-import com.android.internal.logging.UiEventLogger;
-import com.android.wm.shell.common.annotations.ShellMainThread;
import com.android.wm.shell.dagger.WMSingleton;
-import com.android.wm.shell.pip.PipMediaController;
import com.android.wm.shell.pip.PipSurfaceTransactionHelper;
-import com.android.wm.shell.pip.PipUiEventLogger;
import dagger.Module;
import dagger.Provides;
@@ -36,24 +30,9 @@
*/
@Module
public abstract class Pip1SharedModule {
- // Needs handler for registering broadcast receivers
- @WMSingleton
- @Provides
- static PipMediaController providePipMediaController(Context context,
- @ShellMainThread Handler mainHandler) {
- return new PipMediaController(context, mainHandler);
- }
-
@WMSingleton
@Provides
static PipSurfaceTransactionHelper providePipSurfaceTransactionHelper(Context context) {
return new PipSurfaceTransactionHelper(context);
}
-
- @WMSingleton
- @Provides
- static PipUiEventLogger providePipUiEventLogger(UiEventLogger uiEventLogger,
- PackageManager packageManager) {
- return new PipUiEventLogger(uiEventLogger, packageManager);
- }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java
index c7c6e8a..8dec4ea 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java
@@ -18,6 +18,7 @@
import android.annotation.Nullable;
+import com.android.wm.shell.dagger.WMShellBaseModule;
import com.android.wm.shell.dagger.WMSingleton;
import com.android.wm.shell.pip2.PipTransition;
@@ -26,9 +27,9 @@
/**
* Provides dependencies from {@link com.android.wm.shell.pip2}, this implementation is meant to be
- * the successor of its sibling {@link Pip1SharedModule}.
+ * the successor of its sibling {@link Pip1Module}.
*/
-@Module
+@Module(includes = WMShellBaseModule.class)
public abstract class Pip2Module {
@WMSingleton
@Provides
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/TvPipModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/TvPipModule.java
index 80ffbb0..a6ff9ec 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/TvPipModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/TvPipModule.java
@@ -30,20 +30,20 @@
import com.android.wm.shell.common.annotations.ShellMainThread;
import com.android.wm.shell.common.pip.LegacySizeSpecSource;
import com.android.wm.shell.common.pip.PipAppOpsListener;
+import com.android.wm.shell.common.pip.PipMediaController;
+import com.android.wm.shell.common.pip.PipUiEventLogger;
import com.android.wm.shell.common.pip.SizeSpecSource;
import com.android.wm.shell.dagger.WMShellBaseModule;
import com.android.wm.shell.dagger.WMSingleton;
import com.android.wm.shell.pip.Pip;
import com.android.wm.shell.pip.PipAnimationController;
import com.android.wm.shell.pip.PipDisplayLayoutState;
-import com.android.wm.shell.pip.PipMediaController;
import com.android.wm.shell.pip.PipParamsChangedForwarder;
import com.android.wm.shell.pip.PipSnapAlgorithm;
import com.android.wm.shell.pip.PipSurfaceTransactionHelper;
import com.android.wm.shell.pip.PipTaskOrganizer;
import com.android.wm.shell.pip.PipTransitionController;
import com.android.wm.shell.pip.PipTransitionState;
-import com.android.wm.shell.pip.PipUiEventLogger;
import com.android.wm.shell.pip.tv.TvPipBoundsAlgorithm;
import com.android.wm.shell.pip.tv.TvPipBoundsController;
import com.android.wm.shell.pip.tv.TvPipBoundsState;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
index 1d46e75..633f627 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
@@ -18,6 +18,7 @@
import android.R
import android.app.ActivityManager.RunningTaskInfo
+import android.app.WindowConfiguration
import android.app.WindowConfiguration.ACTIVITY_TYPE_HOME
import android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD
import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM
@@ -301,6 +302,24 @@
}
}
+ /** Move a desktop app to split screen. */
+ fun moveToSplit(task: RunningTaskInfo) {
+ KtProtoLog.v(
+ WM_SHELL_DESKTOP_MODE,
+ "DesktopTasksController: moveToSplit taskId=%d",
+ task.taskId
+ )
+ val wct = WindowContainerTransaction()
+ wct.setWindowingMode(task.token, WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW)
+ wct.setBounds(task.token, null)
+ wct.setDensityDpi(task.token, getDefaultDensityDpi())
+ if (Transitions.ENABLE_SHELL_TRANSITIONS) {
+ transitions.startTransition(TRANSIT_CHANGE, wct, null /* handler */)
+ } else {
+ shellTaskOrganizer.applyTransaction(wct)
+ }
+ }
+
/**
* The second part of the animated move to desktop transition, called after
* {@link startMoveToDesktop}. Move a task to fullscreen after being dragged from fullscreen
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMediaController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMediaController.java
deleted file mode 100644
index ddffb5b..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMediaController.java
+++ /dev/null
@@ -1,369 +0,0 @@
-/*
- * 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.pip;
-
-import static android.app.PendingIntent.FLAG_IMMUTABLE;
-import static android.app.PendingIntent.FLAG_UPDATE_CURRENT;
-
-import android.annotation.DrawableRes;
-import android.annotation.StringRes;
-import android.annotation.SuppressLint;
-import android.app.PendingIntent;
-import android.app.RemoteAction;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.graphics.drawable.Icon;
-import android.media.MediaMetadata;
-import android.media.session.MediaController;
-import android.media.session.MediaSession;
-import android.media.session.MediaSessionManager;
-import android.media.session.PlaybackState;
-import android.os.Handler;
-import android.os.HandlerExecutor;
-import android.os.UserHandle;
-
-import androidx.annotation.Nullable;
-
-import com.android.wm.shell.R;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Interfaces with the {@link MediaSessionManager} to compose the right set of actions to show (only
- * if there are no actions from the PiP activity itself). The active media controller is only set
- * when there is a media session from the top PiP activity.
- */
-public class PipMediaController {
- private static final String SYSTEMUI_PERMISSION = "com.android.systemui.permission.SELF";
-
- private static final String ACTION_PLAY = "com.android.wm.shell.pip.PLAY";
- private static final String ACTION_PAUSE = "com.android.wm.shell.pip.PAUSE";
- private static final String ACTION_NEXT = "com.android.wm.shell.pip.NEXT";
- private static final String ACTION_PREV = "com.android.wm.shell.pip.PREV";
-
- /**
- * A listener interface to receive notification on changes to the media actions.
- */
- public interface ActionListener {
- /**
- * Called when the media actions changed.
- */
- void onMediaActionsChanged(List<RemoteAction> actions);
- }
-
- /**
- * A listener interface to receive notification on changes to the media metadata.
- */
- public interface MetadataListener {
- /**
- * Called when the media metadata changed.
- */
- void onMediaMetadataChanged(MediaMetadata metadata);
- }
-
- /**
- * A listener interface to receive notification on changes to the media session token.
- */
- public interface TokenListener {
- /**
- * Called when the media session token changed.
- */
- void onMediaSessionTokenChanged(MediaSession.Token token);
- }
-
- private final Context mContext;
- private final Handler mMainHandler;
- private final HandlerExecutor mHandlerExecutor;
-
- private final MediaSessionManager mMediaSessionManager;
- private MediaController mMediaController;
-
- private RemoteAction mPauseAction;
- private RemoteAction mPlayAction;
- private RemoteAction mNextAction;
- private RemoteAction mPrevAction;
-
- private final BroadcastReceiver mMediaActionReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (mMediaController == null || mMediaController.getTransportControls() == null) {
- // no active media session, bail early.
- return;
- }
- switch (intent.getAction()) {
- case ACTION_PLAY:
- mMediaController.getTransportControls().play();
- break;
- case ACTION_PAUSE:
- mMediaController.getTransportControls().pause();
- break;
- case ACTION_NEXT:
- mMediaController.getTransportControls().skipToNext();
- break;
- case ACTION_PREV:
- mMediaController.getTransportControls().skipToPrevious();
- break;
- }
- }
- };
-
- private final MediaController.Callback mPlaybackChangedListener =
- new MediaController.Callback() {
- @Override
- public void onPlaybackStateChanged(PlaybackState state) {
- notifyActionsChanged();
- }
-
- @Override
- public void onMetadataChanged(@Nullable MediaMetadata metadata) {
- notifyMetadataChanged(metadata);
- }
- };
-
- private final MediaSessionManager.OnActiveSessionsChangedListener mSessionsChangedListener =
- this::resolveActiveMediaController;
-
- private final ArrayList<ActionListener> mActionListeners = new ArrayList<>();
- private final ArrayList<MetadataListener> mMetadataListeners = new ArrayList<>();
- private final ArrayList<TokenListener> mTokenListeners = new ArrayList<>();
-
- public PipMediaController(Context context, Handler mainHandler) {
- mContext = context;
- mMainHandler = mainHandler;
- mHandlerExecutor = new HandlerExecutor(mMainHandler);
- if (!PipUtils.isPip2ExperimentEnabled()) {
- IntentFilter mediaControlFilter = new IntentFilter();
- mediaControlFilter.addAction(ACTION_PLAY);
- mediaControlFilter.addAction(ACTION_PAUSE);
- mediaControlFilter.addAction(ACTION_NEXT);
- mediaControlFilter.addAction(ACTION_PREV);
- mContext.registerReceiverForAllUsers(mMediaActionReceiver, mediaControlFilter,
- SYSTEMUI_PERMISSION, mainHandler, Context.RECEIVER_EXPORTED);
- }
-
- // Creates the standard media buttons that we may show.
- mPauseAction = getDefaultRemoteAction(R.string.pip_pause,
- R.drawable.pip_ic_pause_white, ACTION_PAUSE);
- mPlayAction = getDefaultRemoteAction(R.string.pip_play,
- R.drawable.pip_ic_play_arrow_white, ACTION_PLAY);
- mNextAction = getDefaultRemoteAction(R.string.pip_skip_to_next,
- R.drawable.pip_ic_skip_next_white, ACTION_NEXT);
- mPrevAction = getDefaultRemoteAction(R.string.pip_skip_to_prev,
- R.drawable.pip_ic_skip_previous_white, ACTION_PREV);
-
- mMediaSessionManager = context.getSystemService(MediaSessionManager.class);
- }
-
- /**
- * Handles when an activity is pinned.
- */
- public void onActivityPinned() {
- // Once we enter PiP, try to find the active media controller for the top most activity
- resolveActiveMediaController(mMediaSessionManager.getActiveSessionsForUser(null,
- UserHandle.CURRENT));
- }
-
- /**
- * Adds a new media action listener.
- */
- public void addActionListener(ActionListener listener) {
- if (!mActionListeners.contains(listener)) {
- mActionListeners.add(listener);
- listener.onMediaActionsChanged(getMediaActions());
- }
- }
-
- /**
- * Removes a media action listener.
- */
- public void removeActionListener(ActionListener listener) {
- listener.onMediaActionsChanged(Collections.emptyList());
- mActionListeners.remove(listener);
- }
-
- /**
- * Adds a new media metadata listener.
- */
- public void addMetadataListener(MetadataListener listener) {
- if (!mMetadataListeners.contains(listener)) {
- mMetadataListeners.add(listener);
- listener.onMediaMetadataChanged(getMediaMetadata());
- }
- }
-
- /**
- * Removes a media metadata listener.
- */
- public void removeMetadataListener(MetadataListener listener) {
- listener.onMediaMetadataChanged(null);
- mMetadataListeners.remove(listener);
- }
-
- /**
- * Adds a new token listener.
- */
- public void addTokenListener(TokenListener listener) {
- if (!mTokenListeners.contains(listener)) {
- mTokenListeners.add(listener);
- listener.onMediaSessionTokenChanged(getToken());
- }
- }
-
- /**
- * Removes a token listener.
- */
- public void removeTokenListener(TokenListener listener) {
- listener.onMediaSessionTokenChanged(null);
- mTokenListeners.remove(listener);
- }
-
- private MediaSession.Token getToken() {
- if (mMediaController == null) {
- return null;
- }
- return mMediaController.getSessionToken();
- }
-
- private MediaMetadata getMediaMetadata() {
- return mMediaController != null ? mMediaController.getMetadata() : null;
- }
-
- /**
- * Gets the set of media actions currently available.
- */
- // This is due to using PlaybackState#isActive, which is added in API 31.
- // It can be removed when min_sdk of the app is set to 31 or greater.
- @SuppressLint("NewApi")
- private List<RemoteAction> getMediaActions() {
- // Cache the PlaybackState since it's a Binder call.
- final PlaybackState playbackState;
- if (mMediaController == null
- || (playbackState = mMediaController.getPlaybackState()) == null) {
- return Collections.emptyList();
- }
-
- ArrayList<RemoteAction> mediaActions = new ArrayList<>();
- boolean isPlaying = playbackState.isActive();
- long actions = playbackState.getActions();
-
- // Prev action
- mPrevAction.setEnabled((actions & PlaybackState.ACTION_SKIP_TO_PREVIOUS) != 0);
- mediaActions.add(mPrevAction);
-
- // Play/pause action
- if (!isPlaying && ((actions & PlaybackState.ACTION_PLAY) != 0)) {
- mediaActions.add(mPlayAction);
- } else if (isPlaying && ((actions & PlaybackState.ACTION_PAUSE) != 0)) {
- mediaActions.add(mPauseAction);
- }
-
- // Next action
- mNextAction.setEnabled((actions & PlaybackState.ACTION_SKIP_TO_NEXT) != 0);
- mediaActions.add(mNextAction);
- return mediaActions;
- }
-
- /** @return Default {@link RemoteAction} sends broadcast back to SysUI. */
- private RemoteAction getDefaultRemoteAction(@StringRes int titleAndDescription,
- @DrawableRes int icon, String action) {
- final String titleAndDescriptionStr = mContext.getString(titleAndDescription);
- final Intent intent = new Intent(action);
- intent.setPackage(mContext.getPackageName());
- return new RemoteAction(Icon.createWithResource(mContext, icon),
- titleAndDescriptionStr, titleAndDescriptionStr,
- PendingIntent.getBroadcast(mContext, 0 /* requestCode */, intent,
- FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE));
- }
-
- /**
- * Re-registers the session listener for the current user.
- */
- public void registerSessionListenerForCurrentUser() {
- mMediaSessionManager.removeOnActiveSessionsChangedListener(mSessionsChangedListener);
- mMediaSessionManager.addOnActiveSessionsChangedListener(null, UserHandle.CURRENT,
- mHandlerExecutor, mSessionsChangedListener);
- }
-
- /**
- * Tries to find and set the active media controller for the top PiP activity.
- */
- private void resolveActiveMediaController(List<MediaController> controllers) {
- if (controllers != null) {
- final ComponentName topActivity = PipUtils.getTopPipActivity(mContext).first;
- if (topActivity != null) {
- for (int i = 0; i < controllers.size(); i++) {
- final MediaController controller = controllers.get(i);
- if (controller.getPackageName().equals(topActivity.getPackageName())) {
- setActiveMediaController(controller);
- return;
- }
- }
- }
- }
- setActiveMediaController(null);
- }
-
- /**
- * Sets the active media controller for the top PiP activity.
- */
- private void setActiveMediaController(MediaController controller) {
- if (controller != mMediaController) {
- if (mMediaController != null) {
- mMediaController.unregisterCallback(mPlaybackChangedListener);
- }
- mMediaController = controller;
- if (controller != null) {
- controller.registerCallback(mPlaybackChangedListener, mMainHandler);
- }
- notifyActionsChanged();
- notifyMetadataChanged(getMediaMetadata());
- notifyTokenChanged(getToken());
-
- // TODO(winsonc): Consider if we want to close the PIP after a timeout (like on TV)
- }
- }
-
- /**
- * Notifies all listeners that the actions have changed.
- */
- private void notifyActionsChanged() {
- if (!mActionListeners.isEmpty()) {
- List<RemoteAction> actions = getMediaActions();
- mActionListeners.forEach(l -> l.onMediaActionsChanged(actions));
- }
- }
-
- /**
- * Notifies all listeners that the metadata have changed.
- */
- private void notifyMetadataChanged(MediaMetadata metadata) {
- if (!mMetadataListeners.isEmpty()) {
- mMetadataListeners.forEach(l -> l.onMediaMetadataChanged(metadata));
- }
- }
-
- private void notifyTokenChanged(MediaSession.Token token) {
- if (!mTokenListeners.isEmpty()) {
- mTokenListeners.forEach(l -> l.onMediaSessionTokenChanged(token));
- }
- }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
index 19c60c2..296857b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
@@ -82,6 +82,7 @@
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.common.annotations.ShellMainThread;
+import com.android.wm.shell.common.pip.PipUiEventLogger;
import com.android.wm.shell.pip.phone.PipMotionHelper;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.splitscreen.SplitScreenController;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipUiEventLogger.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipUiEventLogger.java
deleted file mode 100644
index 3e5a19b..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipUiEventLogger.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * 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.pip;
-
-import android.app.TaskInfo;
-import android.content.pm.PackageManager;
-
-import com.android.internal.logging.UiEvent;
-import com.android.internal.logging.UiEventLogger;
-
-/**
- * Helper class that ends PiP log to UiEvent, see also go/uievent
- */
-public class PipUiEventLogger {
-
- private static final int INVALID_PACKAGE_UID = -1;
-
- private final UiEventLogger mUiEventLogger;
- private final PackageManager mPackageManager;
-
- private String mPackageName;
- private int mPackageUid = INVALID_PACKAGE_UID;
-
- public PipUiEventLogger(UiEventLogger uiEventLogger, PackageManager packageManager) {
- mUiEventLogger = uiEventLogger;
- mPackageManager = packageManager;
- }
-
- public void setTaskInfo(TaskInfo taskInfo) {
- if (taskInfo != null && taskInfo.topActivity != null) {
- mPackageName = taskInfo.topActivity.getPackageName();
- mPackageUid = getUid(mPackageName, taskInfo.userId);
- } else {
- mPackageName = null;
- mPackageUid = INVALID_PACKAGE_UID;
- }
- }
-
- /**
- * Sends log via UiEvent, reference go/uievent for how to debug locally
- */
- public void log(PipUiEventEnum event) {
- if (mPackageName == null || mPackageUid == INVALID_PACKAGE_UID) {
- return;
- }
- mUiEventLogger.log(event, mPackageUid, mPackageName);
- }
-
- private int getUid(String packageName, int userId) {
- int uid = INVALID_PACKAGE_UID;
- try {
- uid = mPackageManager.getApplicationInfoAsUser(
- packageName, 0 /* ApplicationInfoFlags */, userId).uid;
- } catch (PackageManager.NameNotFoundException e) {
- // do nothing.
- }
- return uid;
- }
-
- /**
- * Enums for logging the PiP events to UiEvent
- */
- public enum PipUiEventEnum implements UiEventLogger.UiEventEnum {
- @UiEvent(doc = "Activity enters picture-in-picture mode")
- PICTURE_IN_PICTURE_ENTER(603),
-
- @UiEvent(doc = "Activity enters picture-in-picture mode with auto-enter-pip API")
- PICTURE_IN_PICTURE_AUTO_ENTER(1313),
-
- @UiEvent(doc = "Activity enters picture-in-picture mode from content-pip API")
- PICTURE_IN_PICTURE_ENTER_CONTENT_PIP(1314),
-
- @UiEvent(doc = "Expands from picture-in-picture to fullscreen")
- PICTURE_IN_PICTURE_EXPAND_TO_FULLSCREEN(604),
-
- @UiEvent(doc = "Removes picture-in-picture by tap close button")
- PICTURE_IN_PICTURE_TAP_TO_REMOVE(605),
-
- @UiEvent(doc = "Removes picture-in-picture by drag to dismiss area")
- PICTURE_IN_PICTURE_DRAG_TO_REMOVE(606),
-
- @UiEvent(doc = "Shows picture-in-picture menu")
- PICTURE_IN_PICTURE_SHOW_MENU(607),
-
- @UiEvent(doc = "Hides picture-in-picture menu")
- PICTURE_IN_PICTURE_HIDE_MENU(608),
-
- @UiEvent(doc = "Changes the aspect ratio of picture-in-picture window. This is inherited"
- + " from previous Tron-based logging and currently not in use.")
- PICTURE_IN_PICTURE_CHANGE_ASPECT_RATIO(609),
-
- @UiEvent(doc = "User resize of the picture-in-picture window")
- PICTURE_IN_PICTURE_RESIZE(610),
-
- @UiEvent(doc = "User unstashed picture-in-picture")
- PICTURE_IN_PICTURE_STASH_UNSTASHED(709),
-
- @UiEvent(doc = "User stashed picture-in-picture to the left side")
- PICTURE_IN_PICTURE_STASH_LEFT(710),
-
- @UiEvent(doc = "User stashed picture-in-picture to the right side")
- PICTURE_IN_PICTURE_STASH_RIGHT(711),
-
- @UiEvent(doc = "User taps on the settings button in PiP menu")
- PICTURE_IN_PICTURE_SHOW_SETTINGS(933),
-
- @UiEvent(doc = "Closes PiP with app-provided close action")
- PICTURE_IN_PICTURE_CUSTOM_CLOSE(1058);
-
- private final int mId;
-
- PipUiEventEnum(int id) {
- mId = id;
- }
-
- @Override
- public int getId() {
- return mId;
- }
- }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java
index 5e1b6be..cc182ba 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java
@@ -38,12 +38,12 @@
import com.android.internal.protolog.common.ProtoLog;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SystemWindows;
+import com.android.wm.shell.common.pip.PipMediaController;
+import com.android.wm.shell.common.pip.PipMediaController.ActionListener;
+import com.android.wm.shell.common.pip.PipUiEventLogger;
import com.android.wm.shell.pip.PipBoundsState;
-import com.android.wm.shell.pip.PipMediaController;
-import com.android.wm.shell.pip.PipMediaController.ActionListener;
import com.android.wm.shell.pip.PipMenuController;
import com.android.wm.shell.pip.PipSurfaceTransactionHelper;
-import com.android.wm.shell.pip.PipUiEventLogger;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.splitscreen.SplitScreenController;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
index b872267..5c65d78 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
@@ -76,6 +76,7 @@
import com.android.wm.shell.common.TaskStackListenerCallback;
import com.android.wm.shell.common.TaskStackListenerImpl;
import com.android.wm.shell.common.pip.PipAppOpsListener;
+import com.android.wm.shell.common.pip.PipMediaController;
import com.android.wm.shell.onehanded.OneHandedController;
import com.android.wm.shell.onehanded.OneHandedTransitionCallback;
import com.android.wm.shell.pip.IPip;
@@ -87,7 +88,6 @@
import com.android.wm.shell.pip.PipBoundsState;
import com.android.wm.shell.pip.PipDisplayLayoutState;
import com.android.wm.shell.pip.PipKeepClearAlgorithmInterface;
-import com.android.wm.shell.pip.PipMediaController;
import com.android.wm.shell.pip.PipParamsChangedForwarder;
import com.android.wm.shell.pip.PipSnapAlgorithm;
import com.android.wm.shell.pip.PipTaskOrganizer;
@@ -123,14 +123,6 @@
private static final long PIP_KEEP_CLEAR_AREAS_DELAY =
SystemProperties.getLong("persist.wm.debug.pip_keep_clear_areas_delay", 200);
- private boolean mEnablePipKeepClearAlgorithm =
- SystemProperties.getBoolean("persist.wm.debug.enable_pip_keep_clear_algorithm", true);
-
- @VisibleForTesting
- void setEnablePipKeepClearAlgorithm(boolean value) {
- mEnablePipKeepClearAlgorithm = value;
- }
-
private Context mContext;
protected ShellExecutor mMainExecutor;
private DisplayController mDisplayController;
@@ -166,10 +158,6 @@
// early bail out if the change was caused by keyguard showing up
return;
}
- if (!mEnablePipKeepClearAlgorithm) {
- // early bail out if the keep clear areas feature is disabled
- return;
- }
if (mPipBoundsState.isStashed()) {
// don't move when stashed
return;
@@ -187,10 +175,6 @@
}
private void updatePipPositionForKeepClearAreas() {
- if (!mEnablePipKeepClearAlgorithm) {
- // early bail out if the keep clear areas feature is disabled
- return;
- }
if (mIsKeyguardShowingOrAnimating) {
// early bail out if the change was caused by keyguard showing up
return;
@@ -343,19 +327,17 @@
public void onKeepClearAreasChanged(int displayId, Set<Rect> restricted,
Set<Rect> unrestricted) {
if (mPipDisplayLayoutState.getDisplayId() == displayId) {
- if (mEnablePipKeepClearAlgorithm) {
- mPipBoundsState.setKeepClearAreas(restricted, unrestricted);
+ mPipBoundsState.setKeepClearAreas(restricted, unrestricted);
- mMainExecutor.removeCallbacks(
- mMovePipInResponseToKeepClearAreasChangeCallback);
- mMainExecutor.executeDelayed(
- mMovePipInResponseToKeepClearAreasChangeCallback,
- PIP_KEEP_CLEAR_AREAS_DELAY);
+ mMainExecutor.removeCallbacks(
+ mMovePipInResponseToKeepClearAreasChangeCallback);
+ mMainExecutor.executeDelayed(
+ mMovePipInResponseToKeepClearAreasChangeCallback,
+ PIP_KEEP_CLEAR_AREAS_DELAY);
- ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
- "onKeepClearAreasChanged: restricted=%s, unrestricted=%s",
- restricted, unrestricted);
- }
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "onKeepClearAreasChanged: restricted=%s, unrestricted=%s",
+ restricted, unrestricted);
}
}
};
@@ -660,25 +642,9 @@
// there's a keyguard present
return;
}
- int oldMaxMovementBound = mPipBoundsState.getMovementBounds().bottom;
onDisplayChangedUncheck(mDisplayController
.getDisplayLayout(mPipDisplayLayoutState.getDisplayId()),
false /* saveRestoreSnapFraction */);
- int newMaxMovementBound = mPipBoundsState.getMovementBounds().bottom;
- if (!mEnablePipKeepClearAlgorithm) {
- // offset PiP to adjust for bottom inset change
- int pipTop = mPipBoundsState.getBounds().top;
- int diff = newMaxMovementBound - oldMaxMovementBound;
- if (diff < 0 && pipTop > newMaxMovementBound) {
- // bottom inset has increased, move PiP up if it is too low
- mPipMotionHelper.animateToOffset(mPipBoundsState.getBounds(),
- newMaxMovementBound - pipTop);
- }
- if (diff > 0 && oldMaxMovementBound == pipTop) {
- // bottom inset has decreased, move PiP down if it was by the edge
- mPipMotionHelper.animateToOffset(mPipBoundsState.getBounds(), diff);
- }
- }
}
});
@@ -947,14 +913,8 @@
* Sets both shelf visibility and its height.
*/
private void setShelfHeight(boolean visible, int height) {
- if (mEnablePipKeepClearAlgorithm) {
- // turn this into Launcher keep clear area registration instead
- setLauncherKeepClearAreaHeight(visible, height);
- return;
- }
- if (!mIsKeyguardShowingOrAnimating) {
- setShelfHeightLocked(visible, height);
- }
+ // turn this into Launcher keep clear area registration instead
+ setLauncherKeepClearAreaHeight(visible, height);
}
private void setLauncherKeepClearAreaHeight(boolean visible, int height) {
@@ -1015,16 +975,10 @@
private Rect startSwipePipToHome(ComponentName componentName, ActivityInfo activityInfo,
PictureInPictureParams pictureInPictureParams,
int launcherRotation, Rect hotseatKeepClearArea) {
-
- if (mEnablePipKeepClearAlgorithm) {
- // preemptively add the keep clear area for Hotseat, so that it is taken into account
- // when calculating the entry destination bounds of PiP window
- mPipBoundsState.addNamedUnrestrictedKeepClearArea(LAUNCHER_KEEP_CLEAR_AREA_TAG,
- hotseatKeepClearArea);
- } else {
- int shelfHeight = hotseatKeepClearArea.height();
- setShelfHeightLocked(shelfHeight > 0 /* visible */, shelfHeight);
- }
+ // preemptively add the keep clear area for Hotseat, so that it is taken into account
+ // when calculating the entry destination bounds of PiP window
+ mPipBoundsState.addNamedUnrestrictedKeepClearArea(LAUNCHER_KEEP_CLEAR_AREA_TAG,
+ hotseatKeepClearArea);
onDisplayRotationChangedNotInPip(mContext, launcherRotation);
final Rect entryBounds = mPipTaskOrganizer.startSwipePipToHome(componentName, activityInfo,
pictureInPictureParams);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipDismissTargetHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipDismissTargetHandler.java
index da455f8..4e75847 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipDismissTargetHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipDismissTargetHandler.java
@@ -38,7 +38,7 @@
import com.android.wm.shell.common.bubbles.DismissCircleView;
import com.android.wm.shell.common.bubbles.DismissView;
import com.android.wm.shell.common.magnetictarget.MagnetizedObject;
-import com.android.wm.shell.pip.PipUiEventLogger;
+import com.android.wm.shell.common.pip.PipUiEventLogger;
import kotlin.Unit;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java
index 779c539..837426a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java
@@ -66,7 +66,7 @@
import com.android.wm.shell.R;
import com.android.wm.shell.animation.Interpolators;
import com.android.wm.shell.common.ShellExecutor;
-import com.android.wm.shell.pip.PipUiEventLogger;
+import com.android.wm.shell.common.pip.PipUiEventLogger;
import com.android.wm.shell.pip.PipUtils;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.splitscreen.SplitScreenController;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java
index b251f6f..8f0a8e1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java
@@ -33,7 +33,6 @@
import android.graphics.PointF;
import android.graphics.Rect;
import android.os.Debug;
-import android.os.SystemProperties;
import com.android.internal.protolog.common.ProtoLog;
import com.android.wm.shell.R;
@@ -48,19 +47,16 @@
import com.android.wm.shell.pip.PipTransitionController;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
-import java.util.function.Consumer;
-
import kotlin.Unit;
import kotlin.jvm.functions.Function0;
+import java.util.function.Consumer;
+
/**
* A helper to animate and manipulate the PiP.
*/
public class PipMotionHelper implements PipAppOpsListener.Callback,
FloatingContentCoordinator.FloatingContent {
-
- public static final boolean ENABLE_FLING_TO_DISMISS_PIP =
- SystemProperties.getBoolean("persist.wm.debug.fling_to_dismiss_pip", false);
private static final String TAG = "PipMotionHelper";
private static final boolean DEBUG = false;
@@ -707,7 +703,7 @@
loc[1] = animatedPipBounds.top;
}
};
- mMagnetizedPip.setFlingToTargetEnabled(ENABLE_FLING_TO_DISMISS_PIP);
+ mMagnetizedPip.setFlingToTargetEnabled(false);
}
return mMagnetizedPip;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java
index abe2db0..4e687dd 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java
@@ -46,11 +46,11 @@
import com.android.internal.policy.TaskResizingAlgorithm;
import com.android.wm.shell.R;
import com.android.wm.shell.common.ShellExecutor;
+import com.android.wm.shell.common.pip.PipUiEventLogger;
import com.android.wm.shell.pip.PipAnimationController;
import com.android.wm.shell.pip.PipBoundsAlgorithm;
import com.android.wm.shell.pip.PipBoundsState;
import com.android.wm.shell.pip.PipTaskOrganizer;
-import com.android.wm.shell.pip.PipUiEventLogger;
import java.io.PrintWriter;
import java.util.function.Consumer;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
index 3e95498a..6055fd9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
@@ -34,7 +34,6 @@
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
-import android.os.SystemProperties;
import android.provider.DeviceConfig;
import android.util.Size;
import android.view.DisplayCutout;
@@ -51,13 +50,13 @@
import com.android.wm.shell.R;
import com.android.wm.shell.common.FloatingContentCoordinator;
import com.android.wm.shell.common.ShellExecutor;
+import com.android.wm.shell.common.pip.PipUiEventLogger;
import com.android.wm.shell.common.pip.SizeSpecSource;
import com.android.wm.shell.pip.PipAnimationController;
import com.android.wm.shell.pip.PipBoundsAlgorithm;
import com.android.wm.shell.pip.PipBoundsState;
import com.android.wm.shell.pip.PipTaskOrganizer;
import com.android.wm.shell.pip.PipTransitionController;
-import com.android.wm.shell.pip.PipUiEventLogger;
import com.android.wm.shell.pip.PipUtils;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.sysui.ShellInit;
@@ -73,14 +72,6 @@
private static final String TAG = "PipTouchHandler";
private static final float DEFAULT_STASH_VELOCITY_THRESHOLD = 18000.f;
- private boolean mEnablePipKeepClearAlgorithm =
- SystemProperties.getBoolean("persist.wm.debug.enable_pip_keep_clear_algorithm", true);
-
- @VisibleForTesting
- void setEnablePipKeepClearAlgorithm(boolean value) {
- mEnablePipKeepClearAlgorithm = value;
- }
-
// Allow PIP to resize to a slightly bigger state upon touch
private boolean mEnableResize;
private final Context mContext;
@@ -430,48 +421,6 @@
mIsImeShowing ? mImeOffset : 0,
!mIsImeShowing && mIsShelfShowing ? mShelfHeight : 0);
- // If this is from an IME or shelf adjustment, then we should move the PiP so that it is not
- // occluded by the IME or shelf.
- if (fromImeAdjustment || fromShelfAdjustment) {
- if (mTouchState.isUserInteracting() && mTouchState.isDragging()) {
- // Defer the update of the current movement bounds until after the user finishes
- // touching the screen
- } else if (mEnablePipKeepClearAlgorithm) {
- // Ignore moving PiP if keep clear algorithm is enabled, since IME and shelf height
- // now are accounted for in the keep clear algorithm calculations
- } else {
- final boolean isExpanded = mMenuState == MENU_STATE_FULL && willResizeMenu();
- final Rect toMovementBounds = new Rect();
- mPipBoundsAlgorithm.getMovementBounds(curBounds, insetBounds,
- toMovementBounds, mIsImeShowing ? mImeHeight : 0);
- final int prevBottom = mPipBoundsState.getMovementBounds().bottom
- - mMovementBoundsExtraOffsets;
- // This is to handle landscape fullscreen IMEs, don't apply the extra offset in this
- // case
- final int toBottom = toMovementBounds.bottom < toMovementBounds.top
- ? toMovementBounds.bottom
- : toMovementBounds.bottom - extraOffset;
-
- if (isExpanded) {
- curBounds.set(mPipBoundsState.getExpandedBounds());
- mPipBoundsAlgorithm.getSnapAlgorithm().applySnapFraction(curBounds,
- toMovementBounds, mSavedSnapFraction);
- }
-
- if (prevBottom < toBottom) {
- // The movement bounds are expanding
- if (curBounds.top > prevBottom - mBottomOffsetBufferPx) {
- mMotionHelper.animateToOffset(curBounds, toBottom - curBounds.top);
- }
- } else if (prevBottom > toBottom) {
- // The movement bounds are shrinking
- if (curBounds.top > toBottom - mBottomOffsetBufferPx) {
- mMotionHelper.animateToOffset(curBounds, toBottom - curBounds.top);
- }
- }
- }
- }
-
// Update the movement bounds after doing the calculations based on the old movement bounds
// above
mPipBoundsState.setNormalMovementBounds(normalMovementBounds);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipActionsProvider.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipActionsProvider.java
index 3b44f10..7dc400c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipActionsProvider.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipActionsProvider.java
@@ -35,7 +35,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.protolog.common.ProtoLog;
import com.android.wm.shell.R;
-import com.android.wm.shell.pip.PipMediaController;
+import com.android.wm.shell.common.pip.PipMediaController;
import com.android.wm.shell.pip.PipUtils;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java
index 5e583c2..0816dc7 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java
@@ -48,11 +48,11 @@
import com.android.wm.shell.common.TaskStackListenerCallback;
import com.android.wm.shell.common.TaskStackListenerImpl;
import com.android.wm.shell.common.pip.PipAppOpsListener;
+import com.android.wm.shell.common.pip.PipMediaController;
import com.android.wm.shell.pip.PinnedStackListenerForwarder;
import com.android.wm.shell.pip.Pip;
import com.android.wm.shell.pip.PipAnimationController;
import com.android.wm.shell.pip.PipDisplayLayoutState;
-import com.android.wm.shell.pip.PipMediaController;
import com.android.wm.shell.pip.PipParamsChangedForwarder;
import com.android.wm.shell.pip.PipTaskOrganizer;
import com.android.wm.shell.pip.PipTransitionController;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipNotificationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipNotificationController.java
index f22ee59..39c7a4b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipNotificationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipNotificationController.java
@@ -36,7 +36,7 @@
import com.android.internal.protolog.common.ProtoLog;
import com.android.internal.util.ImageUtils;
import com.android.wm.shell.R;
-import com.android.wm.shell.pip.PipMediaController;
+import com.android.wm.shell.common.pip.PipMediaController;
import com.android.wm.shell.pip.PipParamsChangedForwarder;
import com.android.wm.shell.pip.PipUtils;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipTaskOrganizer.java
index 4819f66..dbec607 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipTaskOrganizer.java
@@ -25,6 +25,7 @@
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue;
+import com.android.wm.shell.common.pip.PipUiEventLogger;
import com.android.wm.shell.pip.PipAnimationController;
import com.android.wm.shell.pip.PipBoundsAlgorithm;
import com.android.wm.shell.pip.PipBoundsState;
@@ -35,7 +36,6 @@
import com.android.wm.shell.pip.PipTaskOrganizer;
import com.android.wm.shell.pip.PipTransitionController;
import com.android.wm.shell.pip.PipTransitionState;
-import com.android.wm.shell.pip.PipUiEventLogger;
import com.android.wm.shell.pip.PipUtils;
import com.android.wm.shell.splitscreen.SplitScreenController;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
index 2be7a49..29fff03 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
@@ -71,6 +71,7 @@
import com.android.wm.shell.desktopmode.DesktopModeStatus;
import com.android.wm.shell.desktopmode.DesktopTasksController;
import com.android.wm.shell.freeform.FreeformTaskTransitionStarter;
+import com.android.wm.shell.splitscreen.SplitScreen;
import com.android.wm.shell.splitscreen.SplitScreenController;
import com.android.wm.shell.sysui.KeyguardChangeListener;
import com.android.wm.shell.sysui.ShellController;
@@ -200,6 +201,19 @@
@Override
public void setSplitScreenController(SplitScreenController splitScreenController) {
mSplitScreenController = splitScreenController;
+ mSplitScreenController.registerSplitScreenListener(new SplitScreen.SplitScreenListener() {
+ @Override
+ public void onTaskStageChanged(int taskId, int stage, boolean visible) {
+ if (visible) {
+ DesktopModeWindowDecoration decor = mWindowDecorByTaskId.get(taskId);
+ if (decor != null && DesktopModeStatus.isActive(mContext)
+ && decor.mTaskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
+ mDesktopModeController.ifPresent(c -> c.setDesktopModeActive(false));
+ mDesktopTasksController.ifPresent(c -> c.moveToSplit(decor.mTaskInfo));
+ }
+ }
+ }
+ });
}
@Override
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java
index 1e3fe42..248d665 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java
@@ -53,6 +53,7 @@
import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.common.pip.PhoneSizeSpecSource;
+import com.android.wm.shell.common.pip.PipUiEventLogger;
import com.android.wm.shell.common.pip.SizeSpecSource;
import com.android.wm.shell.pip.phone.PhonePipMenuController;
import com.android.wm.shell.splitscreen.SplitScreenController;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java
index 0ae2908..911f5e1 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java
@@ -56,12 +56,12 @@
import com.android.wm.shell.common.TabletopModeController;
import com.android.wm.shell.common.TaskStackListenerImpl;
import com.android.wm.shell.common.pip.PipAppOpsListener;
+import com.android.wm.shell.common.pip.PipMediaController;
import com.android.wm.shell.onehanded.OneHandedController;
import com.android.wm.shell.pip.PipAnimationController;
import com.android.wm.shell.pip.PipBoundsAlgorithm;
import com.android.wm.shell.pip.PipBoundsState;
import com.android.wm.shell.pip.PipDisplayLayoutState;
-import com.android.wm.shell.pip.PipMediaController;
import com.android.wm.shell.pip.PipParamsChangedForwarder;
import com.android.wm.shell.pip.PipSnapAlgorithm;
import com.android.wm.shell.pip.PipTaskOrganizer;
@@ -76,7 +76,6 @@
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import java.util.Optional;
@@ -329,21 +328,7 @@
}
@Test
- public void onKeepClearAreasChanged_featureDisabled_pipBoundsStateDoesntChange() {
- mPipController.setEnablePipKeepClearAlgorithm(false);
- final int displayId = 1;
- final Rect keepClearArea = new Rect(0, 0, 10, 10);
- when(mMockPipDisplayLayoutState.getDisplayId()).thenReturn(displayId);
-
- mPipController.mDisplaysChangedListener.onKeepClearAreasChanged(
- displayId, Set.of(keepClearArea), Set.of());
-
- verify(mMockPipBoundsState, never()).setKeepClearAreas(Mockito.anySet(), Mockito.anySet());
- }
-
- @Test
- public void onKeepClearAreasChanged_featureEnabled_updatesPipBoundsState() {
- mPipController.setEnablePipKeepClearAlgorithm(true);
+ public void onKeepClearAreasChanged_updatesPipBoundsState() {
final int displayId = 1;
final Rect keepClearArea = new Rect(0, 0, 10, 10);
when(mMockPipDisplayLayoutState.getDisplayId()).thenReturn(displayId);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipResizeGestureHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipResizeGestureHandlerTest.java
index 689b5c5..12b4f3e 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipResizeGestureHandlerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipResizeGestureHandlerTest.java
@@ -37,6 +37,7 @@
import com.android.wm.shell.common.FloatingContentCoordinator;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.pip.PhoneSizeSpecSource;
+import com.android.wm.shell.common.pip.PipUiEventLogger;
import com.android.wm.shell.common.pip.SizeSpecSource;
import com.android.wm.shell.pip.PipBoundsAlgorithm;
import com.android.wm.shell.pip.PipBoundsState;
@@ -45,7 +46,6 @@
import com.android.wm.shell.pip.PipSnapAlgorithm;
import com.android.wm.shell.pip.PipTaskOrganizer;
import com.android.wm.shell.pip.PipTransitionController;
-import com.android.wm.shell.pip.PipUiEventLogger;
import org.junit.Before;
import org.junit.Test;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java
index 852183c..314f195d 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java
@@ -18,7 +18,6 @@
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -34,6 +33,7 @@
import com.android.wm.shell.common.FloatingContentCoordinator;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.pip.PhoneSizeSpecSource;
+import com.android.wm.shell.common.pip.PipUiEventLogger;
import com.android.wm.shell.common.pip.SizeSpecSource;
import com.android.wm.shell.pip.PipBoundsAlgorithm;
import com.android.wm.shell.pip.PipBoundsState;
@@ -42,7 +42,6 @@
import com.android.wm.shell.pip.PipSnapAlgorithm;
import com.android.wm.shell.pip.PipTaskOrganizer;
import com.android.wm.shell.pip.PipTransitionController;
-import com.android.wm.shell.pip.PipUiEventLogger;
import com.android.wm.shell.sysui.ShellInit;
import org.junit.Before;
@@ -174,16 +173,4 @@
verify(mPipResizeGestureHandler, times(1))
.updateMaxSize(expectedMaxSize.getWidth(), expectedMaxSize.getHeight());
}
-
- @Test
- public void updateMovementBounds_withImeAdjustment_movesPip() {
- mPipTouchHandler.setEnablePipKeepClearAlgorithm(false);
- mFromImeAdjustment = true;
- mPipTouchHandler.onImeVisibilityChanged(true /* imeVisible */, mImeHeight);
-
- mPipTouchHandler.onMovementBoundsChanged(mInsetBounds, mPipBounds, mCurBounds,
- mFromImeAdjustment, mFromShelfAdjustment, mDisplayRotation);
-
- verify(mMotionHelper, times(1)).animateToOffset(any(), anyInt());
- }
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/TvPipActionProviderTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/TvPipActionProviderTest.java
index 02e6b8c..c40cd406 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/TvPipActionProviderTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/TvPipActionProviderTest.java
@@ -37,7 +37,7 @@
import android.util.Log;
import com.android.wm.shell.ShellTestCase;
-import com.android.wm.shell.pip.PipMediaController;
+import com.android.wm.shell.common.pip.PipMediaController;
import org.junit.Before;
import org.junit.Test;
diff --git a/libs/androidfw/AssetManager.cpp b/libs/androidfw/AssetManager.cpp
index fb2b571..795bb3c 100644
--- a/libs/androidfw/AssetManager.cpp
+++ b/libs/androidfw/AssetManager.cpp
@@ -91,7 +91,7 @@
path.appendPath(kResourceCache);
char buf[256]; // 256 chars should be enough for anyone...
- strncpy(buf, pkgPath.string(), 255);
+ strncpy(buf, pkgPath.c_str(), 255);
buf[255] = '\0';
char* filename = buf;
while (*filename && *filename == '/') {
@@ -183,15 +183,15 @@
if (kAppZipName) {
realPath.appendPath(kAppZipName);
}
- ap.type = ::getFileType(realPath.string());
+ ap.type = ::getFileType(realPath.c_str());
if (ap.type == kFileTypeRegular) {
ap.path = realPath;
} else {
ap.path = path;
- ap.type = ::getFileType(path.string());
+ ap.type = ::getFileType(path.c_str());
if (ap.type != kFileTypeDirectory && ap.type != kFileTypeRegular) {
ALOGW("Asset path %s is neither a directory nor file (type=%d).",
- path.string(), (int)ap.type);
+ path.c_str(), (int)ap.type);
return false;
}
}
@@ -207,7 +207,7 @@
}
ALOGV("In %p Asset %s path: %s", this,
- ap.type == kFileTypeDirectory ? "dir" : "zip", ap.path.string());
+ ap.type == kFileTypeDirectory ? "dir" : "zip", ap.path.c_str());
ap.isSystemAsset = isSystemAsset;
ssize_t apPos = mAssetPaths.add(ap);
@@ -248,7 +248,7 @@
Asset* idmap = NULL;
if ((idmap = openAssetFromFileLocked(idmapPath, Asset::ACCESS_BUFFER)) == NULL) {
- ALOGW("failed to open idmap file %s\n", idmapPath.string());
+ ALOGW("failed to open idmap file %s\n", idmapPath.c_str());
return false;
}
@@ -256,7 +256,7 @@
String8 overlayPath;
if (!ResTable::getIdmapInfo(idmap->getBuffer(false), idmap->getLength(),
NULL, NULL, NULL, &targetPath, &overlayPath)) {
- ALOGW("failed to read idmap file %s\n", idmapPath.string());
+ ALOGW("failed to read idmap file %s\n", idmapPath.c_str());
delete idmap;
return false;
}
@@ -264,29 +264,29 @@
if (overlayPath != packagePath) {
ALOGW("idmap file %s inconcistent: expected path %s does not match actual path %s\n",
- idmapPath.string(), packagePath.string(), overlayPath.string());
+ idmapPath.c_str(), packagePath.c_str(), overlayPath.c_str());
return false;
}
- if (access(targetPath.string(), R_OK) != 0) {
- ALOGW("failed to access file %s: %s\n", targetPath.string(), strerror(errno));
+ if (access(targetPath.c_str(), R_OK) != 0) {
+ ALOGW("failed to access file %s: %s\n", targetPath.c_str(), strerror(errno));
return false;
}
- if (access(idmapPath.string(), R_OK) != 0) {
- ALOGW("failed to access file %s: %s\n", idmapPath.string(), strerror(errno));
+ if (access(idmapPath.c_str(), R_OK) != 0) {
+ ALOGW("failed to access file %s: %s\n", idmapPath.c_str(), strerror(errno));
return false;
}
- if (access(overlayPath.string(), R_OK) != 0) {
- ALOGW("failed to access file %s: %s\n", overlayPath.string(), strerror(errno));
+ if (access(overlayPath.c_str(), R_OK) != 0) {
+ ALOGW("failed to access file %s: %s\n", overlayPath.c_str(), strerror(errno));
return false;
}
asset_path oap;
oap.path = overlayPath;
- oap.type = ::getFileType(overlayPath.string());
+ oap.type = ::getFileType(overlayPath.c_str());
oap.idmap = idmapPath;
#if 0
ALOGD("Overlay added: targetPath=%s overlayPath=%s idmapPath=%s\n",
- targetPath.string(), overlayPath.string(), idmapPath.string());
+ targetPath.c_str(), overlayPath.c_str(), idmapPath.c_str());
#endif
mAssetPaths.add(oap);
*cookie = static_cast<int32_t>(mAssetPaths.size());
@@ -310,7 +310,7 @@
ap.type = kFileTypeRegular;
ap.assumeOwnership = assume_ownership;
- ALOGV("In %p Asset fd %d name: %s", this, fd, ap.path.string());
+ ALOGV("In %p Asset fd %d name: %s", this, fd, ap.path.c_str());
ssize_t apPos = mAssetPaths.add(ap);
@@ -343,11 +343,11 @@
assets[i] = openNonAssetInPathLocked("resources.arsc",
Asset::ACCESS_BUFFER, ap);
if (assets[i] == NULL) {
- ALOGW("failed to find resources.arsc in %s\n", ap.path.string());
+ ALOGW("failed to find resources.arsc in %s\n", ap.path.c_str());
goto exit;
}
if (tables[i].add(assets[i]) != NO_ERROR) {
- ALOGW("failed to add %s to resource table", paths[i].string());
+ ALOGW("failed to add %s to resource table", paths[i].c_str());
goto exit;
}
}
@@ -449,8 +449,8 @@
while (i > 0) {
i--;
ALOGV("Looking for asset '%s' in '%s'\n",
- assetName.string(), mAssetPaths.itemAt(i).path.string());
- Asset* pAsset = openNonAssetInPathLocked(assetName.string(), mode,
+ assetName.c_str(), mAssetPaths.itemAt(i).path.c_str());
+ Asset* pAsset = openNonAssetInPathLocked(assetName.c_str(), mode,
mAssetPaths.editItemAt(i));
if (pAsset != NULL) {
return pAsset != kExcludedAsset ? pAsset : NULL;
@@ -478,7 +478,7 @@
size_t i = mAssetPaths.size();
while (i > 0) {
i--;
- ALOGV("Looking for non-asset '%s' in '%s'\n", fileName, mAssetPaths.itemAt(i).path.string());
+ ALOGV("Looking for non-asset '%s' in '%s'\n", fileName, mAssetPaths.itemAt(i).path.c_str());
Asset* pAsset = openNonAssetInPathLocked(
fileName, mode, mAssetPaths.editItemAt(i));
if (pAsset != NULL) {
@@ -500,7 +500,7 @@
if (which < mAssetPaths.size()) {
ALOGV("Looking for non-asset '%s' in '%s'\n", fileName,
- mAssetPaths.itemAt(which).path.string());
+ mAssetPaths.itemAt(which).path.c_str());
Asset* pAsset = openNonAssetInPathLocked(
fileName, mode, mAssetPaths.editItemAt(which));
if (pAsset != NULL) {
@@ -546,10 +546,10 @@
ResTable* sharedRes = NULL;
bool shared = true;
bool onlyEmptyResources = true;
- ATRACE_NAME(ap.path.string());
+ ATRACE_NAME(ap.path.c_str());
Asset* idmap = openIdmapLocked(ap);
size_t nextEntryIdx = mResources->getTableCount();
- ALOGV("Looking for resource asset in '%s'\n", ap.path.string());
+ ALOGV("Looking for resource asset in '%s'\n", ap.path.c_str());
if (ap.type != kFileTypeDirectory && ap.rawFd < 0) {
if (nextEntryIdx == 0) {
// The first item is typically the framework resources,
@@ -565,7 +565,7 @@
ass = const_cast<AssetManager*>(this)->
mZipSet.getZipResourceTableAsset(ap.path);
if (ass == NULL) {
- ALOGV("loading resource table %s\n", ap.path.string());
+ ALOGV("loading resource table %s\n", ap.path.c_str());
ass = const_cast<AssetManager*>(this)->
openNonAssetInPathLocked("resources.arsc",
Asset::ACCESS_BUFFER,
@@ -580,7 +580,7 @@
// If this is the first resource table in the asset
// manager, then we are going to cache it so that we
// can quickly copy it out for others.
- ALOGV("Creating shared resources for %s", ap.path.string());
+ ALOGV("Creating shared resources for %s", ap.path.c_str());
sharedRes = new ResTable();
sharedRes->add(ass, idmap, nextEntryIdx + 1, false);
#ifdef __ANDROID__
@@ -589,14 +589,14 @@
String8 overlaysListPath(data);
overlaysListPath.appendPath(kResourceCache);
overlaysListPath.appendPath("overlays.list");
- addSystemOverlays(overlaysListPath.string(), ap.path, sharedRes, nextEntryIdx);
+ addSystemOverlays(overlaysListPath.c_str(), ap.path, sharedRes, nextEntryIdx);
#endif
sharedRes = const_cast<AssetManager*>(this)->
mZipSet.setZipResourceTable(ap.path, sharedRes);
}
}
} else {
- ALOGV("loading resource table %s\n", ap.path.string());
+ ALOGV("loading resource table %s\n", ap.path.c_str());
ass = const_cast<AssetManager*>(this)->
openNonAssetInPathLocked("resources.arsc",
Asset::ACCESS_BUFFER,
@@ -607,10 +607,10 @@
if ((ass != NULL || sharedRes != NULL) && ass != kExcludedAsset) {
ALOGV("Installing resource asset %p in to table %p\n", ass, mResources);
if (sharedRes != NULL) {
- ALOGV("Copying existing resources for %s", ap.path.string());
+ ALOGV("Copying existing resources for %s", ap.path.c_str());
mResources->add(sharedRes, ap.isSystemAsset);
} else {
- ALOGV("Parsing resources for %s", ap.path.string());
+ ALOGV("Parsing resources for %s", ap.path.c_str());
mResources->add(ass, idmap, nextEntryIdx + 1, !shared, appAsLib, ap.isSystemAsset);
}
onlyEmptyResources = false;
@@ -692,9 +692,9 @@
ass = const_cast<AssetManager*>(this)->
openAssetFromFileLocked(ap.idmap, Asset::ACCESS_BUFFER);
if (ass) {
- ALOGV("loading idmap %s\n", ap.idmap.string());
+ ALOGV("loading idmap %s\n", ap.idmap.c_str());
} else {
- ALOGW("failed to load idmap %s\n", ap.idmap.string());
+ ALOGW("failed to load idmap %s\n", ap.idmap.c_str());
}
}
return ass;
@@ -812,7 +812,7 @@
ZipFileRO* pZip = getZipFileLocked(ap);
if (pZip != NULL) {
ALOGV("GOT zip, checking NA '%s'", (const char*) path);
- ZipEntryRO entry = pZip->findEntryByName(path.string());
+ ZipEntryRO entry = pZip->findEntryByName(path.c_str());
if (entry != NULL) {
ALOGV("FOUND NA in Zip file for %s", (const char*) path);
pAsset = openAssetFromZipLocked(pZip, entry, mode, path);
@@ -823,7 +823,7 @@
if (pAsset != NULL) {
/* create a "source" name, for debug/display */
pAsset->setAssetSource(
- createZipSourceNameLocked(ZipSet::getPathName(ap.path.string()), String8(""),
+ createZipSourceNameLocked(ZipSet::getPathName(ap.path.c_str()), String8(""),
String8(fileName)));
}
}
@@ -870,7 +870,7 @@
}
if (ap.rawFd < 0) {
- ALOGV("getZipFileLocked: Creating new zip from path %s", ap.path.string());
+ ALOGV("getZipFileLocked: Creating new zip from path %s", ap.path.c_str());
ap.zip = mZipSet.getSharedZip(ap.path);
} else {
ALOGV("getZipFileLocked: Creating new zip from fd %d", ap.rawFd);
@@ -897,12 +897,12 @@
{
Asset* pAsset = NULL;
- if (strcasecmp(pathName.getPathExtension().string(), ".gz") == 0) {
+ if (strcasecmp(pathName.getPathExtension().c_str(), ".gz") == 0) {
//printf("TRYING '%s'\n", (const char*) pathName);
- pAsset = Asset::createFromCompressedFile(pathName.string(), mode);
+ pAsset = Asset::createFromCompressedFile(pathName.c_str(), mode);
} else {
//printf("TRYING '%s'\n", (const char*) pathName);
- pAsset = Asset::createFromFile(pathName.string(), mode);
+ pAsset = Asset::createFromFile(pathName.c_str(), mode);
}
return pAsset;
@@ -940,12 +940,12 @@
if (method == ZipFileRO::kCompressStored) {
pAsset = Asset::createFromUncompressedMap(std::move(*dataMap), mode);
- ALOGV("Opened uncompressed entry %s in zip %s mode %d: %p", entryName.string(),
+ ALOGV("Opened uncompressed entry %s in zip %s mode %d: %p", entryName.c_str(),
dataMap->file_name(), mode, pAsset.get());
} else {
pAsset = Asset::createFromCompressedMap(std::move(*dataMap),
static_cast<size_t>(uncompressedLen), mode);
- ALOGV("Opened compressed entry %s in zip %s mode %d: %p", entryName.string(),
+ ALOGV("Opened compressed entry %s in zip %s mode %d: %p", entryName.c_str(),
dataMap->file_name(), mode, pAsset.get());
}
if (pAsset == NULL) {
@@ -993,10 +993,10 @@
i--;
const asset_path& ap = mAssetPaths.itemAt(i);
if (ap.type == kFileTypeRegular) {
- ALOGV("Adding directory %s from zip %s", dirName, ap.path.string());
+ ALOGV("Adding directory %s from zip %s", dirName, ap.path.c_str());
scanAndMergeZipLocked(pMergedInfo, ap, kAssetsRoot, dirName);
} else {
- ALOGV("Adding directory %s from dir %s", dirName, ap.path.string());
+ ALOGV("Adding directory %s from dir %s", dirName, ap.path.c_str());
scanAndMergeDirLocked(pMergedInfo, ap, kAssetsRoot, dirName);
}
}
@@ -1042,10 +1042,10 @@
if (which < mAssetPaths.size()) {
const asset_path& ap = mAssetPaths.itemAt(which);
if (ap.type == kFileTypeRegular) {
- ALOGV("Adding directory %s from zip %s", dirName, ap.path.string());
+ ALOGV("Adding directory %s from zip %s", dirName, ap.path.c_str());
scanAndMergeZipLocked(pMergedInfo, ap, NULL, dirName);
} else {
- ALOGV("Adding directory %s from dir %s", dirName, ap.path.string());
+ ALOGV("Adding directory %s from dir %s", dirName, ap.path.c_str());
scanAndMergeDirLocked(pMergedInfo, ap, NULL, dirName);
}
}
@@ -1075,7 +1075,7 @@
{
assert(pMergedInfo != NULL);
- //printf("scanAndMergeDir: %s %s %s\n", ap.path.string(), rootDir, dirName);
+ //printf("scanAndMergeDir: %s %s %s\n", ap.path.c_str(), rootDir, dirName);
String8 path = createPathNameLocked(ap, rootDir);
if (dirName[0] != '\0')
@@ -1100,7 +1100,7 @@
const char* name;
int nameLen;
- name = pContents->itemAt(i).getFileName().string();
+ name = pContents->itemAt(i).getFileName().c_str();
nameLen = strlen(name);
if (nameLen > exclExtLen &&
strcmp(name + (nameLen - exclExtLen), kExcludeExtension) == 0)
@@ -1111,8 +1111,8 @@
matchIdx = AssetDir::FileInfo::findEntry(pMergedInfo, match);
if (matchIdx > 0) {
ALOGV("Excluding '%s' [%s]\n",
- pMergedInfo->itemAt(matchIdx).getFileName().string(),
- pMergedInfo->itemAt(matchIdx).getSourceName().string());
+ pMergedInfo->itemAt(matchIdx).getFileName().c_str(),
+ pMergedInfo->itemAt(matchIdx).getSourceName().c_str());
pMergedInfo->removeAt(matchIdx);
} else {
//printf("+++ no match on '%s'\n", (const char*) match);
@@ -1150,9 +1150,9 @@
struct dirent* entry;
FileType fileType;
- ALOGV("Scanning dir '%s'\n", path.string());
+ ALOGV("Scanning dir '%s'\n", path.c_str());
- dir = opendir(path.string());
+ dir = opendir(path.c_str());
if (dir == NULL)
return NULL;
@@ -1176,7 +1176,7 @@
fileType = kFileTypeUnknown;
#else
// stat the file
- fileType = ::getFileType(path.appendPathCopy(entry->d_name).string());
+ fileType = ::getFileType(path.appendPathCopy(entry->d_name).c_str());
#endif
if (fileType != kFileTypeRegular && fileType != kFileTypeDirectory)
@@ -1184,7 +1184,7 @@
AssetDir::FileInfo info;
info.set(String8(entry->d_name), fileType);
- if (strcasecmp(info.getFileName().getPathExtension().string(), ".gz") == 0)
+ if (strcasecmp(info.getFileName().getPathExtension().c_str(), ".gz") == 0)
info.setFileName(info.getFileName().getBasePath());
info.setSourceName(path.appendPathCopy(info.getFileName()));
pContents->add(info);
@@ -1212,11 +1212,11 @@
pZip = mZipSet.getZip(ap.path);
if (pZip == NULL) {
- ALOGW("Failure opening zip %s\n", ap.path.string());
+ ALOGW("Failure opening zip %s\n", ap.path.c_str());
return false;
}
- zipName = ZipSet::getPathName(ap.path.string());
+ zipName = ZipSet::getPathName(ap.path.c_str());
/* convert "sounds" to "rootDir/sounds" */
if (rootDir != NULL) dirName = rootDir;
@@ -1240,7 +1240,7 @@
*/
int dirNameLen = dirName.length();
void *iterationCookie;
- if (!pZip->startIteration(&iterationCookie, dirName.string(), NULL)) {
+ if (!pZip->startIteration(&iterationCookie, dirName.c_str(), NULL)) {
ALOGW("ZipFileRO::startIteration returned false");
return false;
}
@@ -1254,7 +1254,7 @@
ALOGE("ARGH: name too long?\n");
continue;
}
- //printf("Comparing %s in %s?\n", nameBuf, dirName.string());
+ //printf("Comparing %s in %s?\n", nameBuf, dirName.c_str());
if (dirNameLen == 0 || nameBuf[dirNameLen] == '/')
{
const char* cp;
@@ -1275,7 +1275,7 @@
createZipSourceNameLocked(zipName, dirName, info.getFileName()));
contents.add(info);
- //printf("FOUND: file '%s'\n", info.getFileName().string());
+ //printf("FOUND: file '%s'\n", info.getFileName().c_str());
} else {
/* this is a subdir; add it if we don't already have it*/
String8 subdirName(cp, nextSlash - cp);
@@ -1291,7 +1291,7 @@
dirs.add(subdirName);
}
- //printf("FOUND: dir '%s'\n", subdirName.string());
+ //printf("FOUND: dir '%s'\n", subdirName.c_str());
}
}
}
@@ -1427,10 +1427,10 @@
if (kIsDebug) {
ALOGI("Creating SharedZip %p %s\n", this, (const char*)mPath);
}
- ALOGV("+++ opening zip '%s'\n", mPath.string());
- mZipFile = ZipFileRO::open(mPath.string());
+ ALOGV("+++ opening zip '%s'\n", mPath.c_str());
+ mZipFile = ZipFileRO::open(mPath.c_str());
if (mZipFile == NULL) {
- ALOGD("failed to open Zip archive '%s'\n", mPath.string());
+ ALOGD("failed to open Zip archive '%s'\n", mPath.c_str());
}
}
@@ -1441,11 +1441,11 @@
if (kIsDebug) {
ALOGI("Creating SharedZip %p fd=%d %s\n", this, fd, (const char*)mPath);
}
- ALOGV("+++ opening zip fd=%d '%s'\n", fd, mPath.string());
- mZipFile = ZipFileRO::openFd(fd, mPath.string());
+ ALOGV("+++ opening zip fd=%d '%s'\n", fd, mPath.c_str());
+ mZipFile = ZipFileRO::openFd(fd, mPath.c_str());
if (mZipFile == NULL) {
::close(fd);
- ALOGD("failed to open Zip archive fd=%d '%s'\n", fd, mPath.string());
+ ALOGD("failed to open Zip archive fd=%d '%s'\n", fd, mPath.c_str());
}
}
@@ -1520,7 +1520,7 @@
bool AssetManager::SharedZip::isUpToDate()
{
- time_t modWhen = getFileModDate(mPath.string());
+ time_t modWhen = getFileModDate(mPath.c_str());
return mModWhen == modWhen;
}
@@ -1551,7 +1551,7 @@
}
if (mZipFile != NULL) {
delete mZipFile;
- ALOGV("Closed '%s'\n", mPath.string());
+ ALOGV("Closed '%s'\n", mPath.c_str());
}
}
diff --git a/libs/androidfw/BackupData.cpp b/libs/androidfw/BackupData.cpp
index 76a430e..fec0e77 100644
--- a/libs/androidfw/BackupData.cpp
+++ b/libs/androidfw/BackupData.cpp
@@ -106,8 +106,8 @@
k = key;
}
if (kIsDebug) {
- ALOGD("Writing header: prefix='%s' key='%s' dataSize=%zu", m_keyPrefix.string(),
- key.string(), dataSize);
+ ALOGD("Writing header: prefix='%s' key='%s' dataSize=%zu", m_keyPrefix.c_str(),
+ key.c_str(), dataSize);
}
entity_header_v1 header;
@@ -128,7 +128,7 @@
m_pos += amt;
if (kIsDebug) ALOGI("writing entity header key, %zd bytes", keyLen+1);
- amt = write(m_fd, k.string(), keyLen+1);
+ amt = write(m_fd, k.c_str(), keyLen+1);
if (amt != keyLen+1) {
m_status = errno;
return m_status;
diff --git a/libs/androidfw/BackupHelpers.cpp b/libs/androidfw/BackupHelpers.cpp
index e80e948..3582609 100644
--- a/libs/androidfw/BackupHelpers.cpp
+++ b/libs/androidfw/BackupHelpers.cpp
@@ -179,7 +179,7 @@
}
// filename is not NULL terminated, but it is padded
- amt = write(fd, name.string(), nameLen);
+ amt = write(fd, name.c_str(), nameLen);
if (amt != nameLen) {
ALOGW("write_snapshot_file error writing filename %s", strerror(errno));
return 1;
@@ -203,7 +203,7 @@
static int
write_delete_file(BackupDataWriter* dataStream, const String8& key)
{
- LOGP("write_delete_file %s\n", key.string());
+ LOGP("write_delete_file %s\n", key.c_str());
return dataStream->WriteEntityHeader(key, -1);
}
@@ -211,7 +211,7 @@
write_update_file(BackupDataWriter* dataStream, int fd, int mode, const String8& key,
char const* realFilename)
{
- LOGP("write_update_file %s (%s) : mode 0%o\n", realFilename, key.string(), mode);
+ LOGP("write_update_file %s (%s) : mode 0%o\n", realFilename, key.c_str(), mode);
const int bufsize = 4*1024;
int err;
@@ -365,7 +365,7 @@
r.s.size = st.st_size;
if (newSnapshot.indexOfKey(key) >= 0) {
- LOGP("back_up_files key already in use '%s'", key.string());
+ LOGP("back_up_files key already in use '%s'", key.c_str());
return -1;
}
@@ -390,30 +390,30 @@
int cmp = p.compare(q);
if (cmp < 0) {
// file present in oldSnapshot, but not present in newSnapshot
- LOGP("file removed: %s", p.string());
+ LOGP("file removed: %s", p.c_str());
write_delete_file(dataStream, p);
n++;
} else if (cmp > 0) {
// file added
- LOGP("file added: %s crc=0x%08x", g.file.string(), g.s.crc32);
- write_update_file(dataStream, q, g.file.string());
+ LOGP("file added: %s crc=0x%08x", g.file.c_str(), g.s.crc32);
+ write_update_file(dataStream, q, g.file.c_str());
m++;
} else {
// same file exists in both old and new; check whether to update
const FileState& f = oldSnapshot.valueAt(n);
- LOGP("%s", q.string());
+ LOGP("%s", q.c_str());
LOGP(" old: modTime=%d,%d mode=%04o size=%-3d crc32=0x%08x",
f.modTime_sec, f.modTime_nsec, f.mode, f.size, f.crc32);
LOGP(" new: modTime=%d,%d mode=%04o size=%-3d crc32=0x%08x",
g.s.modTime_sec, g.s.modTime_nsec, g.s.mode, g.s.size, g.s.crc32);
if (f.modTime_sec != g.s.modTime_sec || f.modTime_nsec != g.s.modTime_nsec
|| f.mode != g.s.mode || f.size != g.s.size || f.crc32 != g.s.crc32) {
- int fd = open(g.file.string(), O_RDONLY);
+ int fd = open(g.file.c_str(), O_RDONLY);
if (fd < 0) {
- ALOGE("Unable to read file for backup: %s", g.file.string());
+ ALOGE("Unable to read file for backup: %s", g.file.c_str());
} else {
- write_update_file(dataStream, fd, g.s.mode, p, g.file.string());
+ write_update_file(dataStream, fd, g.s.mode, p, g.file.c_str());
close(fd);
}
}
@@ -432,7 +432,7 @@
while (m<M) {
const String8& q = newSnapshot.keyAt(m);
FileRec& g = newSnapshot.editValueAt(m);
- write_update_file(dataStream, q, g.file.string());
+ write_update_file(dataStream, q, g.file.c_str());
m++;
}
@@ -483,7 +483,7 @@
BackupDataWriter* writer)
{
// In the output stream everything is stored relative to the root
- const char* relstart = filepath.string() + rootpath.length();
+ const char* relstart = filepath.c_str() + rootpath.length();
if (*relstart == '/') relstart++; // won't be true when path == rootpath
String8 relpath(relstart);
@@ -514,9 +514,9 @@
int err = 0;
struct stat64 s;
- if (lstat64(filepath.string(), &s) != 0) {
+ if (lstat64(filepath.c_str(), &s) != 0) {
err = errno;
- ALOGE("Error %d (%s) from lstat64(%s)", err, strerror(err), filepath.string());
+ ALOGE("Error %d (%s) from lstat64(%s)", err, strerror(err), filepath.c_str());
return err;
}
@@ -541,10 +541,10 @@
// !!! TODO: use mmap when possible to avoid churning the buffer cache
// !!! TODO: this will break with symlinks; need to use readlink(2)
- int fd = open(filepath.string(), O_RDONLY);
+ int fd = open(filepath.c_str(), O_RDONLY);
if (fd < 0) {
err = errno;
- ALOGE("Error %d (%s) from open(%s)", err, strerror(err), filepath.string());
+ ALOGE("Error %d (%s) from open(%s)", err, strerror(err), filepath.c_str());
return err;
}
@@ -592,7 +592,7 @@
} else if (S_ISREG(s.st_mode)) {
type = '0'; // tar magic: '0' == normal file
} else {
- ALOGW("Error: unknown file mode 0%o [%s]", s.st_mode, filepath.string());
+ ALOGW("Error: unknown file mode 0%o [%s]", s.st_mode, filepath.c_str());
goto cleanup;
}
buf[156] = type;
@@ -620,16 +620,16 @@
// [ 345 : 155 ] filename path prefix
// We only use the prefix area if fullname won't fit in the path
if (fullname.length() > 100) {
- strncpy(buf, relpath.string(), 100);
- strncpy(buf + 345, prefix.string(), 155);
+ strncpy(buf, relpath.c_str(), 100);
+ strncpy(buf + 345, prefix.c_str(), 155);
} else {
- strncpy(buf, fullname.string(), 100);
+ strncpy(buf, fullname.c_str(), 100);
}
}
// [ 329 : 8 ] and [ 337 : 8 ] devmajor/devminor, not used
- ALOGI(" Name: %s", fullname.string());
+ ALOGI(" Name: %s", fullname.c_str());
// If we're using a pax extended header, build & write that here; lengths are
// already preflighted
@@ -647,7 +647,7 @@
// fullname was generated above with the ustar paths
paxLen += write_pax_header_entry(paxData + paxLen, PAXDATA_SIZE - paxLen,
- "path", fullname.string());
+ "path", fullname.c_str());
// Now we know how big the pax data is
@@ -656,9 +656,9 @@
String8 leaf = fullname.getPathLeaf();
memset(paxHeader, 0, 100); // rewrite the name area
- snprintf(paxHeader, 100, "PaxHeader/%s", leaf.string());
+ snprintf(paxHeader, 100, "PaxHeader/%s", leaf.c_str());
memset(paxHeader + 345, 0, 155); // rewrite the prefix area
- strncpy(paxHeader + 345, prefix.string(), 155);
+ strncpy(paxHeader + 345, prefix.c_str(), 155);
paxHeader[156] = 'x'; // mark it as a pax extended header
@@ -691,12 +691,12 @@
ssize_t nRead = read(fd, buf, toRead);
if (nRead < 0) {
err = errno;
- ALOGE("Unable to read file [%s], err=%d (%s)", filepath.string(),
+ ALOGE("Unable to read file [%s], err=%d (%s)", filepath.c_str(),
err, strerror(err));
break;
} else if (nRead == 0) {
ALOGE("EOF but expect %lld more bytes in [%s]", (long long) toWrite,
- filepath.string());
+ filepath.c_str());
err = EIO;
break;
}
@@ -762,7 +762,7 @@
file_metadata_v1 metadata;
amt = in->ReadEntityData(&metadata, sizeof(metadata));
if (amt != sizeof(metadata)) {
- ALOGW("Could not read metadata for %s -- %ld / %s", filename.string(),
+ ALOGW("Could not read metadata for %s -- %ld / %s", filename.c_str(),
(long)amt, strerror(errno));
return EIO;
}
@@ -779,9 +779,9 @@
// Write the file and compute the crc
crc = crc32(0L, Z_NULL, 0);
- fd = open(filename.string(), O_CREAT|O_RDWR|O_TRUNC, mode);
+ fd = open(filename.c_str(), O_CREAT|O_RDWR|O_TRUNC, mode);
if (fd == -1) {
- ALOGW("Could not open file %s -- %s", filename.string(), strerror(errno));
+ ALOGW("Could not open file %s -- %s", filename.c_str(), strerror(errno));
return errno;
}
@@ -789,7 +789,7 @@
err = write(fd, buf, amt);
if (err != amt) {
close(fd);
- ALOGW("Error '%s' writing '%s'", strerror(errno), filename.string());
+ ALOGW("Error '%s' writing '%s'", strerror(errno), filename.c_str());
return errno;
}
crc = crc32(crc, (Bytef*)buf, amt);
@@ -798,9 +798,9 @@
close(fd);
// Record for the snapshot
- err = stat(filename.string(), &st);
+ err = stat(filename.c_str(), &st);
if (err != 0) {
- ALOGW("Error stating file that we just created %s", filename.string());
+ ALOGW("Error stating file that we just created %s", filename.c_str());
return errno;
}
@@ -1104,9 +1104,9 @@
fprintf(stderr, "state %zu expected={%d/%d, %04o, 0x%08x, 0x%08x, %3zu} '%s'\n"
" actual={%d/%d, %04o, 0x%08x, 0x%08x, %3d} '%s'\n", i,
states[i].modTime_sec, states[i].modTime_nsec, states[i].mode, states[i].size,
- states[i].crc32, name.length(), filenames[i].string(),
+ states[i].crc32, name.length(), filenames[i].c_str(),
state.modTime_sec, state.modTime_nsec, state.mode, state.size, state.crc32,
- state.nameLen, name.string());
+ state.nameLen, name.c_str());
matched = false;
}
}
@@ -1152,9 +1152,9 @@
return err;
}
- err = writer.WriteEntityData(text.string(), text.length()+1);
+ err = writer.WriteEntityData(text.c_str(), text.length()+1);
if (err != 0) {
- fprintf(stderr, "write failed for data '%s'\n", text.string());
+ fprintf(stderr, "write failed for data '%s'\n", text.c_str());
return errno;
}
@@ -1230,7 +1230,7 @@
goto finished;
}
if (string != str) {
- fprintf(stderr, "ReadEntityHeader expected key '%s' got '%s'\n", str, string.string());
+ fprintf(stderr, "ReadEntityHeader expected key '%s' got '%s'\n", str, string.c_str());
err = EINVAL;
goto finished;
}
diff --git a/libs/androidfw/ConfigDescription.cpp b/libs/androidfw/ConfigDescription.cpp
index cf2fd6f..e08030c 100644
--- a/libs/androidfw/ConfigDescription.cpp
+++ b/libs/androidfw/ConfigDescription.cpp
@@ -905,7 +905,7 @@
std::string ConfigDescription::to_string() const {
const String8 str = toString();
- return std::string(str.string(), str.size());
+ return std::string(str.c_str(), str.size());
}
bool ConfigDescription::Dominates(const ConfigDescription& o) const {
diff --git a/libs/androidfw/CursorWindow.cpp b/libs/androidfw/CursorWindow.cpp
index 2a6dc7b..5e645cc 100644
--- a/libs/androidfw/CursorWindow.cpp
+++ b/libs/androidfw/CursorWindow.cpp
@@ -84,7 +84,7 @@
String8 ashmemName("CursorWindow: ");
ashmemName.append(mName);
- ashmemFd = ashmem_create_region(ashmemName.string(), mInflatedSize);
+ ashmemFd = ashmem_create_region(ashmemName.c_str(), mInflatedSize);
if (ashmemFd < 0) {
PLOG(ERROR) << "Failed ashmem_create_region";
goto fail_silent;
diff --git a/libs/androidfw/ObbFile.cpp b/libs/androidfw/ObbFile.cpp
index 95332a3..c6a9632 100644
--- a/libs/androidfw/ObbFile.cpp
+++ b/libs/androidfw/ObbFile.cpp
@@ -217,7 +217,7 @@
free(scanBuf);
#ifdef DEBUG
- ALOGI("Obb scan succeeded: packageName=%s, version=%d\n", mPackageName.string(), mVersion);
+ ALOGI("Obb scan succeeded: packageName=%s, version=%d\n", mPackageName.c_str(), mVersion);
#endif
return true;
@@ -288,7 +288,7 @@
return false;
}
- if (write(fd, mPackageName.string(), packageNameLen) != (ssize_t)packageNameLen) {
+ if (write(fd, mPackageName.c_str(), packageNameLen) != (ssize_t)packageNameLen) {
ALOGW("couldn't write package name: %s\n", strerror(errno));
return false;
}
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index 29d33da..c7a17af 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -1042,7 +1042,7 @@
if ((mHeader->flags&ResStringPool_header::UTF8_FLAG) != 0) {
if (kDebugStringPoolNoisy) {
- ALOGI("indexOfString UTF-8: %s", String8(str, strLen).string());
+ ALOGI("indexOfString UTF-8: %s", String8(str, strLen).c_str());
}
// The string pool contains UTF 8 strings; we don't want to cause
@@ -1103,7 +1103,7 @@
ALOGI("Looking at %s, i=%d\n", s->data(), i);
}
if (str8Len == s->size()
- && memcmp(s->data(), str8.string(), str8Len) == 0) {
+ && memcmp(s->data(), str8.c_str(), str8Len) == 0) {
if (kDebugStringPoolNoisy) {
ALOGI("MATCH!");
}
@@ -1115,7 +1115,7 @@
} else {
if (kDebugStringPoolNoisy) {
- ALOGI("indexOfString UTF-16: %s", String8(str, strLen).string());
+ ALOGI("indexOfString UTF-16: %s", String8(str, strLen).c_str());
}
if (mHeader->flags&ResStringPool_header::SORTED_FLAG) {
@@ -1133,7 +1133,7 @@
int c = s.has_value() ? strzcmp16(s->data(), s->size(), str, strLen) : -1;
if (kDebugStringPoolNoisy) {
ALOGI("Looking at %s, cmp=%d, l/mid/h=%d/%d/%d\n",
- String8(s->data(), s->size()).string(), c, (int)l, (int)mid, (int)h);
+ String8(s->data(), s->size()).c_str(), c, (int)l, (int)mid, (int)h);
}
if (c == 0) {
if (kDebugStringPoolNoisy) {
@@ -1157,7 +1157,7 @@
return base::unexpected(s.error());
}
if (kDebugStringPoolNoisy) {
- ALOGI("Looking at %s, i=%d\n", String8(s->data(), s->size()).string(), i);
+ ALOGI("Looking at %s, i=%d\n", String8(s->data(), s->size()).c_str(), i);
}
if (s.has_value() && strLen == s->size() &&
strzcmp16(s->data(), s->size(), str, strLen) == 0) {
@@ -1525,8 +1525,8 @@
{
String16 nsStr(ns != NULL ? ns : "");
String16 attrStr(attr);
- return indexOfAttribute(ns ? nsStr.string() : NULL, ns ? nsStr.size() : 0,
- attrStr.string(), attrStr.size());
+ return indexOfAttribute(ns ? nsStr.c_str() : NULL, ns ? nsStr.size() : 0,
+ attrStr.c_str(), attrStr.size());
}
ssize_t ResXMLParser::indexOfAttribute(const char16_t* ns, size_t nsLen,
@@ -1544,8 +1544,8 @@
}
attr8 = String8(attr, attrLen);
if (kDebugStringPoolNoisy) {
- ALOGI("indexOfAttribute UTF8 %s (%zu) / %s (%zu)", ns8.string(), nsLen,
- attr8.string(), attrLen);
+ ALOGI("indexOfAttribute UTF8 %s (%zu) / %s (%zu)", ns8.c_str(), nsLen,
+ attr8.c_str(), attrLen);
}
for (size_t i=0; i<N; i++) {
size_t curNsLen = 0, curAttrLen = 0;
@@ -1555,7 +1555,7 @@
ALOGI(" curNs=%s (%zu), curAttr=%s (%zu)", curNs, curNsLen, curAttr, curAttrLen);
}
if (curAttr != NULL && curNsLen == nsLen && curAttrLen == attrLen
- && memcmp(attr8.string(), curAttr, attrLen) == 0) {
+ && memcmp(attr8.c_str(), curAttr, attrLen) == 0) {
if (ns == NULL) {
if (curNs == NULL) {
if (kDebugStringPoolNoisy) {
@@ -1565,8 +1565,8 @@
}
} else if (curNs != NULL) {
//printf(" --> ns=%s, curNs=%s\n",
- // String8(ns).string(), String8(curNs).string());
- if (memcmp(ns8.string(), curNs, nsLen) == 0) {
+ // String8(ns).c_str(), String8(curNs).c_str());
+ if (memcmp(ns8.c_str(), curNs, nsLen) == 0) {
if (kDebugStringPoolNoisy) {
ALOGI(" FOUND!");
}
@@ -1578,8 +1578,8 @@
} else {
if (kDebugStringPoolNoisy) {
ALOGI("indexOfAttribute UTF16 %s (%zu) / %s (%zu)",
- String8(ns, nsLen).string(), nsLen,
- String8(attr, attrLen).string(), attrLen);
+ String8(ns, nsLen).c_str(), nsLen,
+ String8(attr, attrLen).c_str(), attrLen);
}
for (size_t i=0; i<N; i++) {
size_t curNsLen = 0, curAttrLen = 0;
@@ -1587,8 +1587,8 @@
const char16_t* curAttr = getAttributeName(i, &curAttrLen);
if (kDebugStringPoolNoisy) {
ALOGI(" curNs=%s (%zu), curAttr=%s (%zu)",
- String8(curNs, curNsLen).string(), curNsLen,
- String8(curAttr, curAttrLen).string(), curAttrLen);
+ String8(curNs, curNsLen).c_str(), curNsLen,
+ String8(curAttr, curAttrLen).c_str(), curAttrLen);
}
if (curAttr != NULL && curNsLen == nsLen && curAttrLen == attrLen
&& (memcmp(attr, curAttr, attrLen*sizeof(char16_t)) == 0)) {
@@ -1601,7 +1601,7 @@
}
} else if (curNs != NULL) {
//printf(" --> ns=%s, curNs=%s\n",
- // String8(ns).string(), String8(curNs).string());
+ // String8(ns).c_str(), String8(curNs).c_str());
if (memcmp(ns, curNs, nsLen*sizeof(char16_t)) == 0) {
if (kDebugStringPoolNoisy) {
ALOGI(" FOUND!");
@@ -4458,7 +4458,7 @@
return false;
}
- outName->package = grp->name.string();
+ outName->package = grp->name.c_str();
outName->packageLen = grp->name.size();
if (allowUtf8) {
outName->type8 = UnpackOptionalString(entry.typeStr.string8(), &outName->typeLen);
@@ -4558,7 +4558,7 @@
outValue->dataType,
outValue->dataType == Res_value::TYPE_STRING ?
String8(UnpackOptionalString(
- entry.package->header->values.stringAt(outValue->data), &len)).string() :
+ entry.package->header->values.stringAt(outValue->data), &len)).c_str() :
"",
outValue->data);
}
@@ -4927,7 +4927,7 @@
AutoMutex _lock2(mFilteredConfigLock);
if (kDebugTableGetEntry) {
- ALOGI("Setting parameters: %s\n", params->toString().string());
+ ALOGI("Setting parameters: %s\n", params->toString().c_str());
}
mParams = *params;
for (size_t p = 0; p < mPackageGroups.size(); p++) {
@@ -5038,7 +5038,7 @@
if (name[1] == 'i' && name[2] == 'n'
&& name[3] == 'd' && name[4] == 'e' && name[5] == 'x'
&& name[6] == '_') {
- int index = atoi(String8(name + 7, nameLen - 7).string());
+ int index = atoi(String8(name + 7, nameLen - 7).c_str());
if (Res_CHECKID(index)) {
ALOGW("Array resource index: %d is too large.",
index);
@@ -5104,9 +5104,9 @@
if (kDebugTableNoisy) {
printf("Looking for identifier: type=%s, name=%s, package=%s\n",
- String8(type, typeLen).string(),
- String8(name, nameLen).string(),
- String8(package, packageLen).string());
+ String8(type, typeLen).c_str(),
+ String8(name, nameLen).c_str(),
+ String8(package, packageLen).c_str());
}
const String16 attr("attr");
@@ -5117,9 +5117,9 @@
const PackageGroup* group = mPackageGroups[ig];
if (strzcmp16(package, packageLen,
- group->name.string(), group->name.size())) {
+ group->name.c_str(), group->name.size())) {
if (kDebugTableNoisy) {
- printf("Skipping package group: %s\n", String8(group->name).string());
+ printf("Skipping package group: %s\n", String8(group->name).c_str());
}
continue;
}
@@ -5144,8 +5144,8 @@
}
return identifier;
}
- } while (strzcmp16(attr.string(), attr.size(), targetType, targetTypeLen) == 0
- && (targetType = attrPrivate.string())
+ } while (strzcmp16(attr.c_str(), attr.size(), targetType, targetTypeLen) == 0
+ && (targetType = attrPrivate.c_str())
&& (targetTypeLen = attrPrivate.size())
);
}
@@ -5564,7 +5564,7 @@
}
}
- //printf("Value for: %s\n", String8(s, len).string());
+ //printf("Value for: %s\n", String8(s, len).c_str());
uint32_t l10nReq = ResTable_map::L10N_NOT_REQUIRED;
uint32_t attrMin = 0x80000000, attrMax = 0x7fffffff;
@@ -5619,7 +5619,7 @@
// be to any other type; we just need to count on the client making
// sure the referenced type is correct.
- //printf("Looking up ref: %s\n", String8(s, len).string());
+ //printf("Looking up ref: %s\n", String8(s, len).c_str());
// It's a reference!
if (len == 5 && s[1]=='n' && s[2]=='u' && s[3]=='l' && s[4]=='l') {
@@ -5659,8 +5659,8 @@
}
uint32_t specFlags = 0;
- uint32_t rid = identifierForName(name.string(), name.size(), type.string(),
- type.size(), package.string(), package.size(), &specFlags);
+ uint32_t rid = identifierForName(name.c_str(), name.size(), type.c_str(),
+ type.size(), package.c_str(), package.size(), &specFlags);
if (rid != 0) {
if (enforcePrivate) {
if (accessor == NULL || accessor->getAssetsPackage() != package) {
@@ -5679,8 +5679,8 @@
Res_GETTYPE(rid), Res_GETENTRY(rid));
if (kDebugTableNoisy) {
ALOGI("Incl %s:%s/%s: 0x%08x\n",
- String8(package).string(), String8(type).string(),
- String8(name).string(), rid);
+ String8(package).c_str(), String8(type).c_str(),
+ String8(name).c_str(), rid);
}
}
@@ -5698,8 +5698,8 @@
if (rid != 0) {
if (kDebugTableNoisy) {
ALOGI("Pckg %s:%s/%s: 0x%08x\n",
- String8(package).string(), String8(type).string(),
- String8(name).string(), rid);
+ String8(package).c_str(), String8(type).c_str(),
+ String8(name).c_str(), rid);
}
uint32_t packageId = Res_GETPACKAGE(rid) + 1;
if (packageId == 0x00) {
@@ -5788,7 +5788,7 @@
}
} else {
outValue->data = color;
- //printf("Color input=%s, output=0x%x\n", String8(s, len).string(), color);
+ //printf("Color input=%s, output=0x%x\n", String8(s, len).c_str(), color);
return true;
}
} else {
@@ -5800,8 +5800,8 @@
#if 0
fprintf(stderr, "%s: Color ID %s value %s is not valid\n",
"Resource File", //(const char*)in->getPrintableSource(),
- String8(*curTag).string(),
- String8(s, len).string());
+ String8(*curTag).c_str(),
+ String8(s, len).c_str());
#endif
return false;
}
@@ -5815,7 +5815,7 @@
// be to any other type; we just need to count on the client making
// sure the referenced type is correct.
- //printf("Looking up attr: %s\n", String8(s, len).string());
+ //printf("Looking up attr: %s\n", String8(s, len).c_str());
static const String16 attr16("attr");
String16 package, type, name;
@@ -5828,13 +5828,13 @@
}
//printf("Pkg: %s, Type: %s, Name: %s\n",
- // String8(package).string(), String8(type).string(),
- // String8(name).string());
+ // String8(package).c_str(), String8(type).c_str(),
+ // String8(name).c_str());
uint32_t specFlags = 0;
uint32_t rid =
- identifierForName(name.string(), name.size(),
- type.string(), type.size(),
- package.string(), package.size(), &specFlags);
+ identifierForName(name.c_str(), name.size(),
+ type.c_str(), type.size(),
+ package.c_str(), package.size(), &specFlags);
if (rid != 0) {
if (enforcePrivate) {
if ((specFlags&ResTable_typeSpec::SPEC_PUBLIC) == 0) {
@@ -5992,8 +5992,8 @@
if (getResourceName(bag->map.name.ident, false, &rname)) {
#if 0
printf("Matching %s against %s (0x%08x)\n",
- String8(s, len).string(),
- String8(rname.name, rname.nameLen).string(),
+ String8(s, len).c_str(),
+ String8(rname.name, rname.nameLen).c_str(),
bag->map.name.ident);
#endif
if (strzcmp16(s, len, rname.name, rname.nameLen) == 0) {
@@ -6036,7 +6036,7 @@
while (pos < end && *pos != '|') {
pos++;
}
- //printf("Looking for: %s\n", String8(start, pos-start).string());
+ //printf("Looking for: %s\n", String8(start, pos-start).c_str());
const bag_entry* bagi = bag;
ssize_t i;
for (i=0; i<cnt; i++, bagi++) {
@@ -6045,8 +6045,8 @@
if (getResourceName(bagi->map.name.ident, false, &rname)) {
#if 0
printf("Matching %s against %s (0x%08x)\n",
- String8(start,pos-start).string(),
- String8(rname.name, rname.nameLen).string(),
+ String8(start,pos-start).c_str(),
+ String8(rname.name, rname.nameLen).c_str(),
bagi->map.name.ident);
#endif
if (strzcmp16(start, pos-start, rname.name, rname.nameLen) == 0) {
@@ -6373,7 +6373,7 @@
}
static bool compareString8AndCString(const String8& str, const char* cStr) {
- return strcmp(str.string(), cStr) < 0;
+ return strcmp(str.c_str(), cStr) < 0;
}
void ResTable::getLocales(Vector<String8>* locales, bool includeSystemLocales,
@@ -6387,7 +6387,7 @@
const auto endIter = locales->end();
auto iter = std::lower_bound(beginIter, endIter, locale, compareString8AndCString);
- if (iter == endIter || strcmp(iter->string(), locale) != 0) {
+ if (iter == endIter || strcmp(iter->c_str(), locale) != 0) {
locales->insertAt(String8(locale), std::distance(beginIter, iter));
}
});
@@ -6984,7 +6984,7 @@
ResTable_config thisConfig;
thisConfig.copyFromDtoH(type->config);
ALOGI("Adding config to type %d: %s\n", type->id,
- thisConfig.toString().string());
+ thisConfig.toString().c_str());
}
}
} else {
@@ -7061,7 +7061,7 @@
char16_t tmpName[sizeof(entry->packageName) / sizeof(char16_t)];
strcpy16_dtoh(tmpName, entry->packageName, sizeof(entry->packageName) / sizeof(char16_t));
if (kDebugLibNoisy) {
- ALOGV("Found lib entry %s with id %d\n", String8(tmpName).string(),
+ ALOGV("Found lib entry %s with id %d\n", String8(tmpName).c_str(),
dtohl(entry->packageId));
}
if (packageId >= 256) {
@@ -7340,7 +7340,7 @@
current_res.nameLen,
current_res.type,
current_res.typeLen,
- targetPackageName.string(),
+ targetPackageName.c_str(),
targetPackageName.size(),
&typeSpecFlags);
@@ -7447,7 +7447,7 @@
}
-#define CHAR16_TO_CSTR(c16, len) (String8(String16(c16,len)).string())
+#define CHAR16_TO_CSTR(c16, len) (String8(String16(c16,len)).c_str())
#define CHAR16_ARRAY_EQ(constant, var, len) \
(((len) == (sizeof(constant)/sizeof((constant)[0]))) && (0 == memcmp((var), (constant), (len))))
@@ -7542,13 +7542,13 @@
const char* str8 = UnpackOptionalString(pkg->header->values.string8At(
value.data), &len);
if (str8 != NULL) {
- printf("(string8) \"%s\"\n", normalizeForOutput(str8).string());
+ printf("(string8) \"%s\"\n", normalizeForOutput(str8).c_str());
} else {
const char16_t* str16 = UnpackOptionalString(pkg->header->values.stringAt(
value.data), &len);
if (str16 != NULL) {
printf("(string16) \"%s\"\n",
- normalizeForOutput(String8(str16, len).string()).string());
+ normalizeForOutput(String8(str16, len).c_str()).c_str());
} else {
printf("(string) null\n");
}
@@ -7589,7 +7589,7 @@
const PackageGroup* pg = mPackageGroups[pgIndex];
printf("Package Group %d id=0x%02x packageCount=%d name=%s\n",
(int)pgIndex, pg->id, (int)pg->packages.size(),
- String8(pg->name).string());
+ String8(pg->name).c_str());
const KeyedVector<String16, uint8_t>& refEntries = pg->dynamicRefTable.entries();
const size_t refEntryCount = refEntries.size();
@@ -7598,7 +7598,7 @@
for (size_t refIndex = 0; refIndex < refEntryCount; refIndex++) {
printf(" 0x%02x -> %s\n",
refEntries.valueAt(refIndex),
- String8(refEntries.keyAt(refIndex)).string());
+ String8(refEntries.keyAt(refIndex)).c_str());
}
printf("\n");
}
@@ -7624,7 +7624,7 @@
strcpy16_dtoh(tmpName, pkg->package->name,
sizeof(pkg->package->name)/sizeof(pkg->package->name[0]));
printf(" Package %d id=0x%02x name=%s\n", (int)pkgIndex,
- pkg->package->id, String8(tmpName).string());
+ pkg->package->id, String8(tmpName).c_str());
}
for (size_t typeIndex = 0; typeIndex < pg->types.size(); typeIndex++) {
@@ -7666,7 +7666,7 @@
printf(" spec resource 0x%08x %s:%s/%s: flags=0x%08x\n",
resID,
CHAR16_TO_CSTR(resName.package, resName.packageLen),
- type8.string(), name8.string(),
+ type8.c_str(), name8.c_str(),
dtohl(typeConfigs->typeSpecFlags[entryIndex]));
} else {
printf(" INVALID TYPE CONFIG FOR RESOURCE 0x%08x\n", resID);
@@ -7687,7 +7687,7 @@
String8 configStr = thisConfig.toString();
printf(" config %s", configStr.size() > 0
- ? configStr.string() : "(default)");
+ ? configStr.c_str() : "(default)");
if (type->flags != 0u) {
printf(" flags=0x%02x", type->flags);
if (type->flags & ResTable_type::FLAG_SPARSE) {
@@ -7761,7 +7761,7 @@
}
printf(" resource 0x%08x %s:%s/%s: ", resID,
CHAR16_TO_CSTR(resName.package, resName.packageLen),
- type8.string(), name8.string());
+ type8.c_str(), name8.c_str());
} else {
printf(" INVALID RESOURCE 0x%08x: ", resID);
}
diff --git a/libs/androidfw/include/androidfw/Asset.h b/libs/androidfw/include/androidfw/Asset.h
index 19febcd..f3776b5 100644
--- a/libs/androidfw/include/androidfw/Asset.h
+++ b/libs/androidfw/include/androidfw/Asset.h
@@ -135,7 +135,7 @@
* This is NOT intended to be used for anything except debug output.
* DO NOT try to parse this or use it to open a file.
*/
- const char* getAssetSource(void) const { return mAssetSource.string(); }
+ const char* getAssetSource(void) const { return mAssetSource.c_str(); }
/*
* Create the asset from a file descriptor.
diff --git a/libs/androidfw/include/androidfw/ConfigDescription.h b/libs/androidfw/include/androidfw/ConfigDescription.h
index 7fbd7c0..83a80ce 100644
--- a/libs/androidfw/include/androidfw/ConfigDescription.h
+++ b/libs/androidfw/include/androidfw/ConfigDescription.h
@@ -213,7 +213,7 @@
inline ::std::ostream& operator<<(::std::ostream& out,
const ConfigDescription& o) {
- return out << o.toString().string();
+ return out << o.toString().c_str();
}
} // namespace android
diff --git a/libs/androidfw/tests/BackupData_test.cpp b/libs/androidfw/tests/BackupData_test.cpp
index e25b616..7d3a341 100644
--- a/libs/androidfw/tests/BackupData_test.cpp
+++ b/libs/androidfw/tests/BackupData_test.cpp
@@ -56,10 +56,10 @@
mFilename.append(m_external_storage);
mFilename.append(TEST_FILENAME);
- ::unlink(mFilename.string());
- int fd = ::open(mFilename.string(), O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
+ ::unlink(mFilename.c_str());
+ int fd = ::open(mFilename.c_str(), O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
if (fd < 0) {
- FAIL() << "Couldn't create " << mFilename.string() << " for writing";
+ FAIL() << "Couldn't create " << mFilename.c_str() << " for writing";
}
mKey1 = String8(KEY1);
mKey2 = String8(KEY2);
@@ -72,7 +72,7 @@
};
TEST_F(BackupDataTest, WriteAndReadSingle) {
- int fd = ::open(mFilename.string(), O_WRONLY);
+ int fd = ::open(mFilename.c_str(), O_WRONLY);
BackupDataWriter* writer = new BackupDataWriter(fd);
EXPECT_EQ(NO_ERROR, writer->WriteEntityHeader(mKey1, sizeof(DATA1)))
@@ -81,7 +81,7 @@
<< "WriteEntityData returned an error";
::close(fd);
- fd = ::open(mFilename.string(), O_RDONLY);
+ fd = ::open(mFilename.c_str(), O_RDONLY);
BackupDataReader* reader = new BackupDataReader(fd);
EXPECT_EQ(NO_ERROR, reader->Status())
<< "Reader ctor failed";
@@ -114,7 +114,7 @@
}
TEST_F(BackupDataTest, WriteAndReadMultiple) {
- int fd = ::open(mFilename.string(), O_WRONLY);
+ int fd = ::open(mFilename.c_str(), O_WRONLY);
BackupDataWriter* writer = new BackupDataWriter(fd);
writer->WriteEntityHeader(mKey1, sizeof(DATA1));
writer->WriteEntityData(DATA1, sizeof(DATA1));
@@ -122,7 +122,7 @@
writer->WriteEntityData(DATA2, sizeof(DATA2));
::close(fd);
- fd = ::open(mFilename.string(), O_RDONLY);
+ fd = ::open(mFilename.c_str(), O_RDONLY);
BackupDataReader* reader = new BackupDataReader(fd);
bool done;
@@ -162,7 +162,7 @@
}
TEST_F(BackupDataTest, SkipEntity) {
- int fd = ::open(mFilename.string(), O_WRONLY);
+ int fd = ::open(mFilename.c_str(), O_WRONLY);
BackupDataWriter* writer = new BackupDataWriter(fd);
writer->WriteEntityHeader(mKey1, sizeof(DATA1));
writer->WriteEntityData(DATA1, sizeof(DATA1));
@@ -172,7 +172,7 @@
writer->WriteEntityData(DATA3, sizeof(DATA3));
::close(fd);
- fd = ::open(mFilename.string(), O_RDONLY);
+ fd = ::open(mFilename.c_str(), O_RDONLY);
BackupDataReader* reader = new BackupDataReader(fd);
bool done;
@@ -217,14 +217,14 @@
}
TEST_F(BackupDataTest, DeleteEntity) {
- int fd = ::open(mFilename.string(), O_WRONLY);
+ int fd = ::open(mFilename.c_str(), O_WRONLY);
BackupDataWriter* writer = new BackupDataWriter(fd);
writer->WriteEntityHeader(mKey1, sizeof(DATA1));
writer->WriteEntityData(DATA1, sizeof(DATA1));
writer->WriteEntityHeader(mKey2, -1);
::close(fd);
- fd = ::open(mFilename.string(), O_RDONLY);
+ fd = ::open(mFilename.c_str(), O_RDONLY);
BackupDataReader* reader = new BackupDataReader(fd);
bool done;
@@ -256,7 +256,7 @@
}
TEST_F(BackupDataTest, EneityAfterDelete) {
- int fd = ::open(mFilename.string(), O_WRONLY);
+ int fd = ::open(mFilename.c_str(), O_WRONLY);
BackupDataWriter* writer = new BackupDataWriter(fd);
writer->WriteEntityHeader(mKey1, sizeof(DATA1));
writer->WriteEntityData(DATA1, sizeof(DATA1));
@@ -265,7 +265,7 @@
writer->WriteEntityData(DATA3, sizeof(DATA3));
::close(fd);
- fd = ::open(mFilename.string(), O_RDONLY);
+ fd = ::open(mFilename.c_str(), O_RDONLY);
BackupDataReader* reader = new BackupDataReader(fd);
bool done;
@@ -317,7 +317,7 @@
}
TEST_F(BackupDataTest, OnlyDeleteEntities) {
- int fd = ::open(mFilename.string(), O_WRONLY);
+ int fd = ::open(mFilename.c_str(), O_WRONLY);
BackupDataWriter* writer = new BackupDataWriter(fd);
writer->WriteEntityHeader(mKey1, -1);
writer->WriteEntityHeader(mKey2, -1);
@@ -325,7 +325,7 @@
writer->WriteEntityHeader(mKey4, -1);
::close(fd);
- fd = ::open(mFilename.string(), O_RDONLY);
+ fd = ::open(mFilename.c_str(), O_RDONLY);
BackupDataReader* reader = new BackupDataReader(fd);
bool done;
@@ -385,13 +385,13 @@
}
TEST_F(BackupDataTest, ReadDeletedEntityData) {
- int fd = ::open(mFilename.string(), O_WRONLY);
+ int fd = ::open(mFilename.c_str(), O_WRONLY);
BackupDataWriter* writer = new BackupDataWriter(fd);
writer->WriteEntityHeader(mKey1, -1);
writer->WriteEntityHeader(mKey2, -1);
::close(fd);
- fd = ::open(mFilename.string(), O_RDONLY);
+ fd = ::open(mFilename.c_str(), O_RDONLY);
BackupDataReader* reader = new BackupDataReader(fd);
bool done;
diff --git a/libs/androidfw/tests/CommonHelpers.cpp b/libs/androidfw/tests/CommonHelpers.cpp
index 3396729..10138de 100644
--- a/libs/androidfw/tests/CommonHelpers.cpp
+++ b/libs/androidfw/tests/CommonHelpers.cpp
@@ -60,7 +60,7 @@
std::string GetStringFromPool(const ResStringPool* pool, uint32_t idx) {
auto str = pool->string8ObjectAt(idx);
CHECK(str.has_value()) << "failed to find string entry";
- return std::string(str->string(), str->length());
+ return std::string(str->c_str(), str->length());
}
} // namespace android
diff --git a/libs/androidfw/tests/ConfigDescription_test.cpp b/libs/androidfw/tests/ConfigDescription_test.cpp
index f5c01e5..ec478b0 100644
--- a/libs/androidfw/tests/ConfigDescription_test.cpp
+++ b/libs/androidfw/tests/ConfigDescription_test.cpp
@@ -50,10 +50,10 @@
TEST(ConfigDescriptionTest, ParseBasicQualifiers) {
ConfigDescription config;
EXPECT_TRUE(TestParse("", &config));
- EXPECT_EQ(std::string(""), config.toString().string());
+ EXPECT_EQ(std::string(""), config.toString().c_str());
EXPECT_TRUE(TestParse("fr-land", &config));
- EXPECT_EQ(std::string("fr-land"), config.toString().string());
+ EXPECT_EQ(std::string("fr-land"), config.toString().c_str());
EXPECT_TRUE(
TestParse("mcc310-pl-sw720dp-normal-long-port-night-"
@@ -61,22 +61,22 @@
&config));
EXPECT_EQ(std::string("mcc310-pl-sw720dp-normal-long-port-night-"
"xhdpi-keyssoft-qwerty-navexposed-nonav-v13"),
- config.toString().string());
+ config.toString().c_str());
}
TEST(ConfigDescriptionTest, ParseLocales) {
ConfigDescription config;
EXPECT_TRUE(TestParse("en-rUS", &config));
- EXPECT_EQ(std::string("en-rUS"), config.toString().string());
+ EXPECT_EQ(std::string("en-rUS"), config.toString().c_str());
}
TEST(ConfigDescriptionTest, ParseQualifierAddedInApi13) {
ConfigDescription config;
EXPECT_TRUE(TestParse("sw600dp", &config));
- EXPECT_EQ(std::string("sw600dp-v13"), config.toString().string());
+ EXPECT_EQ(std::string("sw600dp-v13"), config.toString().c_str());
EXPECT_TRUE(TestParse("sw600dp-v8", &config));
- EXPECT_EQ(std::string("sw600dp-v13"), config.toString().string());
+ EXPECT_EQ(std::string("sw600dp-v13"), config.toString().c_str());
}
TEST(ConfigDescriptionTest, ParseCarAttribute) {
@@ -91,13 +91,13 @@
EXPECT_EQ(android::ResTable_config::SCREENROUND_YES,
config.screenLayout2 & android::ResTable_config::MASK_SCREENROUND);
EXPECT_EQ(SDK_MARSHMALLOW, config.sdkVersion);
- EXPECT_EQ(std::string("round-v23"), config.toString().string());
+ EXPECT_EQ(std::string("round-v23"), config.toString().c_str());
EXPECT_TRUE(TestParse("notround", &config));
EXPECT_EQ(android::ResTable_config::SCREENROUND_NO,
config.screenLayout2 & android::ResTable_config::MASK_SCREENROUND);
EXPECT_EQ(SDK_MARSHMALLOW, config.sdkVersion);
- EXPECT_EQ(std::string("notround-v23"), config.toString().string());
+ EXPECT_EQ(std::string("notround-v23"), config.toString().c_str());
}
TEST(ConfigDescriptionTest, TestWideColorGamutQualifier) {
@@ -106,13 +106,13 @@
EXPECT_EQ(android::ResTable_config::WIDE_COLOR_GAMUT_YES,
config.colorMode & android::ResTable_config::MASK_WIDE_COLOR_GAMUT);
EXPECT_EQ(SDK_O, config.sdkVersion);
- EXPECT_EQ(std::string("widecg-v26"), config.toString().string());
+ EXPECT_EQ(std::string("widecg-v26"), config.toString().c_str());
EXPECT_TRUE(TestParse("nowidecg", &config));
EXPECT_EQ(android::ResTable_config::WIDE_COLOR_GAMUT_NO,
config.colorMode & android::ResTable_config::MASK_WIDE_COLOR_GAMUT);
EXPECT_EQ(SDK_O, config.sdkVersion);
- EXPECT_EQ(std::string("nowidecg-v26"), config.toString().string());
+ EXPECT_EQ(std::string("nowidecg-v26"), config.toString().c_str());
}
TEST(ConfigDescriptionTest, TestHdrQualifier) {
@@ -121,13 +121,13 @@
EXPECT_EQ(android::ResTable_config::HDR_YES,
config.colorMode & android::ResTable_config::MASK_HDR);
EXPECT_EQ(SDK_O, config.sdkVersion);
- EXPECT_EQ(std::string("highdr-v26"), config.toString().string());
+ EXPECT_EQ(std::string("highdr-v26"), config.toString().c_str());
EXPECT_TRUE(TestParse("lowdr", &config));
EXPECT_EQ(android::ResTable_config::HDR_NO,
config.colorMode & android::ResTable_config::MASK_HDR);
EXPECT_EQ(SDK_O, config.sdkVersion);
- EXPECT_EQ(std::string("lowdr-v26"), config.toString().string());
+ EXPECT_EQ(std::string("lowdr-v26"), config.toString().c_str());
}
TEST(ConfigDescriptionTest, ParseVrAttribute) {
@@ -135,7 +135,7 @@
EXPECT_TRUE(TestParse("vrheadset", &config));
EXPECT_EQ(android::ResTable_config::UI_MODE_TYPE_VR_HEADSET, config.uiMode);
EXPECT_EQ(SDK_O, config.sdkVersion);
- EXPECT_EQ(std::string("vrheadset-v26"), config.toString().string());
+ EXPECT_EQ(std::string("vrheadset-v26"), config.toString().c_str());
}
static inline ConfigDescription ParseConfigOrDie(android::StringPiece str) {
diff --git a/libs/androidfw/tests/ObbFile_test.cpp b/libs/androidfw/tests/ObbFile_test.cpp
index 1151121..ba818c4 100644
--- a/libs/androidfw/tests/ObbFile_test.cpp
+++ b/libs/androidfw/tests/ObbFile_test.cpp
@@ -43,9 +43,9 @@
mFileName.append(externalStorage);
mFileName.append(TEST_FILENAME);
- int fd = ::open(mFileName.string(), O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
+ int fd = ::open(mFileName.c_str(), O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
if (fd < 0) {
- FAIL() << "Couldn't create " << mFileName.string() << " for tests";
+ FAIL() << "Couldn't create " << mFileName.c_str() << " for tests";
}
}
@@ -69,17 +69,17 @@
EXPECT_TRUE(mObbFile->setSalt(salt, SALT_SIZE))
<< "Salt should be successfully set";
- EXPECT_TRUE(mObbFile->writeTo(mFileName.string()))
+ EXPECT_TRUE(mObbFile->writeTo(mFileName.c_str()))
<< "couldn't write to fake .obb file";
mObbFile = new ObbFile();
- EXPECT_TRUE(mObbFile->readFrom(mFileName.string()))
+ EXPECT_TRUE(mObbFile->readFrom(mFileName.c_str()))
<< "couldn't read from fake .obb file";
EXPECT_EQ(versionNum, mObbFile->getVersion())
<< "version didn't come out the same as it went in";
- const char* currentPackageName = mObbFile->getPackageName().string();
+ const char* currentPackageName = mObbFile->getPackageName().c_str();
EXPECT_STREQ(packageName, currentPackageName)
<< "package name didn't come out the same as it went in";
diff --git a/libs/androidfw/tests/ResTable_test.cpp b/libs/androidfw/tests/ResTable_test.cpp
index fbf7098..945981b 100644
--- a/libs/androidfw/tests/ResTable_test.cpp
+++ b/libs/androidfw/tests/ResTable_test.cpp
@@ -64,8 +64,8 @@
String16 defPackage("com.android.basic");
String16 testName("@string/test1");
uint32_t resID =
- table.identifierForName(testName.string(), testName.size(), 0, 0,
- defPackage.string(), defPackage.size());
+ table.identifierForName(testName.c_str(), testName.size(), 0, 0,
+ defPackage.c_str(), defPackage.size());
ASSERT_NE(uint32_t(0x00000000), resID);
ASSERT_EQ(basic::R::string::test1, resID);
}
diff --git a/libs/androidfw/tests/Split_test.cpp b/libs/androidfw/tests/Split_test.cpp
index 2c242db..3d88577 100644
--- a/libs/androidfw/tests/Split_test.cpp
+++ b/libs/androidfw/tests/Split_test.cpp
@@ -261,8 +261,8 @@
const String16 package("com.android.basic");
ASSERT_EQ(
R::string::test3,
- table.identifierForName(name.string(), name.size(), type.string(),
- type.size(), package.string(), package.size()));
+ table.identifierForName(name.c_str(), name.size(), type.c_str(),
+ type.size(), package.c_str(), package.size()));
}
} // namespace
diff --git a/libs/androidfw/tests/TestHelpers.cpp b/libs/androidfw/tests/TestHelpers.cpp
index 10c0a4f..c6f657c 100644
--- a/libs/androidfw/tests/TestHelpers.cpp
+++ b/libs/androidfw/tests/TestHelpers.cpp
@@ -79,9 +79,9 @@
}
if (String8(expected_str) != *actual_str) {
- return AssertionFailure() << actual_str->string();
+ return AssertionFailure() << actual_str->c_str();
}
- return AssertionSuccess() << actual_str->string();
+ return AssertionSuccess() << actual_str->c_str();
}
} // namespace android
diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h
index d1e04ad..d27c428c 100644
--- a/libs/hwui/RenderNode.h
+++ b/libs/hwui/RenderNode.h
@@ -114,7 +114,7 @@
return mDisplayList.containsProjectionReceiver();
}
- const char* getName() const { return mName.string(); }
+ const char* getName() const { return mName.c_str(); }
void setName(const char* name) {
if (name) {
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
index b020e96..cb23bcc 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
@@ -200,7 +200,7 @@
String8 cachesOutput;
mRenderThread.cacheManager().dumpMemoryUsage(cachesOutput,
&mRenderThread.renderState());
- ALOGE("%s", cachesOutput.string());
+ ALOGE("%s", cachesOutput.c_str());
if (errorHandler) {
std::ostringstream err;
err << "Unable to create layer for " << node->getName();
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index eb28c08..0dea941 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -357,7 +357,7 @@
String8 cachesOutput;
mCacheManager->dumpMemoryUsage(cachesOutput, mRenderState);
- dprintf(fd, "\nPipeline=%s\n%s\n", pipelineToString(), cachesOutput.string());
+ dprintf(fd, "\nPipeline=%s\n%s\n", pipelineToString(), cachesOutput.c_str());
}
void RenderThread::getMemoryUsage(size_t* cpuUsage, size_t* gpuUsage) {
diff --git a/libs/hwui/utils/LinearAllocator.cpp b/libs/hwui/utils/LinearAllocator.cpp
index 8baa4b77..eab888e 100644
--- a/libs/hwui/utils/LinearAllocator.cpp
+++ b/libs/hwui/utils/LinearAllocator.cpp
@@ -31,15 +31,11 @@
#include <utils/Log.h>
#include <utils/Macros.h>
-// The ideal size of a page allocation (these need to be multiples of 8)
-#define INITIAL_PAGE_SIZE ((size_t)512) // 512b
-#define MAX_PAGE_SIZE ((size_t)131072) // 128kb
-
// The maximum amount of wasted space we can have per page
// Allocations exceeding this will have their own dedicated page
// If this is too low, we will malloc too much
// Too high, and we may waste too much space
-// Must be smaller than INITIAL_PAGE_SIZE
+// Must be smaller than kInitialPageSize
#define MAX_WASTE_RATIO (0.5f)
#if LOG_NDEBUG
@@ -75,6 +71,10 @@
namespace android {
namespace uirenderer {
+// The ideal size of a page allocation (these need to be multiples of 8)
+static constexpr size_t kInitialPageSize = 512; // 512b
+static constexpr size_t kMaxPageSize = 131072; // 128kb
+
class LinearAllocator::Page {
public:
Page* next() { return mNextPage; }
@@ -94,8 +94,8 @@
};
LinearAllocator::LinearAllocator()
- : mPageSize(INITIAL_PAGE_SIZE)
- , mMaxAllocSize(INITIAL_PAGE_SIZE * MAX_WASTE_RATIO)
+ : mPageSize(kInitialPageSize)
+ , mMaxAllocSize(kInitialPageSize * MAX_WASTE_RATIO)
, mNext(0)
, mCurrentPage(0)
, mPages(0)
@@ -135,8 +135,8 @@
void LinearAllocator::ensureNext(size_t size) {
if (fitsInCurrentPage(size)) return;
- if (mCurrentPage && mPageSize < MAX_PAGE_SIZE) {
- mPageSize = min(MAX_PAGE_SIZE, mPageSize * 2);
+ if (mCurrentPage && mPageSize < kMaxPageSize) {
+ mPageSize = min(kMaxPageSize, mPageSize * 2);
mMaxAllocSize = mPageSize * MAX_WASTE_RATIO;
mPageSize = ALIGN(mPageSize);
}
diff --git a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2ManagerTest.java b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2ManagerTest.java
index 4193ffa..3d448a8 100644
--- a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2ManagerTest.java
+++ b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2ManagerTest.java
@@ -918,7 +918,7 @@
CountDownLatch addedLatch = new CountDownLatch(1);
CountDownLatch preferenceLatch = new CountDownLatch(1);
- // A dummy callback is required to send route feature info.
+ // A placeholder callback is required to send route feature info.
RouteCallback routeCallback = new RouteCallback() {};
MediaRouter2Manager.Callback managerCallback =
new MediaRouter2Manager.Callback() {
diff --git a/packages/CtsShim/build/Android.bp b/packages/CtsShim/build/Android.bp
index d778feb..d6b7ecf 100644
--- a/packages/CtsShim/build/Android.bp
+++ b/packages/CtsShim/build/Android.bp
@@ -208,3 +208,22 @@
],
min_sdk_version: "24",
}
+
+//##########################################################
+// Variant: Add apk to an apex
+android_app {
+ name: "CtsShimAddApkToApex",
+ sdk_version: "current",
+ srcs: ["shim_add_apk_to_apex/src/android/addapktoapex/app/AddApkToApexDeviceActivity.java"],
+ optimize: {
+ enabled: false,
+ },
+ dex_preopt: {
+ enabled: false,
+ },
+ manifest: "shim_add_apk_to_apex/AndroidManifestAddApkToApex.xml",
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.apex.cts.shim.v2_add_apk_to_apex",
+ ],
+}
diff --git a/packages/CtsShim/build/shim_add_apk_to_apex/AndroidManifestAddApkToApex.xml b/packages/CtsShim/build/shim_add_apk_to_apex/AndroidManifestAddApkToApex.xml
new file mode 100644
index 0000000..0e620b0
--- /dev/null
+++ b/packages/CtsShim/build/shim_add_apk_to_apex/AndroidManifestAddApkToApex.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2023 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="android.addapktoapex.app">
+
+ <application>
+ <activity android:name=".AddApkToApexDeviceActivity"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
\ No newline at end of file
diff --git a/packages/CtsShim/build/shim_add_apk_to_apex/src/android/addapktoapex/app/AddApkToApexDeviceActivity.java b/packages/CtsShim/build/shim_add_apk_to_apex/src/android/addapktoapex/app/AddApkToApexDeviceActivity.java
new file mode 100644
index 0000000..c68904b
--- /dev/null
+++ b/packages/CtsShim/build/shim_add_apk_to_apex/src/android/addapktoapex/app/AddApkToApexDeviceActivity.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.addapktoapex.app;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+
+/**
+ * A simple activity which logs to Logcat.
+ */
+public class AddApkToApexDeviceActivity extends Activity {
+
+ private static final String TAG = AddApkToApexDeviceActivity.class.getSimpleName();
+
+ /**
+ * The test string to log.
+ */
+ private static final String TEST_STRING = "AddApkToApexTestString";
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ // Log the test string to Logcat.
+ Log.i(TAG, TEST_STRING);
+ }
+
+}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
index e071c11..891896d 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
@@ -430,7 +430,7 @@
if (mLocalLOGV) Log.i(TAG, "onResume(): mAppSnippet=" + mAppSnippet);
if (mAppSnippet != null) {
- // load dummy layout with OK button disabled until we override this layout in
+ // load placeholder layout with OK button disabled until we override this layout in
// startInstallConfirm
bindUi();
checkIfAllowedAndInitiateInstall();
diff --git a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatteryStatus.java b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatteryStatus.java
index 9ab84d2..f90a17a 100644
--- a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatteryStatus.java
+++ b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatteryStatus.java
@@ -45,6 +45,7 @@
private static final int EXTREME_LOW_BATTERY_THRESHOLD = 3;
private static final int DEFAULT_CHARGING_VOLTAGE_MICRO_VOLT = 5000000;
+ public static final int BATTERY_LEVEL_UNKNOWN = -1;
public static final int CHARGING_UNKNOWN = -1;
public static final int CHARGING_SLOWLY = 0;
public static final int CHARGING_REGULAR = 1;
@@ -186,12 +187,13 @@
/** Gets the battery level from the intent. */
public static int getBatteryLevel(Intent batteryChangedIntent) {
if (batteryChangedIntent == null) {
- return -1; /*invalid battery level*/
+ return BATTERY_LEVEL_UNKNOWN;
}
- final int level = batteryChangedIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
+ final int level =
+ batteryChangedIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, BATTERY_LEVEL_UNKNOWN);
final int scale = batteryChangedIntent.getIntExtra(BatteryManager.EXTRA_SCALE, 0);
return scale == 0
- ? -1 /*invalid battery level*/
+ ? BATTERY_LEVEL_UNKNOWN
: Math.round((level / (float) scale) * 100f);
}
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java
index 41ce58e..294df72 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java
@@ -24,7 +24,7 @@
/**
* These keys may be mentioned in the SETTINGS_TO_BACKUP arrays in SystemSettings
* and SecureSettings as well. This is because those tables drive both backup and
- * restore, and restore needs to properly whitelist keys that used to live
+ * restore, and restore needs to properly allowlist keys that used to live
* in those namespaces.
*
* NOTE: Settings are backed up and restored in the order they appear
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
index 3efb41d..c2dbf98 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
@@ -240,6 +240,7 @@
Settings.Secure.HEARING_AID_CALL_ROUTING,
Settings.Secure.HEARING_AID_MEDIA_ROUTING,
Settings.Secure.HEARING_AID_SYSTEM_SOUNDS_ROUTING,
- Settings.Secure.ACCESSIBILITY_FONT_SCALING_HAS_BEEN_CHANGED
+ Settings.Secure.ACCESSIBILITY_FONT_SCALING_HAS_BEEN_CHANGED,
+ Settings.Secure.SEARCH_PRESS_HOLD_NAV_HANDLE_ENABLED
};
}
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index e5f7f88..a49461e 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -198,6 +198,7 @@
VALIDATORS.put(Secure.ASSIST_GESTURE_WAKE_ENABLED, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.ASSIST_TOUCH_GESTURE_ENABLED, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.ASSIST_LONG_PRESS_HOME_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.SEARCH_PRESS_HOLD_NAV_HANDLE_ENABLED, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.VR_DISPLAY_MODE, new DiscreteValueValidator(new String[] {"0", "1"}));
VALIDATORS.put(Secure.NOTIFICATION_BADGING, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.NOTIFICATION_DISMISS_RTL, BOOLEAN_VALIDATOR);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
index 056be2e..53c8dc9 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
@@ -905,7 +905,7 @@
@VisibleForTesting
SettingsBackupWhitelist getBackupWhitelist(Uri contentUri) {
// Figure out the white list and redirects to the global table. We restore anything
- // in either the backup whitelist or the legacy-restore whitelist for this table.
+ // in either the backup allowlist or the legacy-restore allowlist for this table.
String[] whitelist;
Map<String, Validator> validators = null;
if (contentUri.equals(Settings.Secure.CONTENT_URI)) {
@@ -1453,7 +1453,7 @@
}
/**
- * Store the whitelist of settings to be backed up and validators for them.
+ * Store the allowlist of settings to be backed up and validators for them.
*/
@VisibleForTesting
static class SettingsBackupWhitelist {
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index a83bfda..ef4e84f 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -1926,6 +1926,9 @@
dumpSetting(s, p,
Settings.Secure.ASSIST_LONG_PRESS_HOME_ENABLED,
SecureSettingsProto.Assist.LONG_PRESS_HOME_ENABLED);
+ dumpSetting(s, p,
+ Settings.Secure.SEARCH_PRESS_HOLD_NAV_HANDLE_ENABLED,
+ SecureSettingsProto.Assist.SEARCH_PRESS_HOLD_NAV_HANDLE_ENABLED);
p.end(assistToken);
final long assistHandlesToken = p.start(SecureSettingsProto.ASSIST_HANDLES);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index b76c66b..215a040 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -250,7 +250,7 @@
public static final int WRITE_FALLBACK_SETTINGS_FILES_JOB_ID = 1;
public static final long ONE_DAY_INTERVAL_MILLIS = 24 * 60 * 60 * 1000L;
- // Overlay specified settings whitelisted for Instant Apps
+ // Overlay specified settings allowlisted for Instant Apps
private static final Set<String> OVERLAY_ALLOWED_GLOBAL_INSTANT_APP_SETTINGS = new ArraySet<>();
private static final Set<String> OVERLAY_ALLOWED_SYSTEM_INSTANT_APP_SETTINGS = new ArraySet<>();
private static final Set<String> OVERLAY_ALLOWED_SECURE_INSTANT_APP_SETTINGS = new ArraySet<>();
@@ -2131,7 +2131,7 @@
@GuardedBy("mLock")
private List<String> getSettingsNamesLocked(int settingsType, int userId) {
- // Don't enforce the instant app whitelist for now -- its too prone to unintended breakage
+ // Don't enforce the instant app allowlist for now -- its too prone to unintended breakage
// in the current form.
return mSettingsRegistry.getSettingsNamesLocked(settingsType, userId);
}
@@ -2172,7 +2172,7 @@
}
if (!getInstantAppAccessibleSettings(settingsType).contains(settingName)
&& !getOverlayInstantAppAccessibleSettings(settingsType).contains(settingName)) {
- // Don't enforce the instant app whitelist for now -- its too prone to unintended
+ // Don't enforce the instant app allowlist for now -- its too prone to unintended
// breakage in the current form.
Slog.w(LOG_TAG, "Instant App " + ai.packageName
+ " trying to access unexposed setting, this will be an error in the future.");
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt
index 798bdec4..ab0225d 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt
@@ -409,6 +409,18 @@
scope.launch(bgDispatcher) { mutateSetting { it.copy(seedColor = value) } }
}
+ // Returns currentClockId if clock is connected, otherwise DEFAULT_CLOCK_ID. Since this
+ // is dependent on which clocks are connected, it may change when a clock is installed or
+ // removed from the device (unlike currentClockId).
+ // TODO: Merge w/ CurrentClockId when we convert to a flow. We shouldn't need both behaviors.
+ val activeClockId: String
+ get() {
+ if (!availableClocks.containsKey(currentClockId)) {
+ return DEFAULT_CLOCK_ID
+ }
+ return currentClockId
+ }
+
init {
// Register default clock designs
for (clock in defaultClockProvider.getClocks()) {
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt
index e7a53e5b..b28920c 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt
@@ -65,7 +65,7 @@
protected var onSecondaryDisplay: Boolean = false
override val events: DefaultClockEvents
- override val config = ClockConfig()
+ override val config = ClockConfig(DEFAULT_CLOCK_ID)
init {
val parent = FrameLayout(ctx)
diff --git a/packages/SystemUI/docs/qs-tiles.md b/packages/SystemUI/docs/qs-tiles.md
index 488f8c7..bd0b4ab 100644
--- a/packages/SystemUI/docs/qs-tiles.md
+++ b/packages/SystemUI/docs/qs-tiles.md
@@ -123,7 +123,7 @@
### API classes
-The classes that define the public API are in [core/java/android/service/quicksettings](core/java/android/service/quicksettings).
+The classes that define the public API are in [core/java/android/service/quicksettings](/core/java/android/service/quicksettings).
#### Tile
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt
index 527f8007..e2f4793 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt
@@ -199,6 +199,8 @@
/** Render configuration for the full clock. Modifies the way systemUI behaves with this clock. */
data class ClockConfig(
+ val id: String,
+
/** Transition to AOD should move smartspace like large clock instead of small clock */
val useAlternateSmartspaceAODTransition: Boolean = false,
diff --git a/packages/SystemUI/res-keyguard/layout/shade_carrier_new.xml b/packages/SystemUI/res-keyguard/layout/shade_carrier_new.xml
new file mode 100644
index 0000000..952f056
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/layout/shade_carrier_new.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2023, 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.
+*/
+-->
+<com.android.systemui.statusbar.pipeline.mobile.ui.view.ModernShadeCarrierGroupMobileView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/carrier_combo"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:gravity="center_vertical"
+ android:orientation="horizontal" >
+
+ <com.android.systemui.util.AutoMarqueeTextView
+ android:id="@+id/mobile_carrier_text"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:layout_marginEnd="@dimen/qs_carrier_margin_width"
+ android:visibility="gone"
+ android:textDirection="locale"
+ android:marqueeRepeatLimit="marquee_forever"
+ android:singleLine="true"
+ android:maxEms="7"/>
+
+ <include layout="@layout/status_bar_mobile_signal_group_new" />
+
+</com.android.systemui.statusbar.pipeline.mobile.ui.view.ModernShadeCarrierGroupMobileView>
+
diff --git a/packages/SystemUI/res/drawable/stat_sys_ringer_silent.xml b/packages/SystemUI/res/drawable/stat_sys_ringer_silent.xml
index 4a9d41f..b83f15a 100644
--- a/packages/SystemUI/res/drawable/stat_sys_ringer_silent.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_ringer_silent.xml
@@ -14,6 +14,4 @@
limitations under the License.
-->
<inset xmlns:android="http://schemas.android.com/apk/res/android"
- android:insetLeft="3dp"
- android:insetRight="3dp"
android:drawable="@drawable/ic_speaker_mute" />
diff --git a/packages/SystemUI/res/layout/screenshot_work_profile_first_run.xml b/packages/SystemUI/res/layout/screenshot_work_profile_first_run.xml
index 78cd718..39ec09b 100644
--- a/packages/SystemUI/res/layout/screenshot_work_profile_first_run.xml
+++ b/packages/SystemUI/res/layout/screenshot_work_profile_first_run.xml
@@ -34,8 +34,8 @@
android:layout_height="@dimen/overlay_dismiss_button_tappable_size"
android:contentDescription="@string/screenshot_dismiss_work_profile">
<ImageView
- android:layout_width="16dp"
- android:layout_height="16dp"
+ android:layout_width="24dp"
+ android:layout_height="24dp"
android:layout_gravity="center"
android:background="@drawable/circular_background"
android:backgroundTint="?androidprv:attr/materialColorSurfaceContainerHigh"
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
index b589887..06b6692 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
@@ -39,6 +39,7 @@
public class KeyguardClockSwitch extends RelativeLayout {
private static final String TAG = "KeyguardClockSwitch";
+ public static final String MISSING_CLOCK_ID = "CLOCK_MISSING";
private static final long CLOCK_OUT_MILLIS = 133;
private static final long CLOCK_IN_MILLIS = 167;
@@ -196,6 +197,14 @@
return mLogBuffer;
}
+ /** Returns the id of the currently rendering clock */
+ public String getClockId() {
+ if (mClock == null) {
+ return MISSING_CLOCK_ID;
+ }
+ return mClock.getConfig().getId();
+ }
+
void setClock(ClockController clock, int statusBarState) {
mClock = clock;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
index 0ed802e..4ccd3a9 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
@@ -222,8 +222,10 @@
mSmallClockFrame = mView.findViewById(R.id.lockscreen_clock_view);
mLargeClockFrame = mView.findViewById(R.id.lockscreen_clock_view_large);
- mDumpManager.unregisterDumpable(getClass().toString()); // unregister previous clocks
- mDumpManager.registerDumpable(getClass().toString(), this);
+ if (!mOnlyClock) {
+ mDumpManager.unregisterDumpable(getClass().toString()); // unregister previous clocks
+ mDumpManager.registerDumpable(getClass().toString(), this);
+ }
if (mFeatureFlags.isEnabled(LOCKSCREEN_WALLPAPER_DREAM_ENABLED)) {
mStatusArea = mView.findViewById(R.id.keyguard_status_area);
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
index 04692c4..9f3908a 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
@@ -27,6 +27,7 @@
import static com.android.keyguard.KeyguardSecurityContainer.USER_TYPE_SECONDARY_USER;
import static com.android.keyguard.KeyguardSecurityContainer.USER_TYPE_WORK_PROFILE;
import static com.android.systemui.DejankUtils.whitelistIpcs;
+import static com.android.systemui.flags.Flags.LOCKSCREEN_ENABLE_LANDSCAPE;
import static com.android.systemui.flags.Flags.REVAMPED_BOUNCER_MESSAGES;
import android.app.ActivityManager;
@@ -370,8 +371,12 @@
@Override
public void onOrientationChanged(int orientation) {
- KeyguardSecurityContainerController.this
+ if (mFeatureFlags.isEnabled(LOCKSCREEN_ENABLE_LANDSCAPE)) {
+ // TODO(b/295603468)
+ // Fix reinflation of views when flag is enabled.
+ KeyguardSecurityContainerController.this
.onDensityOrFontScaleOrOrientationChanged();
+ }
}
};
private final KeyguardUpdateMonitorCallback mKeyguardUpdateMonitorCallback =
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index f73a602..64c4eec 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
@@ -107,6 +107,7 @@
import com.android.systemui.statusbar.notification.row.dagger.NotificationShelfComponent;
import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.phone.LetterboxModule;
+import com.android.systemui.statusbar.phone.NotificationIconAreaControllerModule;
import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
import com.android.systemui.statusbar.pipeline.dagger.StatusBarPipelineModule;
import com.android.systemui.statusbar.policy.HeadsUpManager;
@@ -184,6 +185,7 @@
MediaProjectionModule.class,
MediaProjectionTaskSwitcherModule.class,
MotionToolModule.class,
+ NotificationIconAreaControllerModule.class,
PeopleHubModule.class,
PeopleModule.class,
PluginModule.class,
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index 93bdac2..6d68eef 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -398,6 +398,10 @@
// TODO(b/294588085): Tracking Bug
val WIFI_SECONDARY_NETWORKS = releasedFlag("wifi_secondary_networks")
+ // TODO(b/290676905): Tracking Bug
+ val NEW_SHADE_CARRIER_GROUP_MOBILE_ICONS =
+ unreleasedFlag("new_shade_carrier_group_mobile_icons")
+
// 700 - dialer/calls
// TODO(b/254512734): Tracking Bug
val ONGOING_CALL_STATUS_BAR_CHIP = releasedFlag("ongoing_call_status_bar_chip")
@@ -502,21 +506,6 @@
val WM_CAPTION_ON_SHELL =
sysPropBooleanFlag("persist.wm.debug.caption_on_shell", default = true)
- @Keep
- @JvmField
- val ENABLE_FLING_TO_DISMISS_BUBBLE =
- sysPropBooleanFlag("persist.wm.debug.fling_to_dismiss_bubble", default = true)
-
- @Keep
- @JvmField
- val ENABLE_FLING_TO_DISMISS_PIP =
- sysPropBooleanFlag("persist.wm.debug.fling_to_dismiss_pip", default = true)
-
- @Keep
- @JvmField
- val ENABLE_PIP_KEEP_CLEAR_ALGORITHM =
- sysPropBooleanFlag("persist.wm.debug.enable_pip_keep_clear_algorithm", default = true)
-
// TODO(b/256873975): Tracking Bug
@JvmField
@Keep
@@ -538,13 +527,6 @@
teamfood = false
)
- // TODO(b/198643358): Tracking bug
- @Keep
- @JvmField
- val ENABLE_PIP_SIZE_LARGE_SCREEN =
- sysPropBooleanFlag("persist.wm.debug.enable_pip_size_large_screen", default = true)
-
-
// TODO(b/293252410) : Tracking Bug
@JvmField
val LOCKSCREEN_ENABLE_LANDSCAPE =
@@ -628,6 +610,10 @@
// TODO(b/251205791): Tracking Bug
@JvmField val SCREENSHOT_APP_CLIPS = releasedFlag("screenshot_app_clips")
+ /** TODO(b/295143676): Tracking bug. When enable, captures a screenshot for each display. */
+ @JvmField
+ val MULTI_DISPLAY_SCREENSHOT = unreleasedFlag("multi_display_screenshot")
+
// 1400 - columbus
// TODO(b/254512756): Tracking Bug
val QUICK_TAP_IN_PCC = releasedFlag("quick_tap_in_pcc")
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardKeyEventInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardKeyEventInteractor.kt
index 635961b..e501ece 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardKeyEventInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardKeyEventInteractor.kt
@@ -54,7 +54,11 @@
if (event.handleAction()) {
when (event.keyCode) {
KeyEvent.KEYCODE_MENU -> return dispatchMenuKeyEvent()
- KeyEvent.KEYCODE_SPACE -> return dispatchSpaceEvent()
+ KeyEvent.KEYCODE_SPACE,
+ KeyEvent.KEYCODE_ENTER ->
+ if (isDeviceInteractive()) {
+ return collapseShadeLockedOrShowPrimaryBouncer()
+ }
}
}
return false
@@ -90,16 +94,22 @@
(statusBarStateController.state != StatusBarState.SHADE) &&
statusBarKeyguardViewManager.shouldDismissOnMenuPressed()
if (shouldUnlockOnMenuPressed) {
- shadeController.animateCollapseShadeForced()
- return true
+ return collapseShadeLockedOrShowPrimaryBouncer()
}
return false
}
- private fun dispatchSpaceEvent(): Boolean {
- if (isDeviceInteractive() && statusBarStateController.state != StatusBarState.SHADE) {
- shadeController.animateCollapseShadeForced()
- return true
+ private fun collapseShadeLockedOrShowPrimaryBouncer(): Boolean {
+ when (statusBarStateController.state) {
+ StatusBarState.SHADE -> return false
+ StatusBarState.SHADE_LOCKED -> {
+ shadeController.animateCollapseShadeForced()
+ return true
+ }
+ StatusBarState.KEYGUARD -> {
+ statusBarKeyguardViewManager.showPrimaryBouncer(true)
+ return true
+ }
}
return false
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
index a3d1d8c..d8824983 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
@@ -515,11 +515,13 @@
mSeekBar.setOnTouchListener((v, event) -> false);
updateIconAreaClickListener((v) -> {
if (device.getCurrentVolume() == 0) {
+ mController.logInteractionUnmuteDevice(device);
mSeekBar.setVolume(UNMUTE_DEFAULT_VOLUME);
mController.adjustVolume(device, UNMUTE_DEFAULT_VOLUME);
updateUnmutedVolumeIcon();
mIconAreaLayout.setOnTouchListener(((iconV, event) -> false));
} else {
+ mController.logInteractionMuteDevice(device);
mSeekBar.resetVolume();
mController.adjustVolume(device, 0);
updateMutedVolumeIcon();
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
index b431bab..13cd8e3 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
@@ -843,6 +843,14 @@
mMetricLogger.logInteractionAdjustVolume(device);
}
+ void logInteractionMuteDevice(MediaDevice device) {
+ mMetricLogger.logInteractionMute(device);
+ }
+
+ void logInteractionUnmuteDevice(MediaDevice device) {
+ mMetricLogger.logInteractionUnmute(device);
+ }
+
String getPackageName() {
return mPackageName;
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputMetricLogger.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputMetricLogger.java
index 412d1a3..ffd626a 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputMetricLogger.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputMetricLogger.java
@@ -154,6 +154,38 @@
}
/**
+ * Do the metric logging of muting device.
+ */
+ public void logInteractionMute(MediaDevice source) {
+ if (DEBUG) {
+ Log.d(TAG, "logInteraction - Mute");
+ }
+
+ SysUiStatsLog.write(
+ SysUiStatsLog.MEDIAOUTPUT_OP_INTERACTION_REPORT,
+ SysUiStatsLog.MEDIA_OUTPUT_OP_INTERACTION_REPORTED__INTERACTION_TYPE__MUTE,
+ getInteractionDeviceType(source),
+ getLoggingPackageName(),
+ source.isSuggestedDevice());
+ }
+
+ /**
+ * Do the metric logging of unmuting device.
+ */
+ public void logInteractionUnmute(MediaDevice source) {
+ if (DEBUG) {
+ Log.d(TAG, "logInteraction - Unmute");
+ }
+
+ SysUiStatsLog.write(
+ SysUiStatsLog.MEDIAOUTPUT_OP_INTERACTION_REPORT,
+ SysUiStatsLog.MEDIA_OUTPUT_OP_INTERACTION_REPORTED__INTERACTION_TYPE__UNMUTE,
+ getInteractionDeviceType(source),
+ getLoggingPackageName(),
+ source.isSuggestedDevice());
+ }
+
+ /**
* Do the metric logging of content switching failure.
*
* @param deviceItemList media item list for device count updating
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialog.kt b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialog.kt
index e8683fb..fb99775 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialog.kt
@@ -63,6 +63,7 @@
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setDialogTitle(R.string.screenrecord_permission_dialog_title)
+ setTitle(R.string.screenrecord_title)
setStartButtonText(R.string.screenrecord_permission_dialog_continue)
setStartButtonOnClickListener { v: View? ->
onStartRecordingClicked?.run()
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index cabbeb1..014093d 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -985,6 +985,7 @@
// Make sure the clock is in the correct position after the unlock animation
// so that it's not in the wrong place when we show the keyguard again.
positionClockAndNotifications(true /* forceClockUpdate */);
+ mScrimController.onUnlockAnimationFinished();
}
private void unlockAnimationStarted(
@@ -1243,6 +1244,13 @@
mKeyguardStatusViewController.init();
}
mKeyguardStatusViewController.setSplitShadeEnabled(mSplitShadeEnabled);
+ mKeyguardStatusViewController.getView().addOnLayoutChangeListener(
+ (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
+ int oldHeight = oldBottom - oldTop;
+ if (v.getHeight() != oldHeight) {
+ mNotificationStackScrollLayoutController.animateNextTopPaddingChange();
+ }
+ });
updateClockAppearance();
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
index 832a25b..798f2d5 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
@@ -21,8 +21,6 @@
import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow;
import android.app.StatusBarManager;
-import android.media.AudioManager;
-import android.media.session.MediaSessionLegacyHelper;
import android.os.PowerManager;
import android.util.Log;
import android.view.GestureDetector;
@@ -47,6 +45,7 @@
import com.android.systemui.dock.DockManager;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.Flags;
+import com.android.systemui.keyevent.domain.interactor.KeyEventInteractor;
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
import com.android.systemui.keyguard.shared.model.TransitionState;
@@ -101,13 +100,21 @@
private final NotificationInsetsController mNotificationInsetsController;
private final boolean mIsTrackpadCommonEnabled;
private final FeatureFlags mFeatureFlags;
+ private final KeyEventInteractor mKeyEventInteractor;
private GestureDetector mPulsingWakeupGestureHandler;
private GestureDetector mDreamingWakeupGestureHandler;
private View mBrightnessMirror;
private boolean mTouchActive;
private boolean mTouchCancelled;
private MotionEvent mDownEvent;
+ // TODO rename to mLaunchAnimationRunning
private boolean mExpandAnimationRunning;
+ /**
+ * When mExpandAnimationRunning is true and the touch dispatcher receives a down even after
+ * uptime exceeds this, the dispatcher will stop blocking touches for the launch animation,
+ * which has presumabely not completed due to an error.
+ */
+ private long mLaunchAnimationTimeout;
private NotificationStackScrollLayout mStackScrollLayout;
private PhoneStatusBarViewController mStatusBarViewController;
private final CentralSurfaces mService;
@@ -164,7 +171,8 @@
FeatureFlags featureFlags,
SystemClock clock,
BouncerMessageInteractor bouncerMessageInteractor,
- BouncerLogger bouncerLogger) {
+ BouncerLogger bouncerLogger,
+ KeyEventInteractor keyEventInteractor) {
mLockscreenShadeTransitionController = transitionController;
mFalsingCollector = falsingCollector;
mStatusBarStateController = statusBarStateController;
@@ -190,6 +198,7 @@
mNotificationInsetsController = notificationInsetsController;
mIsTrackpadCommonEnabled = featureFlags.isEnabled(TRACKPAD_GESTURE_COMMON);
mFeatureFlags = featureFlags;
+ mKeyEventInteractor = keyEventInteractor;
// This view is not part of the newly inflated expanded status bar.
mBrightnessMirror = mView.findViewById(R.id.brightness_mirror_container);
@@ -278,7 +287,12 @@
return logDownDispatch(ev, "touch cancelled", false);
}
if (mExpandAnimationRunning) {
- return logDownDispatch(ev, "expand animation running", false);
+ if (isDown && mClock.uptimeMillis() > mLaunchAnimationTimeout) {
+ mShadeLogger.d("NSWVC: launch animation timed out");
+ setExpandAnimationRunning(false);
+ } else {
+ return logDownDispatch(ev, "expand animation running", false);
+ }
}
if (mKeyguardUnlockAnimationController.isPlayingCannedUnlockAnimation()) {
@@ -457,44 +471,17 @@
@Override
public boolean interceptMediaKey(KeyEvent event) {
- return mService.interceptMediaKey(event);
+ return mKeyEventInteractor.interceptMediaKey(event);
}
@Override
public boolean dispatchKeyEventPreIme(KeyEvent event) {
- return mService.dispatchKeyEventPreIme(event);
+ return mKeyEventInteractor.dispatchKeyEventPreIme(event);
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
- boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
- switch (event.getKeyCode()) {
- case KeyEvent.KEYCODE_BACK:
- if (!down) {
- mBackActionInteractor.onBackRequested();
- }
- return true;
- case KeyEvent.KEYCODE_MENU:
- if (!down) {
- return mService.onMenuPressed();
- }
- break;
- case KeyEvent.KEYCODE_SPACE:
- if (!down) {
- return mService.onSpacePressed();
- }
- break;
- case KeyEvent.KEYCODE_VOLUME_DOWN:
- case KeyEvent.KEYCODE_VOLUME_UP:
- if (mStatusBarStateController.isDozing()) {
- MediaSessionLegacyHelper.getHelper(mView.getContext())
- .sendVolumeKeyEvent(
- event, AudioManager.USE_DEFAULT_STREAM_TYPE, true);
- return true;
- }
- break;
- }
- return false;
+ return mKeyEventInteractor.dispatchKeyEvent(event);
}
});
@@ -555,8 +542,12 @@
pw.println(mTouchActive);
}
- private void setExpandAnimationRunning(boolean running) {
+ @VisibleForTesting
+ void setExpandAnimationRunning(boolean running) {
if (mExpandAnimationRunning != running) {
+ if (running) {
+ mLaunchAnimationTimeout = mClock.uptimeMillis() + 5000;
+ }
mExpandAnimationRunning = running;
mNotificationShadeWindowController.setLaunchingActivity(mExpandAnimationRunning);
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrier.java b/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrier.java
index 8586828..8612cdf 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrier.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrier.java
@@ -34,6 +34,7 @@
import com.android.settingslib.graph.SignalDrawable;
import com.android.systemui.FontSizeUtils;
import com.android.systemui.R;
+import com.android.systemui.statusbar.pipeline.mobile.ui.view.ModernShadeCarrierGroupMobileView;
import com.android.systemui.util.LargeScreenUtils;
import java.util.Objects;
@@ -44,6 +45,7 @@
private TextView mCarrierText;
private ImageView mMobileSignal;
private ImageView mMobileRoaming;
+ private ModernShadeCarrierGroupMobileView mModernMobileView;
private View mSpacer;
@Nullable
private CellSignalState mLastSignalState;
@@ -77,6 +79,23 @@
updateResources();
}
+ /** Removes a ModernStatusBarMobileView from the ViewGroup. */
+ public void removeModernMobileView() {
+ if (mModernMobileView != null) {
+ removeView(mModernMobileView);
+ mModernMobileView = null;
+ }
+ }
+
+ /** Adds a ModernStatusBarMobileView to the ViewGroup. */
+ public void addModernMobileView(ModernShadeCarrierGroupMobileView mobileView) {
+ mModernMobileView = mobileView;
+ mMobileGroup.setVisibility(View.GONE);
+ mSpacer.setVisibility(View.GONE);
+ mCarrierText.setVisibility(View.GONE);
+ addView(mobileView);
+ }
+
/**
* Update the state of this view
* @param state the current state of the signal for this view
diff --git a/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrierGroupController.java b/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrierGroupController.java
index ad49b26..98d8a53 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrierGroupController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrierGroupController.java
@@ -16,6 +16,7 @@
package com.android.systemui.shade.carrier;
+import static android.telephony.SubscriptionManager.INVALID_SIM_SLOT_INDEX;
import static android.view.View.IMPORTANT_FOR_ACCESSIBILITY_YES;
import android.annotation.MainThread;
@@ -46,8 +47,17 @@
import com.android.systemui.statusbar.connectivity.MobileDataIndicators;
import com.android.systemui.statusbar.connectivity.NetworkController;
import com.android.systemui.statusbar.connectivity.SignalCallback;
+import com.android.systemui.statusbar.connectivity.ui.MobileContextProvider;
+import com.android.systemui.statusbar.phone.StatusBarLocation;
+import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags;
+import com.android.systemui.statusbar.pipeline.mobile.ui.MobileUiAdapter;
+import com.android.systemui.statusbar.pipeline.mobile.ui.binder.MobileIconsBinder;
+import com.android.systemui.statusbar.pipeline.mobile.ui.view.ModernShadeCarrierGroupMobileView;
+import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.MobileIconsViewModel;
+import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.ShadeCarrierGroupMobileIconViewModel;
import com.android.systemui.util.CarrierConfigTracker;
+import java.util.List;
import java.util.function.Consumer;
import javax.inject.Inject;
@@ -62,12 +72,16 @@
private final ActivityStarter mActivityStarter;
private final Handler mBgHandler;
+ private final Context mContext;
private final NetworkController mNetworkController;
private final CarrierTextManager mCarrierTextManager;
private final TextView mNoSimTextView;
// Non final for testing
private H mMainHandler;
private final Callback mCallback;
+ private final MobileIconsViewModel mMobileIconsViewModel;
+ private final MobileContextProvider mMobileContextProvider;
+ private final StatusBarPipelineFlags mStatusBarPipelineFlags;
private boolean mListening;
private final CellSignalState[] mInfos =
new CellSignalState[SIM_SLOTS];
@@ -91,7 +105,7 @@
Log.w(TAG, "setMobileDataIndicators - slot: " + slotIndex);
return;
}
- if (slotIndex == SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
+ if (slotIndex == INVALID_SIM_SLOT_INDEX) {
Log.e(TAG, "Invalid SIM slot index for subscription: " + indicators.subId);
return;
}
@@ -129,15 +143,25 @@
}
}
- private ShadeCarrierGroupController(ShadeCarrierGroup view, ActivityStarter activityStarter,
- @Background Handler bgHandler, @Main Looper mainLooper,
+ private ShadeCarrierGroupController(
+ ShadeCarrierGroup view,
+ ActivityStarter activityStarter,
+ @Background Handler bgHandler,
+ @Main Looper mainLooper,
NetworkController networkController,
- CarrierTextManager.Builder carrierTextManagerBuilder, Context context,
- CarrierConfigTracker carrierConfigTracker, SlotIndexResolver slotIndexResolver) {
-
+ CarrierTextManager.Builder carrierTextManagerBuilder,
+ Context context,
+ CarrierConfigTracker carrierConfigTracker,
+ SlotIndexResolver slotIndexResolver,
+ MobileUiAdapter mobileUiAdapter,
+ MobileContextProvider mobileContextProvider,
+ StatusBarPipelineFlags statusBarPipelineFlags
+ ) {
+ mContext = context;
mActivityStarter = activityStarter;
mBgHandler = bgHandler;
mNetworkController = networkController;
+ mStatusBarPipelineFlags = statusBarPipelineFlags;
mCarrierTextManager = carrierTextManagerBuilder
.setShowAirplaneMode(false)
.setShowMissingSim(false)
@@ -162,6 +186,14 @@
mCarrierGroups[1] = view.getCarrier2View();
mCarrierGroups[2] = view.getCarrier3View();
+ mMobileContextProvider = mobileContextProvider;
+ mMobileIconsViewModel = mobileUiAdapter.getMobileIconsViewModel();
+
+ if (mStatusBarPipelineFlags.useNewShadeCarrierGroupMobileIcons()) {
+ mobileUiAdapter.setShadeCarrierGroupController(this);
+ MobileIconsBinder.bind(view, mMobileIconsViewModel);
+ }
+
mCarrierDividers[0] = view.getCarrierDivider1();
mCarrierDividers[1] = view.getCarrierDivider2();
@@ -193,6 +225,50 @@
});
}
+ /** Updates the number of visible mobile icons using the new pipeline. */
+ public void updateModernMobileIcons(List<Integer> subIds) {
+ if (!mStatusBarPipelineFlags.useNewShadeCarrierGroupMobileIcons()) {
+ Log.d(TAG, "ignoring new pipeline callback because new mobile icon is disabled");
+ return;
+ }
+
+ for (ShadeCarrier carrier : mCarrierGroups) {
+ carrier.removeModernMobileView();
+ }
+
+ List<IconData> iconDataList = processSubIdList(subIds);
+
+ for (IconData iconData : iconDataList) {
+ ShadeCarrier carrier = mCarrierGroups[iconData.slotIndex];
+
+ Context mobileContext =
+ mMobileContextProvider.getMobileContextForSub(iconData.subId, mContext);
+ ModernShadeCarrierGroupMobileView modernMobileView = ModernShadeCarrierGroupMobileView
+ .constructAndBind(
+ mobileContext,
+ mMobileIconsViewModel.getLogger(),
+ "mobile_carrier_shade_group",
+ (ShadeCarrierGroupMobileIconViewModel) mMobileIconsViewModel
+ .viewModelForSub(iconData.subId,
+ StatusBarLocation.SHADE_CARRIER_GROUP)
+ );
+ carrier.addModernMobileView(modernMobileView);
+ }
+ }
+
+ @VisibleForTesting
+ List<IconData> processSubIdList(List<Integer> subIds) {
+ return subIds
+ .stream()
+ .limit(SIM_SLOTS)
+ .map(subId -> new IconData(subId, getSlotIndex(subId)))
+ .filter(iconData ->
+ iconData.slotIndex < SIM_SLOTS
+ && iconData.slotIndex != INVALID_SIM_SLOT_INDEX
+ )
+ .toList();
+ }
+
@VisibleForTesting
protected int getSlotIndex(int subscriptionId) {
return mSlotIndexResolver.getSlotIndex(subscriptionId);
@@ -269,8 +345,12 @@
}
}
- for (int i = 0; i < SIM_SLOTS; i++) {
- mCarrierGroups[i].updateState(mInfos[i], singleCarrier);
+ if (mStatusBarPipelineFlags.useNewShadeCarrierGroupMobileIcons()) {
+ Log.d(TAG, "ignoring old pipeline callback because new mobile icon is enabled");
+ } else {
+ for (int i = 0; i < SIM_SLOTS; i++) {
+ mCarrierGroups[i].updateState(mInfos[i], singleCarrier);
+ }
}
mCarrierDividers[0].setVisibility(
@@ -306,7 +386,7 @@
Log.w(TAG, "updateInfoCarrier - slot: " + slot);
continue;
}
- if (slot == SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
+ if (slot == INVALID_SIM_SLOT_INDEX) {
Log.e(TAG,
"Invalid SIM slot index for subscription: "
+ info.subscriptionIds[i]);
@@ -385,12 +465,24 @@
private final Context mContext;
private final CarrierConfigTracker mCarrierConfigTracker;
private final SlotIndexResolver mSlotIndexResolver;
+ private final MobileUiAdapter mMobileUiAdapter;
+ private final MobileContextProvider mMobileContextProvider;
+ private final StatusBarPipelineFlags mStatusBarPipelineFlags;
@Inject
- public Builder(ActivityStarter activityStarter, @Background Handler handler,
- @Main Looper looper, NetworkController networkController,
- CarrierTextManager.Builder carrierTextControllerBuilder, Context context,
- CarrierConfigTracker carrierConfigTracker, SlotIndexResolver slotIndexResolver) {
+ public Builder(
+ ActivityStarter activityStarter,
+ @Background Handler handler,
+ @Main Looper looper,
+ NetworkController networkController,
+ CarrierTextManager.Builder carrierTextControllerBuilder,
+ Context context,
+ CarrierConfigTracker carrierConfigTracker,
+ SlotIndexResolver slotIndexResolver,
+ MobileUiAdapter mobileUiAdapter,
+ MobileContextProvider mobileContextProvider,
+ StatusBarPipelineFlags statusBarPipelineFlags
+ ) {
mActivityStarter = activityStarter;
mHandler = handler;
mLooper = looper;
@@ -399,6 +491,9 @@
mContext = context;
mCarrierConfigTracker = carrierConfigTracker;
mSlotIndexResolver = slotIndexResolver;
+ mMobileUiAdapter = mobileUiAdapter;
+ mMobileContextProvider = mobileContextProvider;
+ mStatusBarPipelineFlags = statusBarPipelineFlags;
}
public Builder setShadeCarrierGroup(ShadeCarrierGroup view) {
@@ -407,9 +502,20 @@
}
public ShadeCarrierGroupController build() {
- return new ShadeCarrierGroupController(mView, mActivityStarter, mHandler, mLooper,
- mNetworkController, mCarrierTextControllerBuilder, mContext,
- mCarrierConfigTracker, mSlotIndexResolver);
+ return new ShadeCarrierGroupController(
+ mView,
+ mActivityStarter,
+ mHandler,
+ mLooper,
+ mNetworkController,
+ mCarrierTextControllerBuilder,
+ mContext,
+ mCarrierConfigTracker,
+ mSlotIndexResolver,
+ mMobileUiAdapter,
+ mMobileContextProvider,
+ mStatusBarPipelineFlags
+ );
}
}
@@ -448,4 +554,15 @@
return SubscriptionManager.getSlotIndex(subscriptionId);
}
}
+
+ @VisibleForTesting
+ static class IconData {
+ public final int subId;
+ public final int slotIndex;
+
+ IconData(int subId, int slotIndex) {
+ this.subId = subId;
+ this.slotIndex = slotIndex;
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ActionClickLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/ActionClickLogger.kt
index d3c19b7..5042f1b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ActionClickLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActionClickLogger.kt
@@ -31,56 +31,68 @@
) {
fun logInitialClick(
entry: NotificationEntry?,
+ index: Integer?,
pendingIntent: PendingIntent
) {
buffer.log(TAG, LogLevel.DEBUG, {
str1 = entry?.key
str2 = entry?.ranking?.channel?.id
- str3 = pendingIntent.intent.toString()
+ str3 = pendingIntent.toString()
+ int1 = index?.toInt() ?: Int.MIN_VALUE
}, {
- "ACTION CLICK $str1 (channel=$str2) for pending intent $str3"
+ "ACTION CLICK $str1 (channel=$str2) for pending intent $str3 at index $int1"
})
}
fun logRemoteInputWasHandled(
- entry: NotificationEntry?
+ entry: NotificationEntry?,
+ index: Int?
) {
buffer.log(TAG, LogLevel.DEBUG, {
str1 = entry?.key
+ int1 = index ?: Int.MIN_VALUE
}, {
- " [Action click] Triggered remote input (for $str1))"
+ " [Action click] Triggered remote input (for $str1) at index $int1"
})
}
fun logStartingIntentWithDefaultHandler(
entry: NotificationEntry?,
- pendingIntent: PendingIntent
+ pendingIntent: PendingIntent,
+ index: Int?
) {
buffer.log(TAG, LogLevel.DEBUG, {
str1 = entry?.key
- str2 = pendingIntent.intent.toString()
+ str2 = pendingIntent.toString()
+ int1 = index ?: Int.MIN_VALUE
}, {
- " [Action click] Launching intent $str2 via default handler (for $str1)"
+ " [Action click] Launching intent $str2 via default handler (for $str1 at index $int1)"
})
}
fun logWaitingToCloseKeyguard(
- pendingIntent: PendingIntent
+ pendingIntent: PendingIntent,
+ index: Int?
) {
buffer.log(TAG, LogLevel.DEBUG, {
- str1 = pendingIntent.intent.toString()
+ str1 = pendingIntent.toString()
+ int1 = index ?: Int.MIN_VALUE
}, {
- " [Action click] Intent $str1 launches an activity, dismissing keyguard first..."
+ " [Action click] Intent $str1 at index $int1 launches an activity, dismissing " +
+ "keyguard first..."
})
}
fun logKeyguardGone(
- pendingIntent: PendingIntent
+ pendingIntent: PendingIntent,
+ index: Int?
) {
buffer.log(TAG, LogLevel.DEBUG, {
- str1 = pendingIntent.intent.toString()
+ str1 = pendingIntent.toString()
+ int1 = index ?: Int.MIN_VALUE
}, {
- " [Action click] Keyguard dismissed, calling default handler for intent $str1"
+ " [Action click] Keyguard dismissed, calling default handler for intent $str1 at " +
+ "index $int1"
})
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationClickNotifier.kt b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationClickNotifier.kt
index abf81c5..692a997 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationClickNotifier.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationClickNotifier.kt
@@ -2,10 +2,12 @@
import android.app.Notification
import android.os.RemoteException
+import android.util.Log
import com.android.internal.statusbar.IStatusBarService
import com.android.internal.statusbar.NotificationVisibility
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.dagger.qualifiers.UiBackground
import com.android.systemui.util.Assert
import java.util.concurrent.Executor
import javax.inject.Inject
@@ -21,7 +23,8 @@
@SysUISingleton
public class NotificationClickNotifier @Inject constructor(
val barService: IStatusBarService,
- @Main val mainExecutor: Executor
+ @Main val mainExecutor: Executor,
+ @UiBackground val backgroundExecutor: Executor
) {
val listeners = mutableListOf<NotificationInteractionListener>()
@@ -48,13 +51,14 @@
visibility: NotificationVisibility,
generatedByAssistant: Boolean
) {
- try {
- barService.onNotificationActionClick(
- key, actionIndex, action, visibility, generatedByAssistant)
- } catch (e: RemoteException) {
- // nothing
+ backgroundExecutor.execute {
+ try {
+ barService.onNotificationActionClick(
+ key, actionIndex, action, visibility, generatedByAssistant)
+ } catch (e: RemoteException) {
+ // nothing
+ }
}
-
mainExecutor.execute {
notifyListenersAboutInteraction(key)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
index da84afe..8089fd9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
@@ -119,11 +119,14 @@
mPowerInteractor.wakeUpIfDozing(
"NOTIFICATION_CLICK", PowerManager.WAKE_REASON_GESTURE);
+ Integer actionIndex = (Integer)
+ view.getTag(com.android.internal.R.id.notification_action_index_tag);
+
final NotificationEntry entry = getNotificationForParent(view.getParent());
- mLogger.logInitialClick(entry, pendingIntent);
+ mLogger.logInitialClick(entry, actionIndex, pendingIntent);
if (handleRemoteInput(view, pendingIntent)) {
- mLogger.logRemoteInputWasHandled(entry);
+ mLogger.logRemoteInputWasHandled(entry, actionIndex);
return true;
}
@@ -141,9 +144,9 @@
}
Notification.Action action = getActionFromView(view, entry, pendingIntent);
return mCallback.handleRemoteViewClick(view, pendingIntent,
- action == null ? false : action.isAuthenticationRequired(), () -> {
+ action == null ? false : action.isAuthenticationRequired(), actionIndex, () -> {
Pair<Intent, ActivityOptions> options = response.getLaunchOptions(view);
- mLogger.logStartingIntentWithDefaultHandler(entry, pendingIntent);
+ mLogger.logStartingIntentWithDefaultHandler(entry, pendingIntent, actionIndex);
boolean started = RemoteViews.startPendingIntent(view, pendingIntent, options);
if (started) releaseNotificationIfKeptForRemoteInputHistory(entry);
return started;
@@ -692,11 +695,13 @@
* @param view
* @param pendingIntent
* @param appRequestedAuth
+ * @param actionIndex
* @param defaultHandler
* @return true iff the click was handled
*/
boolean handleRemoteViewClick(View view, PendingIntent pendingIntent,
- boolean appRequestedAuth, ClickHandler defaultHandler);
+ boolean appRequestedAuth, @Nullable Integer actionIndex,
+ ClickHandler defaultHandler);
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
index d6a14604..6dd24ea 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
@@ -48,8 +48,10 @@
import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.jank.InteractionJankMonitor.Configuration;
import com.android.internal.logging.UiEventLogger;
+import com.android.keyguard.KeyguardClockSwitch;
import com.android.systemui.DejankUtils;
import com.android.systemui.Dumpable;
+import com.android.systemui.R;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
@@ -420,6 +422,25 @@
}
}
+ /** Returns the id of the currently rendering clock */
+ public String getClockId() {
+ if (mView == null) {
+ return KeyguardClockSwitch.MISSING_CLOCK_ID;
+ }
+
+ View clockSwitch = mView.findViewById(R.id.keyguard_clock_container);
+ if (clockSwitch == null) {
+ Log.e(TAG, "Clock container was missing");
+ return KeyguardClockSwitch.MISSING_CLOCK_ID;
+ }
+ if (!(clockSwitch instanceof KeyguardClockSwitch)) {
+ Log.e(TAG, "Clock container was incorrect type: " + clockSwitch);
+ return KeyguardClockSwitch.MISSING_CLOCK_ID;
+ }
+
+ return ((KeyguardClockSwitch) clockSwitch).getClockId();
+ }
+
private void beginInteractionJankMonitor() {
final boolean shouldPost =
(mIsDozing && mDozeAmount == 0) || (!mIsDozing && mDozeAmount == 1);
@@ -429,6 +450,7 @@
Choreographer.CALLBACK_ANIMATION, this::beginInteractionJankMonitor, null);
} else {
Configuration.Builder builder = Configuration.Builder.withView(getCujType(), mView)
+ .setTag(getClockId())
.setDeferMonitorForAnimationStart(false);
mInteractionJankMonitor.begin(builder);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/OWNERS b/packages/SystemUI/src/com/android/systemui/statusbar/notification/OWNERS
index ed80f33..5558ab1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/OWNERS
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/OWNERS
@@ -2,13 +2,17 @@
# Bug component: 78010
-aaliomer@google.com
+aioana@google.com
aroederer@google.com
+iyz@google.com
jeffdq@google.com
juliacr@google.com
juliatuttle@google.com
+kurucz@google.com
+liuyining@google.com
lynhan@google.com
-steell@google.com
+matiashe@google.com
+valiiftime@google.com
yurilin@google.com
per-file MediaNotificationProcessor.java = ethibodeau@google.com, asc@google.com
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconAreaControllerViewBinderWrapperImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconAreaControllerViewBinderWrapperImpl.kt
new file mode 100644
index 0000000..26dfe3e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconAreaControllerViewBinderWrapperImpl.kt
@@ -0,0 +1,684 @@
+/*
+ * Copyright (C) 2023 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.statusbar.notification.icon.ui.viewbinder
+
+import android.content.Context
+import android.graphics.Color
+import android.graphics.Rect
+import android.os.Bundle
+import android.os.Trace
+import android.view.LayoutInflater
+import android.view.View
+import android.widget.FrameLayout
+import androidx.annotation.ColorInt
+import androidx.annotation.VisibleForTesting
+import androidx.collection.ArrayMap
+import com.android.app.animation.Interpolators
+import com.android.internal.statusbar.StatusBarIcon
+import com.android.internal.util.ContrastColorUtil
+import com.android.settingslib.Utils
+import com.android.systemui.R
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.demomode.DemoMode
+import com.android.systemui.demomode.DemoModeController
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
+import com.android.systemui.flags.ViewRefactorFlag
+import com.android.systemui.plugins.DarkIconDispatcher
+import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.statusbar.CrossFadeHelper
+import com.android.systemui.statusbar.NotificationListener
+import com.android.systemui.statusbar.NotificationMediaManager
+import com.android.systemui.statusbar.NotificationShelfController
+import com.android.systemui.statusbar.StatusBarIconView
+import com.android.systemui.statusbar.StatusBarState
+import com.android.systemui.statusbar.notification.NotificationUtils
+import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator
+import com.android.systemui.statusbar.notification.collection.ListEntry
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.collection.provider.SectionStyleProvider
+import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerAlwaysOnDisplayViewModel
+import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerShelfViewModel
+import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerStatusBarViewModel
+import com.android.systemui.statusbar.notification.shelf.ui.viewbinder.NotificationShelfViewBinderWrapperControllerImpl
+import com.android.systemui.statusbar.phone.DozeParameters
+import com.android.systemui.statusbar.phone.KeyguardBypassController
+import com.android.systemui.statusbar.phone.NotificationIconAreaController
+import com.android.systemui.statusbar.phone.NotificationIconContainer
+import com.android.systemui.statusbar.phone.ScreenOffAnimationController
+import com.android.systemui.statusbar.window.StatusBarWindowController
+import com.android.wm.shell.bubbles.Bubbles
+import java.util.Optional
+import java.util.function.Function
+import javax.inject.Inject
+import kotlinx.coroutines.DisposableHandle
+
+/**
+ * Controller class for [NotificationIconContainer]. This implementation serves as a temporary
+ * wrapper around [NotificationIconContainerViewBinder], so that external code can continue to
+ * depend on the [NotificationIconAreaController] interface. Once
+ * [LegacyNotificationIconAreaControllerImpl] is removed, this class can go away and the ViewBinder
+ * can be used directly.
+ */
+@SysUISingleton
+class NotificationIconAreaControllerViewBinderWrapperImpl
+@Inject
+constructor(
+ private val context: Context,
+ private val statusBarStateController: StatusBarStateController,
+ private val wakeUpCoordinator: NotificationWakeUpCoordinator,
+ private val bypassController: KeyguardBypassController,
+ private val mediaManager: NotificationMediaManager,
+ notificationListener: NotificationListener,
+ private val dozeParameters: DozeParameters,
+ private val sectionStyleProvider: SectionStyleProvider,
+ private val bubblesOptional: Optional<Bubbles>,
+ demoModeController: DemoModeController,
+ darkIconDispatcher: DarkIconDispatcher,
+ featureFlags: FeatureFlags,
+ private val statusBarWindowController: StatusBarWindowController,
+ private val screenOffAnimationController: ScreenOffAnimationController,
+ private val shelfIconsViewModel: NotificationIconContainerShelfViewModel,
+ private val statusBarIconsViewModel: NotificationIconContainerStatusBarViewModel,
+ private val aodIconsViewModel: NotificationIconContainerAlwaysOnDisplayViewModel,
+) :
+ NotificationIconAreaController,
+ DarkIconDispatcher.DarkReceiver,
+ StatusBarStateController.StateListener,
+ NotificationWakeUpCoordinator.WakeUpListener,
+ DemoMode {
+
+ private val contrastColorUtil: ContrastColorUtil = ContrastColorUtil.getInstance(context)
+ private val updateStatusBarIcons = Runnable { updateStatusBarIcons() }
+ private val shelfRefactor = ViewRefactorFlag(featureFlags, Flags.NOTIFICATION_SHELF_REFACTOR)
+ private val tintAreas = ArrayList<Rect>()
+
+ private var iconSize = 0
+ private var iconHPadding = 0
+ private var iconTint = Color.WHITE
+ private var notificationEntries = listOf<ListEntry>()
+ private var notificationIconArea: View? = null
+ private var notificationIcons: NotificationIconContainer? = null
+ private var shelfIcons: NotificationIconContainer? = null
+ private var aodIcons: NotificationIconContainer? = null
+ private var aodBindJob: DisposableHandle? = null
+ private var aodIconAppearTranslation = 0
+ private var animationsEnabled = false
+ private var aodIconTint = 0
+ private var aodIconsVisible = false
+ private var showLowPriority = true
+
+ @VisibleForTesting
+ val settingsListener: NotificationListener.NotificationSettingsListener =
+ object : NotificationListener.NotificationSettingsListener {
+ override fun onStatusBarIconsBehaviorChanged(hideSilentStatusIcons: Boolean) {
+ showLowPriority = !hideSilentStatusIcons
+ updateStatusBarIcons()
+ }
+ }
+
+ init {
+ statusBarStateController.addCallback(this)
+ wakeUpCoordinator.addListener(this)
+ demoModeController.addCallback(this)
+ notificationListener.addNotificationSettingsListener(settingsListener)
+ initializeNotificationAreaViews(context)
+ reloadAodColor()
+ darkIconDispatcher.addDarkReceiver(this)
+ }
+
+ @VisibleForTesting
+ fun shouldShowLowPriorityIcons(): Boolean {
+ return showLowPriority
+ }
+
+ /** Called by the Keyguard*ViewController whose view contains the aod icons. */
+ override fun setupAodIcons(aodIcons: NotificationIconContainer) {
+ val changed = this.aodIcons != null && aodIcons !== this.aodIcons
+ if (changed) {
+ this.aodIcons!!.setAnimationsEnabled(false)
+ this.aodIcons!!.removeAllViews()
+ aodBindJob?.dispose()
+ }
+ this.aodIcons = aodIcons
+ this.aodIcons!!.setOnLockScreen(true)
+ aodBindJob = NotificationIconContainerViewBinder.bind(aodIcons, aodIconsViewModel)
+ updateAodIconsVisibility(animate = false, forceUpdate = changed)
+ updateAnimations()
+ if (changed) {
+ updateAodNotificationIcons()
+ }
+ updateIconLayoutParams(context)
+ }
+
+ override fun setupShelf(notificationShelfController: NotificationShelfController) =
+ NotificationShelfViewBinderWrapperControllerImpl.unsupported
+
+ override fun setShelfIcons(icons: NotificationIconContainer) {
+ if (shelfRefactor.expectEnabled()) {
+ NotificationIconContainerViewBinder.bind(icons, shelfIconsViewModel)
+ shelfIcons = icons
+ }
+ }
+
+ override fun onDensityOrFontScaleChanged(context: Context) {
+ updateIconLayoutParams(context)
+ }
+
+ /** Returns the view that represents the notification area. */
+ override fun getNotificationInnerAreaView(): View? {
+ return notificationIconArea
+ }
+
+ /**
+ * See [com.android.systemui.statusbar.policy.DarkIconDispatcher.setIconsDarkArea]. Sets the
+ * color that should be used to tint any icons in the notification area.
+ *
+ * @param tintAreas the areas in which to tint the icons, specified in screen coordinates
+ * @param darkIntensity
+ */
+ override fun onDarkChanged(tintAreas: ArrayList<Rect>, darkIntensity: Float, iconTint: Int) {
+ this.tintAreas.clear()
+ this.tintAreas.addAll(tintAreas)
+ if (DarkIconDispatcher.isInAreas(tintAreas, notificationIconArea)) {
+ this.iconTint = iconTint
+ }
+ applyNotificationIconsTint()
+ }
+
+ /** Updates the notifications with the given list of notifications to display. */
+ override fun updateNotificationIcons(entries: List<ListEntry>) {
+ notificationEntries = entries
+ updateNotificationIcons()
+ }
+
+ private fun updateStatusBarIcons() {
+ updateIconsForLayout(
+ { entry: NotificationEntry -> entry.icons.statusBarIcon },
+ notificationIcons,
+ showAmbient = false /* showAmbient */,
+ showLowPriority = showLowPriority,
+ hideDismissed = true /* hideDismissed */,
+ hideRepliedMessages = true /* hideRepliedMessages */,
+ hideCurrentMedia = false /* hideCurrentMedia */,
+ hidePulsing = false /* hidePulsing */
+ )
+ }
+
+ override fun updateAodNotificationIcons() {
+ if (aodIcons == null) {
+ return
+ }
+ updateIconsForLayout(
+ { entry: NotificationEntry -> entry.icons.aodIcon },
+ aodIcons,
+ showAmbient = false /* showAmbient */,
+ showLowPriority = true /* showLowPriority */,
+ hideDismissed = true /* hideDismissed */,
+ hideRepliedMessages = true /* hideRepliedMessages */,
+ hideCurrentMedia = true /* hideCurrentMedia */,
+ hidePulsing = bypassController.bypassEnabled /* hidePulsing */
+ )
+ }
+
+ override fun showIconIsolated(icon: StatusBarIconView?, animated: Boolean) {
+ notificationIcons!!.showIconIsolated(icon, animated)
+ }
+
+ override fun setIsolatedIconLocation(iconDrawingRect: Rect, requireStateUpdate: Boolean) {
+ notificationIcons!!.setIsolatedIconLocation(iconDrawingRect, requireStateUpdate)
+ }
+
+ override fun onDozingChanged(isDozing: Boolean) {
+ if (aodIcons == null) {
+ return
+ }
+ val animate = (dozeParameters.alwaysOn && !dozeParameters.displayNeedsBlanking)
+ aodIcons!!.setDozing(isDozing, animate, 0)
+ }
+
+ override fun setAnimationsEnabled(enabled: Boolean) {
+ animationsEnabled = enabled
+ updateAnimations()
+ }
+
+ override fun onStateChanged(newState: Int) {
+ updateAodIconsVisibility(animate = false, forceUpdate = false)
+ updateAnimations()
+ }
+
+ override fun onThemeChanged() {
+ reloadAodColor()
+ updateAodIconColors()
+ }
+
+ override fun getHeight(): Int {
+ return if (aodIcons == null) 0 else aodIcons!!.height
+ }
+
+ @VisibleForTesting
+ fun appearAodIcons() {
+ if (aodIcons == null) {
+ return
+ }
+ if (screenOffAnimationController.shouldAnimateAodIcons()) {
+ aodIcons!!.translationY = -aodIconAppearTranslation.toFloat()
+ aodIcons!!.alpha = 0f
+ animateInAodIconTranslation()
+ aodIcons!!
+ .animate()
+ .alpha(1f)
+ .setInterpolator(Interpolators.LINEAR)
+ .setDuration(AOD_ICONS_APPEAR_DURATION)
+ .start()
+ } else {
+ aodIcons!!.alpha = 1.0f
+ aodIcons!!.translationY = 0f
+ }
+ }
+
+ override fun onFullyHiddenChanged(isFullyHidden: Boolean) {
+ var animate = true
+ if (!bypassController.bypassEnabled) {
+ animate = dozeParameters.alwaysOn && !dozeParameters.displayNeedsBlanking
+ // We only want the appear animations to happen when the notifications get fully hidden,
+ // since otherwise the unhide animation overlaps
+ animate = animate and isFullyHidden
+ }
+ updateAodIconsVisibility(animate, false /* force */)
+ updateAodNotificationIcons()
+ updateAodIconColors()
+ }
+
+ override fun onPulseExpansionChanged(expandingChanged: Boolean) {
+ if (expandingChanged) {
+ updateAodIconsVisibility(animate = true, forceUpdate = false)
+ }
+ }
+
+ override fun demoCommands(): List<String> {
+ val commands = ArrayList<String>()
+ commands.add(DemoMode.COMMAND_NOTIFICATIONS)
+ return commands
+ }
+
+ override fun dispatchDemoCommand(command: String, args: Bundle) {
+ if (notificationIconArea != null) {
+ val visible = args.getString("visible")
+ val vis = if ("false" == visible) View.INVISIBLE else View.VISIBLE
+ notificationIconArea?.visibility = vis
+ }
+ }
+
+ override fun onDemoModeFinished() {
+ if (notificationIconArea != null) {
+ notificationIconArea?.visibility = View.VISIBLE
+ }
+ }
+
+ private fun inflateIconArea(inflater: LayoutInflater): View {
+ return inflater.inflate(R.layout.notification_icon_area, null)
+ }
+
+ /** Initializes the views that will represent the notification area. */
+ private fun initializeNotificationAreaViews(context: Context) {
+ reloadDimens(context)
+ val layoutInflater = LayoutInflater.from(context)
+ notificationIconArea = inflateIconArea(layoutInflater)
+ notificationIcons = notificationIconArea?.findViewById(R.id.notificationIcons)
+ NotificationIconContainerViewBinder.bind(notificationIcons!!, statusBarIconsViewModel)
+ }
+
+ private fun updateIconLayoutParams(context: Context) {
+ reloadDimens(context)
+ val params = generateIconLayoutParams()
+ for (i in 0 until notificationIcons!!.childCount) {
+ val child = notificationIcons!!.getChildAt(i)
+ child.layoutParams = params
+ }
+ if (shelfIcons != null) {
+ for (i in 0 until shelfIcons!!.childCount) {
+ val child = shelfIcons!!.getChildAt(i)
+ child.layoutParams = params
+ }
+ }
+ if (aodIcons != null) {
+ for (i in 0 until aodIcons!!.childCount) {
+ val child = aodIcons!!.getChildAt(i)
+ child.layoutParams = params
+ }
+ }
+ }
+
+ private fun generateIconLayoutParams(): FrameLayout.LayoutParams {
+ return FrameLayout.LayoutParams(
+ iconSize + 2 * iconHPadding,
+ statusBarWindowController.statusBarHeight
+ )
+ }
+
+ private fun reloadDimens(context: Context) {
+ val res = context.resources
+ iconSize = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_icon_size_sp)
+ iconHPadding = res.getDimensionPixelSize(R.dimen.status_bar_icon_horizontal_margin)
+ aodIconAppearTranslation = res.getDimensionPixelSize(R.dimen.shelf_appear_translation)
+ }
+
+ private fun shouldShowNotificationIcon(
+ entry: NotificationEntry,
+ showAmbient: Boolean,
+ showLowPriority: Boolean,
+ hideDismissed: Boolean,
+ hideRepliedMessages: Boolean,
+ hideCurrentMedia: Boolean,
+ hidePulsing: Boolean
+ ): Boolean {
+ if (!showAmbient && sectionStyleProvider.isMinimized(entry)) {
+ return false
+ }
+ if (hideCurrentMedia && entry.key == mediaManager.mediaNotificationKey) {
+ return false
+ }
+ if (!showLowPriority && sectionStyleProvider.isSilent(entry)) {
+ return false
+ }
+ if (entry.isRowDismissed && hideDismissed) {
+ return false
+ }
+ if (hideRepliedMessages && entry.isLastMessageFromReply) {
+ return false
+ }
+ // showAmbient == show in shade but not shelf
+ if (!showAmbient && entry.shouldSuppressStatusBar()) {
+ return false
+ }
+ if (
+ hidePulsing &&
+ entry.showingPulsing() &&
+ (!wakeUpCoordinator.notificationsFullyHidden || !entry.isPulseSuppressed)
+ ) {
+ return false
+ }
+ return if (bubblesOptional.isPresent && bubblesOptional.get().isBubbleExpanded(entry.key)) {
+ false
+ } else true
+ }
+
+ private fun updateNotificationIcons() {
+ Trace.beginSection("NotificationIconAreaController.updateNotificationIcons")
+ updateStatusBarIcons()
+ updateShelfIcons()
+ updateAodNotificationIcons()
+ applyNotificationIconsTint()
+ Trace.endSection()
+ }
+
+ private fun updateShelfIcons() {
+ if (shelfIcons == null) {
+ return
+ }
+ updateIconsForLayout(
+ { entry: NotificationEntry -> entry.icons.shelfIcon },
+ shelfIcons,
+ showAmbient = true,
+ showLowPriority = true,
+ hideDismissed = false,
+ hideRepliedMessages = false,
+ hideCurrentMedia = false,
+ hidePulsing = false
+ )
+ }
+
+ /**
+ * Updates the notification icons for a host layout. This will ensure that the notification host
+ * layout will have the same icons like the ones in here.
+ *
+ * @param function A function to look up an icon view based on an entry
+ * @param hostLayout which layout should be updated
+ * @param showAmbient should ambient notification icons be shown
+ * @param showLowPriority should icons from silent notifications be shown
+ * @param hideDismissed should dismissed icons be hidden
+ * @param hideRepliedMessages should messages that have been replied to be hidden
+ * @param hidePulsing should pulsing notifications be hidden
+ */
+ private fun updateIconsForLayout(
+ function: Function<NotificationEntry, StatusBarIconView?>,
+ hostLayout: NotificationIconContainer?,
+ showAmbient: Boolean,
+ showLowPriority: Boolean,
+ hideDismissed: Boolean,
+ hideRepliedMessages: Boolean,
+ hideCurrentMedia: Boolean,
+ hidePulsing: Boolean,
+ ) {
+ val toShow = ArrayList<StatusBarIconView>(notificationEntries.size)
+ // Filter out ambient notifications and notification children.
+ for (i in notificationEntries.indices) {
+ val entry = notificationEntries[i].representativeEntry
+ if (entry != null && entry.row != null) {
+ if (
+ shouldShowNotificationIcon(
+ entry,
+ showAmbient,
+ showLowPriority,
+ hideDismissed,
+ hideRepliedMessages,
+ hideCurrentMedia,
+ hidePulsing
+ )
+ ) {
+ val iconView = function.apply(entry)
+ if (iconView != null) {
+ toShow.add(iconView)
+ }
+ }
+ }
+ }
+
+ // In case we are changing the suppression of a group, the replacement shouldn't flicker
+ // and it should just be replaced instead. We therefore look for notifications that were
+ // just replaced by the child or vice-versa to suppress this.
+ val replacingIcons = ArrayMap<String, ArrayList<StatusBarIcon>>()
+ val toRemove = ArrayList<View>()
+ for (i in 0 until hostLayout!!.childCount) {
+ val child = hostLayout.getChildAt(i) as? StatusBarIconView ?: continue
+ if (!toShow.contains(child)) {
+ var iconWasReplaced = false
+ val removedGroupKey = child.notification.groupKey
+ for (j in toShow.indices) {
+ val candidate = toShow[j]
+ if (
+ candidate.sourceIcon.sameAs(child.sourceIcon) &&
+ candidate.notification.groupKey == removedGroupKey
+ ) {
+ if (!iconWasReplaced) {
+ iconWasReplaced = true
+ } else {
+ iconWasReplaced = false
+ break
+ }
+ }
+ }
+ if (iconWasReplaced) {
+ var statusBarIcons = replacingIcons[removedGroupKey]
+ if (statusBarIcons == null) {
+ statusBarIcons = ArrayList()
+ replacingIcons[removedGroupKey] = statusBarIcons
+ }
+ statusBarIcons.add(child.statusBarIcon)
+ }
+ toRemove.add(child)
+ }
+ }
+ // removing all duplicates
+ val duplicates = ArrayList<String?>()
+ for (key in replacingIcons.keys) {
+ val statusBarIcons = replacingIcons[key]!!
+ if (statusBarIcons.size != 1) {
+ duplicates.add(key)
+ }
+ }
+ replacingIcons.removeAll(duplicates)
+ hostLayout.setReplacingIcons(replacingIcons)
+ val toRemoveCount = toRemove.size
+ for (i in 0 until toRemoveCount) {
+ hostLayout.removeView(toRemove[i])
+ }
+ val params = generateIconLayoutParams()
+ for (i in toShow.indices) {
+ val v = toShow[i]
+ // The view might still be transiently added if it was just removed and added again
+ hostLayout.removeTransientView(v)
+ if (v.parent == null) {
+ if (hideDismissed) {
+ v.setOnDismissListener(updateStatusBarIcons)
+ }
+ hostLayout.addView(v, i, params)
+ }
+ }
+ hostLayout.setChangingViewPositions(true)
+ // Re-sort notification icons
+ val childCount = hostLayout.childCount
+ for (i in 0 until childCount) {
+ val actual = hostLayout.getChildAt(i)
+ val expected = toShow[i]
+ if (actual === expected) {
+ continue
+ }
+ hostLayout.removeView(expected)
+ hostLayout.addView(expected, i)
+ }
+ hostLayout.setChangingViewPositions(false)
+ hostLayout.setReplacingIcons(null)
+ }
+
+ /** Applies [.mIconTint] to the notification icons. */
+ private fun applyNotificationIconsTint() {
+ for (i in 0 until notificationIcons!!.childCount) {
+ val iv = notificationIcons!!.getChildAt(i) as StatusBarIconView
+ if (iv.width != 0) {
+ updateTintForIcon(iv, iconTint)
+ } else {
+ iv.executeOnLayout { updateTintForIcon(iv, iconTint) }
+ }
+ }
+ updateAodIconColors()
+ }
+
+ private fun updateTintForIcon(v: StatusBarIconView, tint: Int) {
+ val isPreL = java.lang.Boolean.TRUE == v.getTag(R.id.icon_is_pre_L)
+ var color = StatusBarIconView.NO_COLOR
+ val colorize = !isPreL || NotificationUtils.isGrayscale(v, contrastColorUtil)
+ if (colorize) {
+ color = DarkIconDispatcher.getTint(tintAreas, v, tint)
+ }
+ v.staticDrawableColor = color
+ v.setDecorColor(tint)
+ }
+
+ private fun updateAnimations() {
+ val inShade = statusBarStateController.state == StatusBarState.SHADE
+ if (aodIcons != null) {
+ aodIcons!!.setAnimationsEnabled(animationsEnabled && !inShade)
+ }
+ notificationIcons!!.setAnimationsEnabled(animationsEnabled && inShade)
+ }
+
+ private fun animateInAodIconTranslation() {
+ aodIcons!!
+ .animate()
+ .setInterpolator(Interpolators.DECELERATE_QUINT)
+ .translationY(0f)
+ .setDuration(AOD_ICONS_APPEAR_DURATION)
+ .start()
+ }
+
+ private fun reloadAodColor() {
+ aodIconTint =
+ Utils.getColorAttrDefaultColor(
+ context,
+ R.attr.wallpaperTextColor,
+ DEFAULT_AOD_ICON_COLOR
+ )
+ }
+
+ private fun updateAodIconColors() {
+ if (aodIcons != null) {
+ for (i in 0 until aodIcons!!.childCount) {
+ val iv = aodIcons!!.getChildAt(i) as StatusBarIconView
+ if (iv.width != 0) {
+ updateTintForIcon(iv, aodIconTint)
+ } else {
+ iv.executeOnLayout { updateTintForIcon(iv, aodIconTint) }
+ }
+ }
+ }
+ }
+
+ private fun updateAodIconsVisibility(animate: Boolean, forceUpdate: Boolean) {
+ if (aodIcons == null) {
+ return
+ }
+ var visible = (bypassController.bypassEnabled || wakeUpCoordinator.notificationsFullyHidden)
+
+ // Hide the AOD icons if we're not in the KEYGUARD state unless the screen off animation is
+ // playing, in which case we want them to be visible since we're animating in the AOD UI and
+ // will be switching to KEYGUARD shortly.
+ if (
+ statusBarStateController.state != StatusBarState.KEYGUARD &&
+ !screenOffAnimationController.shouldShowAodIconsWhenShade()
+ ) {
+ visible = false
+ }
+ if (visible && wakeUpCoordinator.isPulseExpanding() && !bypassController.bypassEnabled) {
+ visible = false
+ }
+ if (aodIconsVisible != visible || forceUpdate) {
+ aodIconsVisible = visible
+ aodIcons!!.animate().cancel()
+ if (animate) {
+ val wasFullyInvisible = aodIcons!!.visibility != View.VISIBLE
+ if (aodIconsVisible) {
+ if (wasFullyInvisible) {
+ // No fading here, let's just appear the icons instead!
+ aodIcons!!.visibility = View.VISIBLE
+ aodIcons!!.alpha = 1.0f
+ appearAodIcons()
+ } else {
+ // Let's make sure the icon are translated to 0, since we cancelled it above
+ animateInAodIconTranslation()
+ // We were fading out, let's fade in instead
+ CrossFadeHelper.fadeIn(aodIcons)
+ }
+ } else {
+ // Let's make sure the icon are translated to 0, since we cancelled it above
+ animateInAodIconTranslation()
+ CrossFadeHelper.fadeOut(aodIcons)
+ }
+ } else {
+ aodIcons!!.alpha = 1.0f
+ aodIcons!!.translationY = 0f
+ aodIcons!!.visibility = if (visible) View.VISIBLE else View.INVISIBLE
+ }
+ }
+ }
+
+ companion object {
+ private const val AOD_ICONS_APPEAR_DURATION: Long = 200
+
+ @ColorInt private val DEFAULT_AOD_ICON_COLOR = -0x1
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerViewBinder.kt
new file mode 100644
index 0000000..8293bb3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerViewBinder.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2023 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.statusbar.notification.icon.ui.viewbinder
+
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.repeatOnLifecycle
+import com.android.systemui.lifecycle.repeatWhenAttached
+import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerViewModel
+import com.android.systemui.statusbar.phone.NotificationIconContainer
+import kotlinx.coroutines.DisposableHandle
+
+/** Binds a [NotificationIconContainer] to its [view model][NotificationIconContainerViewModel]. */
+object NotificationIconContainerViewBinder {
+ fun bind(
+ view: NotificationIconContainer,
+ viewModel: NotificationIconContainerViewModel,
+ ): DisposableHandle {
+ return view.repeatWhenAttached { repeatOnLifecycle(Lifecycle.State.CREATED) {} }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModel.kt
new file mode 100644
index 0000000..f68b0ef
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModel.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2023 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.statusbar.notification.icon.ui.viewmodel
+
+import javax.inject.Inject
+
+/** View-model for the row of notification icons displayed on the always-on display. */
+class NotificationIconContainerAlwaysOnDisplayViewModel @Inject constructor() :
+ NotificationIconContainerViewModel
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerShelfViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerShelfViewModel.kt
new file mode 100644
index 0000000..933c76f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerShelfViewModel.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2023 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.statusbar.notification.icon.ui.viewmodel
+
+import javax.inject.Inject
+
+/** View-model for the overflow row of notification icons displayed in the notification shade. */
+class NotificationIconContainerShelfViewModel @Inject constructor() :
+ NotificationIconContainerViewModel
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModel.kt
new file mode 100644
index 0000000..2217646
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModel.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2023 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.statusbar.notification.icon.ui.viewmodel
+
+import javax.inject.Inject
+
+/** View-model for the row of notification icons displayed in the status bar, */
+class NotificationIconContainerStatusBarViewModel @Inject constructor() :
+ NotificationIconContainerViewModel
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerViewModel.kt
new file mode 100644
index 0000000..892b2be
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerViewModel.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2023 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.statusbar.notification.icon.ui.viewmodel
+
+/**
+ * View-model for the row of notification icons displayed in the NotificationShelf, StatusBar, and
+ * AOD.
+ */
+interface NotificationIconContainerViewModel
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/ui/viewbinder/NotificationShelfViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/ui/viewbinder/NotificationShelfViewBinder.kt
index 22a87a7..b92c51f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/ui/viewbinder/NotificationShelfViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/ui/viewbinder/NotificationShelfViewBinder.kt
@@ -64,8 +64,10 @@
override fun setOnClickListener(listener: View.OnClickListener) = unsupported
- private val unsupported: Nothing
- get() = error("Code path not supported when NOTIFICATION_SHELF_REFACTOR is disabled")
+ companion object {
+ val unsupported: Nothing
+ get() = error("Code path not supported when NOTIFICATION_SHELF_REFACTOR is disabled")
+ }
}
/** Binds a [NotificationShelf] to its [view model][NotificationShelfViewModel]. */
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 4668aa4..6db8df9 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
@@ -28,7 +28,6 @@
import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_GENTLE;
import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_HIGH_PRIORITY;
import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.SelectedRows;
-import static com.android.systemui.statusbar.phone.NotificationIconAreaController.HIGH_PRIORITY;
import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow;
import android.content.res.Configuration;
@@ -150,6 +149,7 @@
public class NotificationStackScrollLayoutController {
private static final String TAG = "StackScrollerController";
private static final boolean DEBUG = Compile.IS_DEBUG && Log.isLoggable(TAG, Log.DEBUG);
+ private static final String HIGH_PRIORITY = "high_priority";
private final boolean mAllowLongPress;
private final NotificationGutsManager mNotificationGutsManager;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
index 5c28be3..af09bf2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
@@ -25,7 +25,6 @@
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.UserHandle;
-import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.RemoteAnimationAdapter;
import android.view.View;
@@ -276,19 +275,11 @@
void userActivity();
- boolean interceptMediaKey(KeyEvent event);
-
- boolean dispatchKeyEventPreIme(KeyEvent event);
-
- boolean onMenuPressed();
-
void endAffordanceLaunch();
/** Should the keyguard be hidden immediately in response to a back press/gesture. */
boolean shouldKeyguardHideImmediately();
- boolean onSpacePressed();
-
void showBouncerWithDimissAndCancelIfKeyguard(OnDismissAction performAction,
Runnable cancelAction);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
index 8ffd43a..ccb87bf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -89,7 +89,6 @@
import android.view.Display;
import android.view.IRemoteAnimationRunner;
import android.view.IWindowManager;
-import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.ThreadedRenderer;
import android.view.View;
@@ -2636,44 +2635,6 @@
}
@Override
- public boolean interceptMediaKey(KeyEvent event) {
- return mState == StatusBarState.KEYGUARD
- && mStatusBarKeyguardViewManager.interceptMediaKey(event);
- }
-
- /**
- * While IME is active and a BACK event is detected, check with
- * {@link StatusBarKeyguardViewManager#dispatchBackKeyEventPreIme()} to see if the event
- * should be handled before routing to IME, in order to prevent the user having to hit back
- * twice to exit bouncer.
- */
- @Override
- public boolean dispatchKeyEventPreIme(KeyEvent event) {
- switch (event.getKeyCode()) {
- case KeyEvent.KEYCODE_BACK:
- if (mState == StatusBarState.KEYGUARD
- && mStatusBarKeyguardViewManager.dispatchBackKeyEventPreIme()) {
- return mBackActionInteractor.onBackRequested();
- }
- }
- return false;
- }
-
- protected boolean shouldUnlockOnMenuPressed() {
- return mDeviceInteractive && mState != StatusBarState.SHADE
- && mStatusBarKeyguardViewManager.shouldDismissOnMenuPressed();
- }
-
- @Override
- public boolean onMenuPressed() {
- if (shouldUnlockOnMenuPressed()) {
- mShadeController.animateCollapseShadeForced();
- return true;
- }
- return false;
- }
-
- @Override
public void endAffordanceLaunch() {
releaseGestureWakeLock();
mCameraLauncherLazy.get().setLaunchingAffordance(false);
@@ -2692,15 +2653,6 @@
return (isScrimmedBouncer || isBouncerOverDream);
}
- @Override
- public boolean onSpacePressed() {
- if (mDeviceInteractive && mState != StatusBarState.SHADE) {
- mShadeController.animateCollapseShadeForced();
- return true;
- }
- return false;
- }
-
private void showBouncerOrLockScreenIfKeyguard() {
// If the keyguard is animating away, we aren't really the keyguard anymore and should not
// show the bouncer/lockscreen.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyNotificationIconAreaControllerImpl.java
similarity index 96%
rename from packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyNotificationIconAreaControllerImpl.java
index 0bf0f4b..d22ed38 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyNotificationIconAreaControllerImpl.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright (C) 2023 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.statusbar.phone;
import android.content.Context;
@@ -43,6 +58,8 @@
import com.android.systemui.statusbar.window.StatusBarWindowController;
import com.android.wm.shell.bubbles.Bubbles;
+import org.jetbrains.annotations.NotNull;
+
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
@@ -55,13 +72,13 @@
* normally reserved for notifications.
*/
@SysUISingleton
-public class NotificationIconAreaController implements
+public class LegacyNotificationIconAreaControllerImpl implements
+ NotificationIconAreaController,
DarkReceiver,
StatusBarStateController.StateListener,
NotificationWakeUpCoordinator.WakeUpListener,
DemoMode {
- public static final String HIGH_PRIORITY = "high_priority";
private static final long AOD_ICONS_APPEAR_DURATION = 200;
@ColorInt
private static final int DEFAULT_AOD_ICON_COLOR = 0xffffffff;
@@ -110,7 +127,7 @@
};
@Inject
- public NotificationIconAreaController(
+ public LegacyNotificationIconAreaControllerImpl(
Context context,
StatusBarStateController statusBarStateController,
NotificationWakeUpCoordinator wakeUpCoordinator,
@@ -192,7 +209,7 @@
}
}
- public void onDensityOrFontScaleChanged(Context context) {
+ public void onDensityOrFontScaleChanged(@NotNull Context context) {
updateIconLayoutParams(context);
}
@@ -493,7 +510,7 @@
mNotificationIcons.showIconIsolated(icon, animated);
}
- public void setIsolatedIconLocation(Rect iconDrawingRect, boolean requireStateUpdate) {
+ public void setIsolatedIconLocation(@NotNull Rect iconDrawingRect, boolean requireStateUpdate) {
mNotificationIcons.setIsolatedIconLocation(iconDrawingRect, requireStateUpdate);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.kt
new file mode 100644
index 0000000..0079f7c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.kt
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2023 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.statusbar.phone
+
+import android.content.Context
+import android.graphics.Rect
+import android.view.View
+import com.android.systemui.statusbar.NotificationShelfController
+import com.android.systemui.statusbar.StatusBarIconView
+import com.android.systemui.statusbar.notification.collection.ListEntry
+
+/**
+ * A controller for the space in the status bar to the left of the system icons. This area is
+ * normally reserved for notifications.
+ */
+interface NotificationIconAreaController {
+ /** Called by the Keyguard*ViewController whose view contains the aod icons. */
+ fun setupAodIcons(aodIcons: NotificationIconContainer)
+ fun setupShelf(notificationShelfController: NotificationShelfController)
+ fun setShelfIcons(icons: NotificationIconContainer)
+ fun onDensityOrFontScaleChanged(context: Context)
+
+ /** Returns the view that represents the notification area. */
+ fun getNotificationInnerAreaView(): View?
+
+ /** Updates the notifications with the given list of notifications to display. */
+ fun updateNotificationIcons(entries: List<@JvmSuppressWildcards ListEntry>)
+ fun updateAodNotificationIcons()
+ fun showIconIsolated(icon: StatusBarIconView?, animated: Boolean)
+ fun setIsolatedIconLocation(iconDrawingRect: Rect, requireStateUpdate: Boolean)
+ fun setAnimationsEnabled(enabled: Boolean)
+ fun onThemeChanged()
+ fun getHeight(): Int
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaControllerModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaControllerModule.kt
new file mode 100644
index 0000000..d1ddd51
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaControllerModule.kt
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 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.statusbar.phone
+
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
+import com.android.systemui.statusbar.notification.icon.ui.viewbinder.NotificationIconAreaControllerViewBinderWrapperImpl
+import dagger.Module
+import dagger.Provides
+import javax.inject.Provider
+
+@Module
+object NotificationIconAreaControllerModule {
+ @Provides
+ fun provideNotificationIconAreaControllerImpl(
+ featureFlags: FeatureFlags,
+ legacyProvider: Provider<LegacyNotificationIconAreaControllerImpl>,
+ newProvider: Provider<NotificationIconAreaControllerViewBinderWrapperImpl>,
+ ): NotificationIconAreaController =
+ if (featureFlags.isEnabled(Flags.NOTIFICATION_ICON_CONTAINER_REFACTOR)) {
+ newProvider.get()
+ } else {
+ legacyProvider.get()
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index fc66138..62a8cfd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -709,6 +709,11 @@
}
}
+ public void onUnlockAnimationFinished() {
+ mAnimatingPanelExpansionOnUnlock = false;
+ applyAndDispatchState();
+ }
+
/**
* Set the amount of progress we are currently in if we're transitioning to the full shade.
* 0.0f means we're not transitioning yet, while 1 means we're all the way in the full
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarLocation.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarLocation.kt
index 5ace226..32e5c35 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarLocation.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarLocation.kt
@@ -24,4 +24,6 @@
KEYGUARD,
/** Quick settings (inside the shade). */
QS,
+ /** ShadeCarrierGroup (above QS status bar in expanded mode). */
+ SHADE_CARRIER_GROUP,
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java
index 7fe01825..a6284e3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java
@@ -32,6 +32,8 @@
import android.view.View;
import android.view.ViewParent;
+import androidx.annotation.Nullable;
+
import com.android.systemui.ActivityIntentHelper;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
@@ -254,16 +256,16 @@
@Override
public boolean handleRemoteViewClick(View view, PendingIntent pendingIntent,
- boolean appRequestedAuth,
+ boolean appRequestedAuth, @Nullable Integer actionIndex,
NotificationRemoteInputManager.ClickHandler defaultHandler) {
final boolean isActivity = pendingIntent.isActivity();
if (isActivity || appRequestedAuth) {
- mActionClickLogger.logWaitingToCloseKeyguard(pendingIntent);
+ mActionClickLogger.logWaitingToCloseKeyguard(pendingIntent, actionIndex);
final boolean afterKeyguardGone = mActivityIntentHelper
.wouldPendingLaunchResolverActivity(pendingIntent,
mLockscreenUserManager.getCurrentUserId());
mActivityStarter.dismissKeyguardThenExecute(() -> {
- mActionClickLogger.logKeyguardGone(pendingIntent);
+ mActionClickLogger.logKeyguardGone(pendingIntent, actionIndex);
try {
ActivityManager.getService().resumeAppSwitches();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt
index 1bceb29..cd1afc7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt
@@ -223,10 +223,14 @@
}
.setCustomInterpolator(View.ALPHA, Interpolators.FAST_OUT_SLOW_IN),
true /* animate */)
- interactionJankMonitor.begin(
- notifShadeWindowControllerLazy.get().windowRootView,
- CUJ_SCREEN_OFF_SHOW_AOD
- )
+ val builder = InteractionJankMonitor.Configuration.Builder
+ .withView(
+ InteractionJankMonitor.CUJ_SCREEN_OFF_SHOW_AOD,
+ notifShadeWindowControllerLazy.get().windowRootView
+ )
+ .setTag(statusBarStateControllerImpl.getClockId())
+
+ interactionJankMonitor.begin(builder)
}
override fun onStartedWakingUp() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/StatusBarPipelineFlags.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/StatusBarPipelineFlags.kt
index 6e51ed0..c695773 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/StatusBarPipelineFlags.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/StatusBarPipelineFlags.kt
@@ -18,6 +18,9 @@
import android.content.Context
import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
+import com.android.systemui.shade.carrier.ShadeCarrierGroup
import javax.inject.Inject
/** All flagging methods related to the new status bar pipeline (see b/238425913). */
@@ -26,11 +29,19 @@
@Inject
constructor(
context: Context,
+ private val featureFlags: FeatureFlags,
) {
private val mobileSlot = context.getString(com.android.internal.R.string.status_bar_mobile)
private val wifiSlot = context.getString(com.android.internal.R.string.status_bar_wifi)
/**
+ * True if we should display the mobile icons in the [ShadeCarrierGroup] using the new status
+ * bar Data pipeline.
+ */
+ fun useNewShadeCarrierGroupMobileIcons(): Boolean =
+ featureFlags.isEnabled(Flags.NEW_SHADE_CARRIER_GROUP_MOBILE_ICONS)
+
+ /**
* For convenience in the StatusBarIconController, we want to gate some actions based on slot
* name and the flag together.
*
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/NetworkNameModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/NetworkNameModel.kt
index 78231e2..99ed2d9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/NetworkNameModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/NetworkNameModel.kt
@@ -60,6 +60,19 @@
}
}
+ /** This name has been derived from SubscriptionModel. see [SubscriptionModel] */
+ data class SubscriptionDerived(override val name: String) : NetworkNameModel {
+ override fun logDiffs(prevVal: NetworkNameModel, row: TableRowLogger) {
+ if (prevVal !is SubscriptionDerived || prevVal.name != name) {
+ row.logChange(COL_NETWORK_NAME, "SubscriptionDerived($name)")
+ }
+ }
+
+ override fun logFull(row: TableRowLogger) {
+ row.logChange(COL_NETWORK_NAME, "SubscriptionDerived($name)")
+ }
+ }
+
/**
* This name has been derived from the sim via
* [android.telephony.TelephonyManager.getSimOperatorName].
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/SubscriptionModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/SubscriptionModel.kt
index 16c4027..27f6df4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/SubscriptionModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/SubscriptionModel.kt
@@ -34,4 +34,7 @@
/** Subscriptions in the same group may be filtered or treated as a single subscription */
val groupUuid: ParcelUuid? = null,
+
+ /** Text representing the name for this connection */
+ val carrierName: String,
)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionRepository.kt
index c1af6df..a89b1b2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionRepository.kt
@@ -115,10 +115,18 @@
*/
val cdmaRoaming: StateFlow<Boolean>
- /** The service provider name for this network connection, or the default name */
+ /** The service provider name for this network connection, or the default name. */
val networkName: StateFlow<NetworkNameModel>
/**
+ * The service provider name for this network connection, or the default name.
+ *
+ * TODO(b/296600321): De-duplicate this field with [networkName] after determining the data
+ * provided is identical
+ */
+ val carrierName: StateFlow<NetworkNameModel>
+
+ /**
* True if this type of connection is allowed while airplane mode is on, and false otherwise.
*/
val isAllowedDuringAirplaneMode: StateFlow<Boolean>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionRepository.kt
index 17d20c2..c576b82 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionRepository.kt
@@ -184,7 +184,10 @@
override val cdmaRoaming = MutableStateFlow(false)
- override val networkName = MutableStateFlow(NetworkNameModel.IntentDerived("demo network"))
+ override val networkName = MutableStateFlow(NetworkNameModel.IntentDerived(DEMO_CARRIER_NAME))
+
+ override val carrierName =
+ MutableStateFlow(NetworkNameModel.SubscriptionDerived(DEMO_CARRIER_NAME))
override val isAllowedDuringAirplaneMode = MutableStateFlow(false)
@@ -200,6 +203,7 @@
// This is always true here, because we split out disabled states at the data-source level
dataEnabled.value = true
networkName.value = NetworkNameModel.IntentDerived(event.name)
+ carrierName.value = NetworkNameModel.SubscriptionDerived("${event.name} ${event.subId}")
_carrierId.value = event.carrierId ?: INVALID_SUBSCRIPTION_ID
@@ -227,6 +231,7 @@
// This is always true here, because we split out disabled states at the data-source level
dataEnabled.value = true
networkName.value = NetworkNameModel.IntentDerived(CARRIER_MERGED_NAME)
+ carrierName.value = NetworkNameModel.SubscriptionDerived(CARRIER_MERGED_NAME)
// TODO(b/276943904): is carrierId a thing with carrier merged networks?
_carrierId.value = INVALID_SUBSCRIPTION_ID
numberOfLevels.value = event.numberOfLevels
@@ -248,6 +253,7 @@
}
companion object {
+ private const val DEMO_CARRIER_NAME = "Demo Carrier"
private const val CARRIER_MERGED_NAME = "Carrier Merged Network"
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt
index 0e4ceeb..ee13d93 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt
@@ -92,9 +92,12 @@
private fun maybeCreateSubscription(subId: Int) {
if (!subscriptionInfoCache.containsKey(subId)) {
- SubscriptionModel(subscriptionId = subId, isOpportunistic = false).also {
- subscriptionInfoCache[subId] = it
- }
+ SubscriptionModel(
+ subscriptionId = subId,
+ isOpportunistic = false,
+ carrierName = DEFAULT_CARRIER_NAME,
+ )
+ .also { subscriptionInfoCache[subId] = it }
_subscriptions.value = subscriptionInfoCache.values.toList()
}
@@ -327,6 +330,7 @@
private const val TAG = "DemoMobileConnectionsRepo"
private const val DEFAULT_SUB_ID = 1
+ private const val DEFAULT_CARRIER_NAME = "demo carrier"
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepository.kt
index 65f4866..28be3be 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepository.kt
@@ -108,6 +108,8 @@
NetworkNameModel.SimDerived(telephonyManager.simOperatorName),
)
+ override val carrierName: StateFlow<NetworkNameModel> = networkName
+
override val numberOfLevels: StateFlow<Int> =
wifiRepository.wifiNetwork
.map {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepository.kt
index 8ba7d21..ee11c06 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepository.kt
@@ -22,6 +22,7 @@
import com.android.systemui.log.table.TableLogBufferFactory
import com.android.systemui.log.table.logDiffsForTable
import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
+import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
@@ -47,6 +48,7 @@
override val subId: Int,
startingIsCarrierMerged: Boolean,
override val tableLogBuffer: TableLogBuffer,
+ subscriptionModel: StateFlow<SubscriptionModel?>,
private val defaultNetworkName: NetworkNameModel,
private val networkNameSeparator: String,
@Application scope: CoroutineScope,
@@ -80,6 +82,7 @@
mobileRepoFactory.build(
subId,
tableLogBuffer,
+ subscriptionModel,
defaultNetworkName,
networkNameSeparator,
)
@@ -287,6 +290,16 @@
)
.stateIn(scope, SharingStarted.WhileSubscribed(), activeRepo.value.networkName.value)
+ override val carrierName =
+ activeRepo
+ .flatMapLatest { it.carrierName }
+ .logDiffsForTable(
+ tableLogBuffer,
+ columnPrefix = "",
+ initialValue = activeRepo.value.carrierName.value,
+ )
+ .stateIn(scope, SharingStarted.WhileSubscribed(), activeRepo.value.carrierName.value)
+
override val isAllowedDuringAirplaneMode =
activeRepo
.flatMapLatest { it.isAllowedDuringAirplaneMode }
@@ -307,6 +320,7 @@
fun build(
subId: Int,
startingIsCarrierMerged: Boolean,
+ subscriptionModel: StateFlow<SubscriptionModel?>,
defaultNetworkName: NetworkNameModel,
networkNameSeparator: String,
): FullMobileConnectionRepository {
@@ -317,6 +331,7 @@
subId,
startingIsCarrierMerged,
mobileLogger,
+ subscriptionModel,
defaultNetworkName,
networkNameSeparator,
scope,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt
index aadc975..1f1ac92 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt
@@ -43,6 +43,7 @@
import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.DefaultNetworkType
import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.OverrideNetworkType
import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.UnknownNetworkType
+import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
import com.android.systemui.statusbar.pipeline.mobile.data.model.SystemUiCarrierConfig
import com.android.systemui.statusbar.pipeline.mobile.data.model.toDataConnectionType
import com.android.systemui.statusbar.pipeline.mobile.data.model.toNetworkNameModel
@@ -80,6 +81,7 @@
@OptIn(ExperimentalCoroutinesApi::class)
class MobileConnectionRepositoryImpl(
override val subId: Int,
+ subscriptionModel: StateFlow<SubscriptionModel?>,
defaultNetworkName: NetworkNameModel,
networkNameSeparator: String,
private val telephonyManager: TelephonyManager,
@@ -281,6 +283,14 @@
}
.stateIn(scope, SharingStarted.WhileSubscribed(), DEFAULT_NUM_LEVELS)
+ override val carrierName =
+ subscriptionModel
+ .map {
+ it?.let { model -> NetworkNameModel.SubscriptionDerived(model.carrierName) }
+ ?: defaultNetworkName
+ }
+ .stateIn(scope, SharingStarted.WhileSubscribed(), defaultNetworkName)
+
/**
* There are a few cases where we will need to poll [TelephonyManager] so we can update some
* internal state where callbacks aren't provided. Any of those events should be merged into
@@ -350,11 +360,13 @@
fun build(
subId: Int,
mobileLogger: TableLogBuffer,
+ subscriptionModel: StateFlow<SubscriptionModel?>,
defaultNetworkName: NetworkNameModel,
networkNameSeparator: String,
): MobileConnectionRepository {
return MobileConnectionRepositoryImpl(
subId,
+ subscriptionModel,
defaultNetworkName,
networkNameSeparator,
telephonyManager.createForSubscriptionId(subId),
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt
index 54948a4..67b04db 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt
@@ -319,10 +319,17 @@
@VisibleForTesting fun getSubIdRepoCache() = subIdRepositoryCache
+ private fun subscriptionModelForSubId(subId: Int): StateFlow<SubscriptionModel?> {
+ return subscriptions
+ .map { list -> list.firstOrNull { model -> model.subscriptionId == subId } }
+ .stateIn(scope, SharingStarted.WhileSubscribed(), null)
+ }
+
private fun createRepositoryForSubId(subId: Int): FullMobileConnectionRepository {
return fullMobileRepoFactory.build(
subId,
isCarrierMerged(subId),
+ subscriptionModelForSubId(subId),
defaultNetworkName,
networkNameSeparator,
)
@@ -373,6 +380,7 @@
subscriptionId = subscriptionId,
isOpportunistic = isOpportunistic,
groupUuid = groupUuid,
+ carrierName = carrierName.toString(),
)
companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt
index 1a13827..4cfde5b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt
@@ -92,6 +92,22 @@
*/
val networkName: StateFlow<NetworkNameModel>
+ /**
+ * Provider name for this network connection. The name can be one of 3 values:
+ * 1. The default network name, if one is configured
+ * 2. A name provided by the [SubscriptionModel] of this network connection
+ * 3. Or, in the case where the repository sends us the default network name, we check for an
+ * override in [connectionInfo.operatorAlphaShort], a value that is derived from
+ * [ServiceState]
+ *
+ * TODO(b/296600321): De-duplicate this field with [networkName] after determining the data
+ * provided is identical
+ */
+ val carrierName: StateFlow<String>
+
+ /** True if there is only one active subscription. */
+ val isSingleCarrier: StateFlow<Boolean>
+
/** True if this line of service is emergency-only */
val isEmergencyOnly: StateFlow<Boolean>
@@ -126,6 +142,7 @@
defaultSubscriptionHasDataEnabled: StateFlow<Boolean>,
override val alwaysShowDataRatIcon: StateFlow<Boolean>,
override val alwaysUseCdmaLevel: StateFlow<Boolean>,
+ override val isSingleCarrier: StateFlow<Boolean>,
override val mobileIsDefault: StateFlow<Boolean>,
defaultMobileIconMapping: StateFlow<Map<String, MobileIconGroup>>,
defaultMobileIconGroup: StateFlow<MobileIconGroup>,
@@ -171,6 +188,22 @@
connectionRepository.networkName.value
)
+ override val carrierName =
+ combine(connectionRepository.operatorAlphaShort, connectionRepository.carrierName) {
+ operatorAlphaShort,
+ networkName ->
+ if (networkName is NetworkNameModel.Default && operatorAlphaShort != null) {
+ operatorAlphaShort
+ } else {
+ networkName.name
+ }
+ }
+ .stateIn(
+ scope,
+ SharingStarted.WhileSubscribed(),
+ connectionRepository.carrierName.value.name
+ )
+
/** What the mobile icon would be before carrierId overrides */
private val defaultNetworkType: StateFlow<MobileIconGroup> =
combine(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt
index e90f40c7..d08808b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt
@@ -76,6 +76,9 @@
/** True if the CDMA level should be preferred over the primary level. */
val alwaysUseCdmaLevel: StateFlow<Boolean>
+ /** True if there is only one active subscription. */
+ val isSingleCarrier: StateFlow<Boolean>
+
/** The icon mapping from network type to [MobileIconGroup] for the default subscription */
val defaultMobileIconMapping: StateFlow<Map<String, MobileIconGroup>>
@@ -252,6 +255,17 @@
.mapLatest { it.alwaysShowCdmaRssi }
.stateIn(scope, SharingStarted.WhileSubscribed(), false)
+ override val isSingleCarrier: StateFlow<Boolean> =
+ mobileConnectionsRepo.subscriptions
+ .map { it.size == 1 }
+ .logDiffsForTable(
+ tableLogger,
+ columnPrefix = LOGGING_PREFIX,
+ columnName = "isSingleCarrier",
+ initialValue = false,
+ )
+ .stateIn(scope, SharingStarted.WhileSubscribed(), false)
+
/** If there is no mapping in [defaultMobileIconMapping], then use this default icon group */
override val defaultMobileIconGroup: StateFlow<MobileIconGroup> =
mobileConnectionsRepo.defaultMobileIconGroup.stateIn(
@@ -298,6 +312,7 @@
activeDataConnectionHasDataEnabled,
alwaysShowDataRatIcon,
alwaysUseCdmaLevel,
+ isSingleCarrier,
mobileIsDefault,
defaultMobileIconMapping,
defaultMobileIconGroup,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/MobileUiAdapter.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/MobileUiAdapter.kt
index d7fcf48..02e50a0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/MobileUiAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/MobileUiAdapter.kt
@@ -19,6 +19,7 @@
import com.android.systemui.CoreStartable
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.shade.carrier.ShadeCarrierGroupController
import com.android.systemui.statusbar.phone.StatusBarIconController
import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconsInteractor
import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.MobileIconsViewModel
@@ -49,6 +50,8 @@
private var isCollecting: Boolean = false
private var lastValue: List<Int>? = null
+ private var shadeCarrierGroupController: ShadeCarrierGroupController? = null
+
override fun start() {
// Start notifying the icon controller of subscriptions
scope.launch {
@@ -57,10 +60,16 @@
logger.logUiAdapterSubIdsSentToIconController(it)
lastValue = it
iconController.setNewMobileIconSubIds(it)
+ shadeCarrierGroupController?.updateModernMobileIcons(it)
}
}
}
+ /** Set the [ShadeCarrierGroupController] to notify of subscription updates */
+ fun setShadeCarrierGroupController(controller: ShadeCarrierGroupController) {
+ shadeCarrierGroupController = controller
+ }
+
override fun dump(pw: PrintWriter, args: Array<out String>) {
pw.println("isCollecting=$isCollecting")
pw.println("Last values sent to icon controller: $lastValue")
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/MobileViewLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/MobileViewLogger.kt
index cea6654..2af6795b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/MobileViewLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/MobileViewLogger.kt
@@ -57,7 +57,7 @@
{
str1 = view.getIdForLogging()
str2 = viewModel.getIdForLogging()
- str3 = viewModel.locationName
+ str3 = viewModel.location.name
},
{ "New view binding. viewId=$str1, viewModelId=$str2, viewModelLocation=$str3" },
)
@@ -71,7 +71,7 @@
{
str1 = view.getIdForLogging()
str2 = viewModel.getIdForLogging()
- str3 = viewModel.locationName
+ str3 = viewModel.location.name
},
{ "Collection started. viewId=$str1, viewModelId=$str2, viewModelLocation=$str3" },
)
@@ -85,7 +85,7 @@
{
str1 = view.getIdForLogging()
str2 = viewModel.getIdForLogging()
- str3 = viewModel.locationName
+ str3 = viewModel.location.name
},
{ "Collection stopped. viewId=$str1, viewModelId=$str2, viewModelLocation=$str3" },
)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt
index 55bc8d5..4b2fb43 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt
@@ -50,6 +50,7 @@
fun bind(
view: ViewGroup,
viewModel: LocationBasedMobileViewModel,
+ @StatusBarIconView.VisibleState initialVisibilityState: Int = STATE_HIDDEN,
logger: MobileViewLogger,
): ModernStatusBarViewBinding {
val mobileGroupView = view.requireViewById<ViewGroup>(R.id.mobile_group)
@@ -68,12 +69,12 @@
// TODO(b/238425913): We should log this visibility state.
@StatusBarIconView.VisibleState
- val visibilityState: MutableStateFlow<Int> = MutableStateFlow(STATE_HIDDEN)
+ val visibilityState: MutableStateFlow<Int> = MutableStateFlow(initialVisibilityState)
val iconTint: MutableStateFlow<Int> = MutableStateFlow(viewModel.defaultColor)
val decorTint: MutableStateFlow<Int> = MutableStateFlow(viewModel.defaultColor)
- var isCollecting: Boolean = false
+ var isCollecting = false
view.repeatWhenAttached {
repeatOnLifecycle(Lifecycle.State.STARTED) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/ShadeCarrierBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/ShadeCarrierBinder.kt
new file mode 100644
index 0000000..081e101
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/ShadeCarrierBinder.kt
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2023 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.statusbar.pipeline.mobile.ui.binder
+
+import androidx.core.view.isVisible
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.repeatOnLifecycle
+import com.android.systemui.lifecycle.repeatWhenAttached
+import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.ShadeCarrierGroupMobileIconViewModel
+import com.android.systemui.util.AutoMarqueeTextView
+import kotlinx.coroutines.launch
+
+object ShadeCarrierBinder {
+ /** Binds the view to the view-model, continuing to update the former based on the latter */
+ @JvmStatic
+ fun bind(
+ carrierTextView: AutoMarqueeTextView,
+ viewModel: ShadeCarrierGroupMobileIconViewModel,
+ ) {
+ carrierTextView.isVisible = true
+
+ carrierTextView.repeatWhenAttached {
+ repeatOnLifecycle(Lifecycle.State.STARTED) {
+ launch { viewModel.carrierName.collect { carrierTextView.text = it } }
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernShadeCarrierGroupMobileView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernShadeCarrierGroupMobileView.kt
new file mode 100644
index 0000000..f407127
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernShadeCarrierGroupMobileView.kt
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2023 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.statusbar.pipeline.mobile.ui.view
+
+import android.content.Context
+import android.util.AttributeSet
+import android.view.LayoutInflater
+import android.widget.LinearLayout
+import com.android.systemui.R
+import com.android.systemui.statusbar.StatusBarIconView.STATE_ICON
+import com.android.systemui.statusbar.pipeline.mobile.ui.MobileViewLogger
+import com.android.systemui.statusbar.pipeline.mobile.ui.binder.MobileIconBinder
+import com.android.systemui.statusbar.pipeline.mobile.ui.binder.ShadeCarrierBinder
+import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.ShadeCarrierGroupMobileIconViewModel
+import com.android.systemui.util.AutoMarqueeTextView
+
+/**
+ * ViewGroup containing a mobile carrier name and icon in the Shade Header. Can be multiple
+ * instances as children under [ShadeCarrierGroup]
+ */
+class ModernShadeCarrierGroupMobileView(
+ context: Context,
+ attrs: AttributeSet?,
+) : LinearLayout(context, attrs) {
+
+ var subId: Int = -1
+
+ override fun toString(): String {
+ return "ModernShadeCarrierGroupMobileView(" +
+ "subId=$subId, " +
+ "viewString=${super.toString()}"
+ }
+
+ companion object {
+
+ /**
+ * Inflates a new instance of [ModernShadeCarrierGroupMobileView], binds it to [viewModel],
+ * and returns it.
+ */
+ @JvmStatic
+ fun constructAndBind(
+ context: Context,
+ logger: MobileViewLogger,
+ slot: String,
+ viewModel: ShadeCarrierGroupMobileIconViewModel,
+ ): ModernShadeCarrierGroupMobileView {
+ return (LayoutInflater.from(context).inflate(R.layout.shade_carrier_new, null)
+ as ModernShadeCarrierGroupMobileView)
+ .also {
+ it.subId = viewModel.subscriptionId
+
+ val iconView = it.requireViewById<ModernStatusBarMobileView>(R.id.mobile_combo)
+ iconView.initView(slot) {
+ MobileIconBinder.bind(iconView, viewModel, STATE_ICON, logger)
+ }
+ logger.logNewViewBinding(it, viewModel)
+
+ val textView = it.requireViewById<AutoMarqueeTextView>(R.id.mobile_carrier_text)
+ ShadeCarrierBinder.bind(textView, viewModel)
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileView.kt
index 4144293d..68d02de 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileView.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileView.kt
@@ -60,7 +60,9 @@
as ModernStatusBarMobileView)
.also {
it.subId = viewModel.subscriptionId
- it.initView(slot) { MobileIconBinder.bind(it, viewModel, logger) }
+ it.initView(slot) {
+ MobileIconBinder.bind(view = it, viewModel = viewModel, logger = logger)
+ }
logger.logNewViewBinding(it, viewModel)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileViewModel.kt
index a51982c..e7c311d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileViewModel.kt
@@ -18,7 +18,13 @@
import android.graphics.Color
import com.android.systemui.statusbar.phone.StatusBarLocation
+import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconInteractor
import com.android.systemui.statusbar.pipeline.mobile.ui.VerboseMobileViewLogger
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.stateIn
/**
* A view model for an individual mobile icon that embeds the notion of a [StatusBarLocation]. This
@@ -26,12 +32,12 @@
*
* @param commonImpl for convenience, this class wraps a base interface that can provides all of the
* common implementations between locations. See [MobileIconViewModel]
- * @property locationName the name of the location of this VM, used for logging.
+ * @property location the [StatusBarLocation] of this VM.
* @property verboseLogger an optional logger to log extremely verbose view updates.
*/
abstract class LocationBasedMobileViewModel(
val commonImpl: MobileIconViewModelCommon,
- val locationName: String,
+ val location: StatusBarLocation,
val verboseLogger: VerboseMobileViewLogger?,
) : MobileIconViewModelCommon by commonImpl {
val defaultColor: Int = Color.WHITE
@@ -39,10 +45,12 @@
companion object {
fun viewModelForLocation(
commonImpl: MobileIconViewModelCommon,
+ interactor: MobileIconInteractor,
verboseMobileViewLogger: VerboseMobileViewLogger,
- loc: StatusBarLocation,
+ location: StatusBarLocation,
+ scope: CoroutineScope,
): LocationBasedMobileViewModel =
- when (loc) {
+ when (location) {
StatusBarLocation.HOME ->
HomeMobileIconViewModel(
commonImpl,
@@ -50,6 +58,12 @@
)
StatusBarLocation.KEYGUARD -> KeyguardMobileIconViewModel(commonImpl)
StatusBarLocation.QS -> QsMobileIconViewModel(commonImpl)
+ StatusBarLocation.SHADE_CARRIER_GROUP ->
+ ShadeCarrierGroupMobileIconViewModel(
+ commonImpl,
+ interactor,
+ scope,
+ )
}
}
}
@@ -61,7 +75,7 @@
MobileIconViewModelCommon,
LocationBasedMobileViewModel(
commonImpl,
- locationName = "Home",
+ location = StatusBarLocation.HOME,
verboseMobileViewLogger,
)
@@ -71,18 +85,40 @@
MobileIconViewModelCommon,
LocationBasedMobileViewModel(
commonImpl,
- locationName = "QS",
+ location = StatusBarLocation.QS,
// Only do verbose logging for the Home location.
verboseLogger = null,
)
+class ShadeCarrierGroupMobileIconViewModel(
+ commonImpl: MobileIconViewModelCommon,
+ interactor: MobileIconInteractor,
+ scope: CoroutineScope,
+) :
+ MobileIconViewModelCommon,
+ LocationBasedMobileViewModel(
+ commonImpl,
+ location = StatusBarLocation.SHADE_CARRIER_GROUP,
+ // Only do verbose logging for the Home location.
+ verboseLogger = null,
+ ) {
+ private val isSingleCarrier = interactor.isSingleCarrier
+ val carrierName = interactor.carrierName
+
+ override val isVisible: StateFlow<Boolean> =
+ combine(super.isVisible, isSingleCarrier) { isVisible, isSingleCarrier ->
+ if (isSingleCarrier) false else isVisible
+ }
+ .stateIn(scope, SharingStarted.WhileSubscribed(), super.isVisible.value)
+}
+
class KeyguardMobileIconViewModel(
commonImpl: MobileIconViewModelCommon,
) :
MobileIconViewModelCommon,
LocationBasedMobileViewModel(
commonImpl,
- locationName = "Keyguard",
+ location = StatusBarLocation.KEYGUARD,
// Only do verbose logging for the Home location.
verboseLogger = null,
)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModel.kt
index 5cf887e..216afb9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModel.kt
@@ -22,6 +22,7 @@
import com.android.systemui.statusbar.phone.StatusBarLocation
import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags
import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.AirplaneModeInteractor
+import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconInteractor
import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconsInteractor
import com.android.systemui.statusbar.pipeline.mobile.ui.MobileViewLogger
import com.android.systemui.statusbar.pipeline.mobile.ui.VerboseMobileViewLogger
@@ -58,6 +59,8 @@
private val statusBarPipelineFlags: StatusBarPipelineFlags,
) {
@VisibleForTesting val mobileIconSubIdCache = mutableMapOf<Int, MobileIconViewModel>()
+ @VisibleForTesting
+ val mobileIconInteractorSubIdCache = mutableMapOf<Int, MobileIconInteractor>()
val subscriptionIdsFlow: StateFlow<List<Int>> =
interactor.filteredSubscriptions
@@ -91,15 +94,17 @@
.stateIn(scope, SharingStarted.WhileSubscribed(), false)
init {
- scope.launch { subscriptionIdsFlow.collect { removeInvalidModelsFromCache(it) } }
+ scope.launch { subscriptionIdsFlow.collect { invalidateCaches(it) } }
}
fun viewModelForSub(subId: Int, location: StatusBarLocation): LocationBasedMobileViewModel {
val common = commonViewModelForSub(subId)
return LocationBasedMobileViewModel.viewModelForLocation(
common,
+ mobileIconInteractorForSub(subId),
verboseLogger,
location,
+ scope,
)
}
@@ -107,7 +112,7 @@
return mobileIconSubIdCache[subId]
?: MobileIconViewModel(
subId,
- interactor.createMobileConnectionInteractorForSubId(subId),
+ mobileIconInteractorForSub(subId),
airplaneModeInteractor,
constants,
scope,
@@ -115,8 +120,20 @@
.also { mobileIconSubIdCache[subId] = it }
}
- private fun removeInvalidModelsFromCache(subIds: List<Int>) {
+ @VisibleForTesting
+ fun mobileIconInteractorForSub(subId: Int): MobileIconInteractor {
+ return mobileIconInteractorSubIdCache[subId]
+ ?: interactor.createMobileConnectionInteractorForSubId(subId).also {
+ mobileIconInteractorSubIdCache[subId] = it
+ }
+ }
+
+ private fun invalidateCaches(subIds: List<Int>) {
val subIdsToRemove = mobileIconSubIdCache.keys.filter { !subIds.contains(it) }
subIdsToRemove.forEach { mobileIconSubIdCache.remove(it) }
+
+ mobileIconInteractorSubIdCache.keys
+ .filter { !subIds.contains(it) }
+ .forEach { subId -> mobileIconInteractorSubIdCache.remove(subId) }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/LocationBasedWifiViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/LocationBasedWifiViewModel.kt
index cd5b92c..00bd616 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/LocationBasedWifiViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/LocationBasedWifiViewModel.kt
@@ -18,6 +18,7 @@
import android.graphics.Color
import com.android.systemui.statusbar.phone.StatusBarLocation
+import java.lang.IllegalArgumentException
/**
* A view model for a wifi icon in a specific location. This allows us to control parameters that
@@ -43,6 +44,8 @@
StatusBarLocation.HOME -> HomeWifiViewModel(commonImpl)
StatusBarLocation.KEYGUARD -> KeyguardWifiViewModel(commonImpl)
StatusBarLocation.QS -> QsWifiViewModel(commonImpl)
+ StatusBarLocation.SHADE_CARRIER_GROUP ->
+ throw IllegalArgumentException("invalid location for WifiViewModel: $location")
}
}
}
@@ -64,3 +67,11 @@
class QsWifiViewModel(
commonImpl: WifiViewModelCommon,
) : WifiViewModelCommon, LocationBasedWifiViewModel(commonImpl)
+
+/**
+ * A view model for the wifi icon in the shade carrier group (visible when quick settings is fully
+ * expanded, and in large screen shade). Currently unused.
+ */
+class ShadeCarrierGroupWifiViewModel(
+ commonImpl: WifiViewModelCommon,
+) : WifiViewModelCommon, LocationBasedWifiViewModel(commonImpl)
diff --git a/packages/SystemUI/src/com/android/systemui/wallpapers/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/wallpapers/ImageWallpaper.java
index 091a54f..316b54e 100644
--- a/packages/SystemUI/src/com/android/systemui/wallpapers/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/wallpapers/ImageWallpaper.java
@@ -109,7 +109,6 @@
private WallpaperManager mWallpaperManager;
private final WallpaperLocalColorExtractor mWallpaperLocalColorExtractor;
private SurfaceHolder mSurfaceHolder;
- private boolean mDrawn = false;
@VisibleForTesting
static final int MIN_SURFACE_WIDTH = 128;
@VisibleForTesting
@@ -239,7 +238,6 @@
private void drawFrameSynchronized() {
synchronized (mLock) {
- if (mDrawn) return;
drawFrameInternal();
}
}
@@ -277,7 +275,6 @@
Rect dest = mSurfaceHolder.getSurfaceFrame();
try {
canvas.drawBitmap(bitmap, null, dest, null);
- mDrawn = true;
} finally {
surface.unlockCanvasAndPost(canvas);
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt
index a9aed2f..b5317fa 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt
@@ -620,6 +620,51 @@
configurationListenerArgumentCaptor.value.onUiModeChanged()
verify(view).reloadColors()
}
+ @Test
+ fun onOrientationChanged_landscapeKeyguardFlagDisabled_blockReinflate() {
+ featureFlags.set(Flags.LOCKSCREEN_ENABLE_LANDSCAPE, false)
+
+ // Run onOrientationChanged
+ val configurationListenerArgumentCaptor =
+ ArgumentCaptor.forClass(ConfigurationController.ConfigurationListener::class.java)
+ underTest.onViewAttached()
+ verify(configurationController).addCallback(configurationListenerArgumentCaptor.capture())
+ clearInvocations(viewFlipperController)
+ configurationListenerArgumentCaptor.value.onOrientationChanged(
+ Configuration.ORIENTATION_LANDSCAPE
+ )
+ // Verify view is reinflated when flag is on
+ verify(viewFlipperController, never()).clearViews()
+ verify(viewFlipperController, never())
+ .asynchronouslyInflateView(
+ eq(SecurityMode.PIN),
+ any(),
+ onViewInflatedCallbackArgumentCaptor.capture()
+ )
+ }
+
+ @Test
+ fun onOrientationChanged_landscapeKeyguardFlagEnabled_doesReinflate() {
+ featureFlags.set(Flags.LOCKSCREEN_ENABLE_LANDSCAPE, true)
+
+ // Run onOrientationChanged
+ val configurationListenerArgumentCaptor =
+ ArgumentCaptor.forClass(ConfigurationController.ConfigurationListener::class.java)
+ underTest.onViewAttached()
+ verify(configurationController).addCallback(configurationListenerArgumentCaptor.capture())
+ clearInvocations(viewFlipperController)
+ configurationListenerArgumentCaptor.value.onOrientationChanged(
+ Configuration.ORIENTATION_LANDSCAPE
+ )
+ // Verify view is reinflated when flag is on
+ verify(viewFlipperController).clearViews()
+ verify(viewFlipperController)
+ .asynchronouslyInflateView(
+ eq(SecurityMode.PIN),
+ any(),
+ onViewInflatedCallbackArgumentCaptor.capture()
+ )
+ }
@Test
fun hasDismissActions() {
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java
index 7d23c80..b8b0198 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java
@@ -77,7 +77,7 @@
public void updatePosition_primaryClockAnimation() {
ClockController mockClock = mock(ClockController.class);
when(mKeyguardClockSwitchController.getClock()).thenReturn(mockClock);
- when(mockClock.getConfig()).thenReturn(new ClockConfig(false, true));
+ when(mockClock.getConfig()).thenReturn(new ClockConfig("MOCK", false, true));
mController.updatePosition(10, 15, 20f, true);
@@ -92,7 +92,7 @@
public void updatePosition_alternateClockAnimation() {
ClockController mockClock = mock(ClockController.class);
when(mKeyguardClockSwitchController.getClock()).thenReturn(mockClock);
- when(mockClock.getConfig()).thenReturn(new ClockConfig(true, true));
+ when(mockClock.getConfig()).thenReturn(new ClockConfig("MOCK", true, true));
mController.updatePosition(10, 15, 20f, true);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/LightRevealScrimRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/LightRevealScrimRepositoryTest.kt
index dcaafe8..6fcf54c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/LightRevealScrimRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/LightRevealScrimRepositoryTest.kt
@@ -17,8 +17,8 @@
package com.android.systemui.keyguard.data.repository
import android.graphics.Point
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
@@ -47,7 +47,7 @@
@SmallTest
@RoboPilotTest
@OptIn(ExperimentalCoroutinesApi::class)
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class LightRevealScrimRepositoryTest : SysuiTestCase() {
private lateinit var fakeKeyguardRepository: FakeKeyguardRepository
private lateinit var underTest: LightRevealScrimRepositoryImpl
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardKeyEventInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardKeyEventInteractorTest.kt
index a3f7fc5..e0ae0c3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardKeyEventInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardKeyEventInteractorTest.kt
@@ -131,14 +131,12 @@
}
@Test
- fun dispatchKeyEvent_menuActionUp_interactiveKeyguard_collapsesShade() {
+ fun dispatchKeyEvent_menuActionUp_interactiveKeyguard_showsPrimaryBouncer() {
keyguardInteractorWithDependencies.repository.setWakefulnessModel(awakeWakefulnessMode)
whenever(statusBarStateController.state).thenReturn(StatusBarState.KEYGUARD)
whenever(statusBarKeyguardViewManager.shouldDismissOnMenuPressed()).thenReturn(true)
- val actionUpMenuKeyEvent = KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MENU)
- assertThat(underTest.dispatchKeyEvent(actionUpMenuKeyEvent)).isTrue()
- verify(shadeController).animateCollapseShadeForced()
+ verifyActionUpShowsPrimaryBouncer(KeyEvent.KEYCODE_MENU)
}
@Test
@@ -147,42 +145,48 @@
whenever(statusBarStateController.state).thenReturn(StatusBarState.SHADE_LOCKED)
whenever(statusBarKeyguardViewManager.shouldDismissOnMenuPressed()).thenReturn(true)
- // action down: does NOT collapse the shade
- val actionDownMenuKeyEvent = KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MENU)
- assertThat(underTest.dispatchKeyEvent(actionDownMenuKeyEvent)).isFalse()
- verify(shadeController, never()).animateCollapseShadeForced()
-
- // action up: collapses the shade
- val actionUpMenuKeyEvent = KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MENU)
- assertThat(underTest.dispatchKeyEvent(actionUpMenuKeyEvent)).isTrue()
- verify(shadeController).animateCollapseShadeForced()
+ verifyActionUpCollapsesTheShade(KeyEvent.KEYCODE_MENU)
}
@Test
- fun dispatchKeyEvent_menuActionUp_nonInteractiveKeyguard_neverCollapsesShade() {
+ fun dispatchKeyEvent_menuActionUp_nonInteractiveKeyguard_doNothing() {
keyguardInteractorWithDependencies.repository.setWakefulnessModel(asleepWakefulnessMode)
whenever(statusBarStateController.state).thenReturn(StatusBarState.KEYGUARD)
whenever(statusBarKeyguardViewManager.shouldDismissOnMenuPressed()).thenReturn(true)
- val actionUpMenuKeyEvent = KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MENU)
- assertThat(underTest.dispatchKeyEvent(actionUpMenuKeyEvent)).isFalse()
- verify(shadeController, never()).animateCollapseShadeForced()
+ verifyActionsDoNothing(KeyEvent.KEYCODE_MENU)
}
@Test
- fun dispatchKeyEvent_spaceActionUp_interactiveKeyguard_collapsesShade() {
+ fun dispatchKeyEvent_spaceActionUp_interactiveKeyguard_showsPrimaryBouncer() {
keyguardInteractorWithDependencies.repository.setWakefulnessModel(awakeWakefulnessMode)
whenever(statusBarStateController.state).thenReturn(StatusBarState.KEYGUARD)
- // action down: does NOT collapse the shade
- val actionDownMenuKeyEvent = KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_SPACE)
- assertThat(underTest.dispatchKeyEvent(actionDownMenuKeyEvent)).isFalse()
- verify(shadeController, never()).animateCollapseShadeForced()
+ verifyActionUpShowsPrimaryBouncer(KeyEvent.KEYCODE_SPACE)
+ }
- // action up: collapses the shade
- val actionUpMenuKeyEvent = KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_SPACE)
- assertThat(underTest.dispatchKeyEvent(actionUpMenuKeyEvent)).isTrue()
- verify(shadeController).animateCollapseShadeForced()
+ @Test
+ fun dispatchKeyEvent_spaceActionUp_shadeLocked_collapsesShade() {
+ keyguardInteractorWithDependencies.repository.setWakefulnessModel(awakeWakefulnessMode)
+ whenever(statusBarStateController.state).thenReturn(StatusBarState.SHADE_LOCKED)
+
+ verifyActionUpCollapsesTheShade(KeyEvent.KEYCODE_SPACE)
+ }
+
+ @Test
+ fun dispatchKeyEvent_enterActionUp_interactiveKeyguard_showsPrimaryBouncer() {
+ keyguardInteractorWithDependencies.repository.setWakefulnessModel(awakeWakefulnessMode)
+ whenever(statusBarStateController.state).thenReturn(StatusBarState.KEYGUARD)
+
+ verifyActionUpShowsPrimaryBouncer(KeyEvent.KEYCODE_ENTER)
+ }
+
+ @Test
+ fun dispatchKeyEvent_enterActionUp_shadeLocked_collapsesShade() {
+ keyguardInteractorWithDependencies.repository.setWakefulnessModel(awakeWakefulnessMode)
+ whenever(statusBarStateController.state).thenReturn(StatusBarState.SHADE_LOCKED)
+
+ verifyActionUpCollapsesTheShade(KeyEvent.KEYCODE_ENTER)
}
@Test
@@ -252,4 +256,42 @@
.isFalse()
verify(statusBarKeyguardViewManager, never()).interceptMediaKey(any())
}
+
+ private fun verifyActionUpCollapsesTheShade(keycode: Int) {
+ // action down: does NOT collapse the shade
+ val actionDownMenuKeyEvent = KeyEvent(KeyEvent.ACTION_DOWN, keycode)
+ assertThat(underTest.dispatchKeyEvent(actionDownMenuKeyEvent)).isFalse()
+ verify(shadeController, never()).animateCollapseShadeForced()
+
+ // action up: collapses the shade
+ val actionUpMenuKeyEvent = KeyEvent(KeyEvent.ACTION_UP, keycode)
+ assertThat(underTest.dispatchKeyEvent(actionUpMenuKeyEvent)).isTrue()
+ verify(shadeController).animateCollapseShadeForced()
+ }
+
+ private fun verifyActionUpShowsPrimaryBouncer(keycode: Int) {
+ // action down: does NOT collapse the shade
+ val actionDownMenuKeyEvent = KeyEvent(KeyEvent.ACTION_DOWN, keycode)
+ assertThat(underTest.dispatchKeyEvent(actionDownMenuKeyEvent)).isFalse()
+ verify(statusBarKeyguardViewManager, never()).showPrimaryBouncer(any())
+
+ // action up: collapses the shade
+ val actionUpMenuKeyEvent = KeyEvent(KeyEvent.ACTION_UP, keycode)
+ assertThat(underTest.dispatchKeyEvent(actionUpMenuKeyEvent)).isTrue()
+ verify(statusBarKeyguardViewManager).showPrimaryBouncer(eq(true))
+ }
+
+ private fun verifyActionsDoNothing(keycode: Int) {
+ // action down: does nothing
+ val actionDownMenuKeyEvent = KeyEvent(KeyEvent.ACTION_DOWN, keycode)
+ assertThat(underTest.dispatchKeyEvent(actionDownMenuKeyEvent)).isFalse()
+ verify(shadeController, never()).animateCollapseShadeForced()
+ verify(statusBarKeyguardViewManager, never()).showPrimaryBouncer(any())
+
+ // action up: doesNothing
+ val actionUpMenuKeyEvent = KeyEvent(KeyEvent.ACTION_UP, keycode)
+ assertThat(underTest.dispatchKeyEvent(actionUpMenuKeyEvent)).isFalse()
+ verify(shadeController, never()).animateCollapseShadeForced()
+ verify(statusBarKeyguardViewManager, never()).showPrimaryBouncer(any())
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
index eb4ae1a..7aeafeb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
@@ -539,6 +539,23 @@
}
@Test
+ public void onKeyguardStatusViewHeightChange_animatesNextTopPaddingChangeForNSSL() {
+ ArgumentCaptor<View.OnLayoutChangeListener> captor =
+ ArgumentCaptor.forClass(View.OnLayoutChangeListener.class);
+ verify(mKeyguardStatusView).addOnLayoutChangeListener(captor.capture());
+ View.OnLayoutChangeListener listener = captor.getValue();
+
+ clearInvocations(mNotificationStackScrollLayoutController);
+
+ when(mKeyguardStatusView.getHeight()).thenReturn(0);
+ listener.onLayoutChange(mKeyguardStatusView, /* left= */ 0, /* top= */ 0, /* right= */
+ 0, /* bottom= */ 0, /* oldLeft= */ 0, /* oldTop= */ 0, /* oldRight= */
+ 0, /* oldBottom = */ 200);
+
+ verify(mNotificationStackScrollLayoutController).animateNextTopPaddingChange();
+ }
+
+ @Test
public void testCanCollapsePanelOnTouch_trueForKeyGuard() {
mStatusBarStateController.setState(KEYGUARD);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
index 1edeeff..3cce423 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
@@ -18,6 +18,7 @@
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
+import android.view.KeyEvent
import android.view.MotionEvent
import android.view.ViewGroup
import androidx.test.filters.SmallTest
@@ -38,6 +39,7 @@
import com.android.systemui.dump.logcatLogBuffer
import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags
+import com.android.systemui.keyevent.domain.interactor.KeyEventInteractor
import com.android.systemui.keyguard.KeyguardUnlockAnimationController
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
import com.android.systemui.keyguard.shared.model.TransitionStep
@@ -118,8 +120,10 @@
@Mock lateinit var keyguardTransitionInteractor: KeyguardTransitionInteractor
@Mock
lateinit var primaryBouncerToGoneTransitionViewModel: PrimaryBouncerToGoneTransitionViewModel
+ @Mock lateinit var keyEventInteractor: KeyEventInteractor
private val notificationExpansionRepository = NotificationExpansionRepository()
+ private lateinit var fakeClock: FakeSystemClock
private lateinit var interactionEventHandlerCaptor: ArgumentCaptor<InteractionEventHandler>
private lateinit var interactionEventHandler: InteractionEventHandler
@@ -148,6 +152,7 @@
featureFlags.set(Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLED, false)
testScope = TestScope()
+ fakeClock = FakeSystemClock()
underTest =
NotificationShadeWindowViewController(
lockscreenShadeTransitionController,
@@ -180,7 +185,7 @@
primaryBouncerToGoneTransitionViewModel,
notificationExpansionRepository,
featureFlags,
- FakeSystemClock(),
+ fakeClock,
BouncerMessageInteractor(
FakeBouncerMessageRepository(),
mock(BouncerMessageFactory::class.java),
@@ -188,7 +193,8 @@
CountDownTimerUtil(),
featureFlags
),
- BouncerLogger(logcatLogBuffer("BouncerLog"))
+ BouncerLogger(logcatLogBuffer("BouncerLog")),
+ keyEventInteractor,
)
underTest.setupExpandedStatusBar()
@@ -328,6 +334,33 @@
}
@Test
+ fun handleDispatchTouchEvent_launchAnimationRunningTimesOut() =
+ testScope.runTest {
+ // GIVEN touch dispatcher in a state that returns true
+ underTest.setStatusBarViewController(phoneStatusBarViewController)
+ whenever(keyguardUnlockAnimationController.isPlayingCannedUnlockAnimation()).thenReturn(
+ true
+ )
+ assertThat(interactionEventHandler.handleDispatchTouchEvent(DOWN_EVENT)).isTrue()
+
+ // WHEN launch animation is running for 2 seconds
+ fakeClock.setUptimeMillis(10000)
+ underTest.setExpandAnimationRunning(true)
+ fakeClock.advanceTime(2000)
+
+ // THEN touch is ignored
+ assertThat(interactionEventHandler.handleDispatchTouchEvent(DOWN_EVENT)).isFalse()
+
+ // WHEN Launch animation is running for 6 seconds
+ fakeClock.advanceTime(4000)
+
+ // THEN move is ignored, down is handled, and window is notified
+ assertThat(interactionEventHandler.handleDispatchTouchEvent(MOVE_EVENT)).isFalse()
+ assertThat(interactionEventHandler.handleDispatchTouchEvent(DOWN_EVENT)).isTrue()
+ verify(notificationShadeWindowController).setLaunchingActivity(false)
+ }
+
+ @Test
fun shouldInterceptTouchEvent_statusBarKeyguardViewManagerShouldIntercept() {
// down event should be intercepted by keyguardViewManager
whenever(statusBarKeyguardViewManager.shouldInterceptTouchEvent(DOWN_EVENT))
@@ -345,8 +378,30 @@
verify(view).findViewById<ViewGroup>(R.id.keyguard_message_area)
}
+ @Test
+ fun forwardsDispatchKeyEvent() {
+ val keyEvent = KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_B)
+ interactionEventHandler.dispatchKeyEvent(keyEvent)
+ verify(keyEventInteractor).dispatchKeyEvent(keyEvent)
+ }
+
+ @Test
+ fun forwardsDispatchKeyEventPreIme() {
+ val keyEvent = KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_B)
+ interactionEventHandler.dispatchKeyEventPreIme(keyEvent)
+ verify(keyEventInteractor).dispatchKeyEventPreIme(keyEvent)
+ }
+
+ @Test
+ fun forwardsInterceptMediaKey() {
+ val keyEvent = KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_VOLUME_UP)
+ interactionEventHandler.interceptMediaKey(keyEvent)
+ verify(keyEventInteractor).interceptMediaKey(keyEvent)
+ }
+
companion object {
private val DOWN_EVENT = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 0f, 0)
+ private val MOVE_EVENT = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_MOVE, 0f, 0f, 0)
private const val VIEW_BOTTOM = 100
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt
index 829184c..66d48d6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt
@@ -38,6 +38,7 @@
import com.android.systemui.dump.logcatLogBuffer
import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags
+import com.android.systemui.keyevent.domain.interactor.KeyEventInteractor
import com.android.systemui.keyguard.KeyguardUnlockAnimationController
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToGoneTransitionViewModel
@@ -198,7 +199,8 @@
CountDownTimerUtil(),
featureFlags
),
- BouncerLogger(logcatLogBuffer("BouncerLog"))
+ BouncerLogger(logcatLogBuffer("BouncerLog")),
+ Mockito.mock(KeyEventInteractor::class.java),
)
controller.setupExpandedStatusBar()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/carrier/ShadeCarrierGroupControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/carrier/ShadeCarrierGroupControllerTest.java
index 31bfa3fd..5fa6b3a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/carrier/ShadeCarrierGroupControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/carrier/ShadeCarrierGroupControllerTest.java
@@ -29,6 +29,7 @@
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
@@ -50,6 +51,12 @@
import com.android.systemui.statusbar.connectivity.MobileDataIndicators;
import com.android.systemui.statusbar.connectivity.NetworkController;
import com.android.systemui.statusbar.connectivity.SignalCallback;
+import com.android.systemui.statusbar.connectivity.ui.MobileContextProvider;
+import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags;
+import com.android.systemui.statusbar.pipeline.mobile.ui.MobileUiAdapter;
+import com.android.systemui.statusbar.pipeline.mobile.ui.MobileViewLogger;
+import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.MobileIconsViewModel;
+import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.ShadeCarrierGroupMobileIconViewModel;
import com.android.systemui.util.CarrierConfigTracker;
import com.android.systemui.utils.leaks.LeakCheckedTest;
import com.android.systemui.utils.os.FakeHandler;
@@ -61,6 +68,10 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
@SmallTest
@@ -95,6 +106,18 @@
private TestableLooper mTestableLooper;
@Mock
private ShadeCarrierGroupController.OnSingleCarrierChangedListener mOnSingleCarrierChangedListener;
+ @Mock
+ private MobileUiAdapter mMobileUiAdapter;
+ @Mock
+ private MobileIconsViewModel mMobileIconsViewModel;
+ @Mock
+ private ShadeCarrierGroupMobileIconViewModel mShadeCarrierGroupMobileIconViewModel;
+ @Mock
+ private MobileViewLogger mMobileViewLogger;
+ @Mock
+ private MobileContextProvider mMobileContextProvider;
+ @Mock
+ private StatusBarPipelineFlags mStatusBarPipelineFlags;
private FakeSlotIndexResolver mSlotIndexResolver;
private ClickListenerTextView mNoCarrierTextView;
@@ -133,16 +156,35 @@
mSlotIndexResolver = new FakeSlotIndexResolver();
+ when(mMobileUiAdapter.getMobileIconsViewModel()).thenReturn(mMobileIconsViewModel);
+
mShadeCarrierGroupController = new ShadeCarrierGroupController.Builder(
- mActivityStarter, handler, TestableLooper.get(this).getLooper(),
- mNetworkController, mCarrierTextControllerBuilder, mContext, mCarrierConfigTracker,
- mSlotIndexResolver)
+ mActivityStarter,
+ handler,
+ TestableLooper.get(this).getLooper(),
+ mNetworkController,
+ mCarrierTextControllerBuilder,
+ mContext,
+ mCarrierConfigTracker,
+ mSlotIndexResolver,
+ mMobileUiAdapter,
+ mMobileContextProvider,
+ mStatusBarPipelineFlags
+ )
.setShadeCarrierGroup(mShadeCarrierGroup)
.build();
mShadeCarrierGroupController.setListening(true);
}
+ private void setupWithNewPipeline() {
+ when(mStatusBarPipelineFlags.useNewShadeCarrierGroupMobileIcons()).thenReturn(true);
+ when(mMobileContextProvider.getMobileContextForSub(anyInt(), any())).thenReturn(mContext);
+ when(mMobileIconsViewModel.getLogger()).thenReturn(mMobileViewLogger);
+ when(mMobileIconsViewModel.viewModelForSub(anyInt(), any()))
+ .thenReturn(mShadeCarrierGroupMobileIconViewModel);
+ }
+
@Test
public void testInitiallyMultiCarrier() {
assertFalse(mShadeCarrierGroupController.isSingleCarrier());
@@ -406,6 +448,129 @@
verify(mOnSingleCarrierChangedListener, never()).onSingleCarrierChanged(anyBoolean());
}
+ @TestableLooper.RunWithLooper(setAsMainLooper = true)
+ @Test
+ public void testUpdateModernMobileIcons_addSubscription() {
+ setupWithNewPipeline();
+
+ mShadeCarrier1.setVisibility(View.GONE);
+ mShadeCarrier2.setVisibility(View.GONE);
+ mShadeCarrier3.setVisibility(View.GONE);
+
+ List<Integer> subIds = new ArrayList<>();
+ subIds.add(0);
+ mShadeCarrierGroupController.updateModernMobileIcons(subIds);
+
+ verify(mShadeCarrier1).addModernMobileView(any());
+ verify(mShadeCarrier2, never()).addModernMobileView(any());
+ verify(mShadeCarrier3, never()).addModernMobileView(any());
+
+ resetShadeCarriers();
+
+ subIds.add(1);
+ mShadeCarrierGroupController.updateModernMobileIcons(subIds);
+
+ verify(mShadeCarrier1, times(1)).removeModernMobileView();
+
+ verify(mShadeCarrier1).addModernMobileView(any());
+ verify(mShadeCarrier2).addModernMobileView(any());
+ verify(mShadeCarrier3, never()).addModernMobileView(any());
+ }
+
+ @TestableLooper.RunWithLooper(setAsMainLooper = true)
+ @Test
+ public void testUpdateModernMobileIcons_removeSubscription() {
+ setupWithNewPipeline();
+
+ List<Integer> subIds = new ArrayList<>();
+ subIds.add(0);
+ subIds.add(1);
+ mShadeCarrierGroupController.updateModernMobileIcons(subIds);
+
+ verify(mShadeCarrier1).addModernMobileView(any());
+ verify(mShadeCarrier2).addModernMobileView(any());
+ verify(mShadeCarrier3, never()).addModernMobileView(any());
+
+ resetShadeCarriers();
+
+ subIds.remove(1);
+ mShadeCarrierGroupController.updateModernMobileIcons(subIds);
+
+ verify(mShadeCarrier1, times(1)).removeModernMobileView();
+ verify(mShadeCarrier2, times(1)).removeModernMobileView();
+
+ verify(mShadeCarrier1).addModernMobileView(any());
+ verify(mShadeCarrier2, never()).addModernMobileView(any());
+ verify(mShadeCarrier3, never()).addModernMobileView(any());
+ }
+
+ @TestableLooper.RunWithLooper(setAsMainLooper = true)
+ @Test
+ public void testUpdateModernMobileIcons_removeSubscriptionOutOfOrder() {
+ setupWithNewPipeline();
+
+ List<Integer> subIds = new ArrayList<>();
+ subIds.add(0);
+ subIds.add(1);
+ subIds.add(2);
+ mShadeCarrierGroupController.updateModernMobileIcons(subIds);
+
+ verify(mShadeCarrier1).addModernMobileView(any());
+ verify(mShadeCarrier2).addModernMobileView(any());
+ verify(mShadeCarrier3).addModernMobileView(any());
+
+ resetShadeCarriers();
+
+ subIds.remove(1);
+ mShadeCarrierGroupController.updateModernMobileIcons(subIds);
+
+ verify(mShadeCarrier1).removeModernMobileView();
+ verify(mShadeCarrier2).removeModernMobileView();
+ verify(mShadeCarrier3).removeModernMobileView();
+
+ verify(mShadeCarrier1).addModernMobileView(any());
+ verify(mShadeCarrier2, never()).addModernMobileView(any());
+ verify(mShadeCarrier3).addModernMobileView(any());
+ }
+
+ @TestableLooper.RunWithLooper(setAsMainLooper = true)
+ @Test
+ public void testProcessSubIdList_moreSubsThanSimSlots_listLimitedToMax() {
+ setupWithNewPipeline();
+
+ List<Integer> subIds = Arrays.asList(0, 1, 2, 2);
+
+ assertThat(mShadeCarrierGroupController.processSubIdList(subIds).size()).isEqualTo(3);
+ }
+
+ @TestableLooper.RunWithLooper(setAsMainLooper = true)
+ @Test
+ public void testProcessSubIdList_invalidSimSlotIndexFilteredOut() {
+ setupWithNewPipeline();
+
+ List<Integer> subIds = Arrays.asList(0, 1, -1);
+
+ List<ShadeCarrierGroupController.IconData> processedSubs =
+ mShadeCarrierGroupController.processSubIdList(subIds);
+ assertThat(processedSubs).hasSize(2);
+ assertThat(processedSubs.get(0).subId).isNotEqualTo(-1);
+ assertThat(processedSubs.get(1).subId).isNotEqualTo(-1);
+ }
+
+ @TestableLooper.RunWithLooper(setAsMainLooper = true)
+ @Test
+ public void testProcessSubIdList_indexGreaterThanSimSlotsFilteredOut() {
+ setupWithNewPipeline();
+
+ List<Integer> subIds = Arrays.asList(0, 4);
+
+ List<ShadeCarrierGroupController.IconData> processedSubs =
+ mShadeCarrierGroupController.processSubIdList(subIds);
+ assertThat(processedSubs).hasSize(1);
+ assertThat(processedSubs.get(0).subId).isNotEqualTo(4);
+ }
+
+
@Test
public void testOnlyInternalViewsHaveClickableListener() {
ArgumentCaptor<View.OnClickListener> captor =
@@ -447,6 +612,12 @@
.isEqualTo(Settings.ACTION_WIRELESS_SETTINGS);
}
+ private void resetShadeCarriers() {
+ reset(mShadeCarrier1);
+ reset(mShadeCarrier2);
+ reset(mShadeCarrier3);
+ }
+
private class FakeSlotIndexResolver implements ShadeCarrierGroupController.SlotIndexResolver {
public boolean overrideInvalid;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt
index 9495fdd..ecaf137 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt
@@ -227,6 +227,25 @@
}
@Test
+ fun activeClockId_changeAfterPluginConnected() {
+ val plugin1 = FakeClockPlugin()
+ .addClock("clock_1", "clock 1")
+ .addClock("clock_2", "clock 2")
+
+ val plugin2 = FakeClockPlugin()
+ .addClock("clock_3", "clock 3", { mockClock })
+ .addClock("clock_4", "clock 4")
+
+ registry.applySettings(ClockSettings("clock_3", null))
+
+ pluginListener.onPluginLoaded(plugin1, mockContext, mockPluginLifecycle)
+ assertEquals(DEFAULT_CLOCK_ID, registry.activeClockId)
+
+ pluginListener.onPluginLoaded(plugin2, mockContext, mockPluginLifecycle)
+ assertEquals("clock_3", registry.activeClockId)
+ }
+
+ @Test
fun createDefaultClock_pluginDisconnected() {
val plugin1 = FakeClockPlugin()
.addClock("clock_1", "clock 1")
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconAreaControllerViewBinderWrapperImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconAreaControllerViewBinderWrapperImplTest.kt
new file mode 100644
index 0000000..b8792a8
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconAreaControllerViewBinderWrapperImplTest.kt
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2023 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.statusbar.notification.icon.ui.viewbinder
+
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper.RunWithLooper
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.demomode.DemoModeController
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.plugins.DarkIconDispatcher
+import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.statusbar.NotificationListener
+import com.android.systemui.statusbar.NotificationMediaManager
+import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator
+import com.android.systemui.statusbar.notification.collection.provider.SectionStyleProvider
+import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerAlwaysOnDisplayViewModel
+import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerShelfViewModel
+import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerStatusBarViewModel
+import com.android.systemui.statusbar.phone.DozeParameters
+import com.android.systemui.statusbar.phone.KeyguardBypassController
+import com.android.systemui.statusbar.phone.NotificationIconContainer
+import com.android.systemui.statusbar.phone.ScreenOffAnimationController
+import com.android.systemui.statusbar.window.StatusBarWindowController
+import com.android.systemui.util.mockito.whenever
+import com.android.wm.shell.bubbles.Bubbles
+import java.util.Optional
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertTrue
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@RunWithLooper(setAsMainLooper = true)
+class NotificationIconAreaControllerViewBinderWrapperImplTest : SysuiTestCase() {
+ @Mock private lateinit var notifListener: NotificationListener
+ @Mock private lateinit var statusBarStateController: StatusBarStateController
+ @Mock private lateinit var wakeUpCoordinator: NotificationWakeUpCoordinator
+ @Mock private lateinit var keyguardBypassController: KeyguardBypassController
+ @Mock private lateinit var notifMediaManager: NotificationMediaManager
+ @Mock private lateinit var dozeParams: DozeParameters
+ @Mock private lateinit var sectionStyleProvider: SectionStyleProvider
+ @Mock private lateinit var darkIconDispatcher: DarkIconDispatcher
+ @Mock private lateinit var statusBarWindowController: StatusBarWindowController
+ @Mock private lateinit var screenOffAnimController: ScreenOffAnimationController
+ @Mock private lateinit var bubbles: Bubbles
+ @Mock private lateinit var demoModeController: DemoModeController
+ @Mock private lateinit var aodIcons: NotificationIconContainer
+ @Mock private lateinit var featureFlags: FeatureFlags
+
+ private val shelfViewModel = NotificationIconContainerShelfViewModel()
+ private val statusBarViewModel = NotificationIconContainerStatusBarViewModel()
+ private val aodViewModel = NotificationIconContainerAlwaysOnDisplayViewModel()
+
+ private lateinit var underTest: NotificationIconAreaControllerViewBinderWrapperImpl
+
+ @Before
+ fun setup() {
+ MockitoAnnotations.initMocks(this)
+ underTest =
+ NotificationIconAreaControllerViewBinderWrapperImpl(
+ mContext,
+ statusBarStateController,
+ wakeUpCoordinator,
+ keyguardBypassController,
+ notifMediaManager,
+ notifListener,
+ dozeParams,
+ sectionStyleProvider,
+ Optional.of(bubbles),
+ demoModeController,
+ darkIconDispatcher,
+ featureFlags,
+ statusBarWindowController,
+ screenOffAnimController,
+ shelfViewModel,
+ statusBarViewModel,
+ aodViewModel,
+ )
+ }
+
+ @Test
+ fun testNotificationIcons_settingHideIcons() {
+ underTest.settingsListener.onStatusBarIconsBehaviorChanged(true)
+ assertFalse(underTest.shouldShowLowPriorityIcons())
+ }
+
+ @Test
+ fun testNotificationIcons_settingShowIcons() {
+ underTest.settingsListener.onStatusBarIconsBehaviorChanged(false)
+ assertTrue(underTest.shouldShowLowPriorityIcons())
+ }
+
+ @Test
+ fun testAppearResetsTranslation() {
+ underTest.setupAodIcons(aodIcons)
+ whenever(dozeParams.shouldControlScreenOff()).thenReturn(false)
+ underTest.appearAodIcons()
+ verify(aodIcons).translationY = 0f
+ verify(aodIcons).alpha = 1.0f
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconAreaControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LegacyNotificationIconAreaControllerImplTest.java
similarity index 94%
rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconAreaControllerTest.java
rename to packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LegacyNotificationIconAreaControllerImplTest.java
index 8e1dcf0..1b8cfd4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconAreaControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LegacyNotificationIconAreaControllerImplTest.java
@@ -48,7 +48,7 @@
@SmallTest
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
-public class NotificationIconAreaControllerTest extends SysuiTestCase {
+public class LegacyNotificationIconAreaControllerImplTest extends SysuiTestCase {
@Mock
private NotificationListener mListener;
@@ -70,7 +70,7 @@
StatusBarWindowController mStatusBarWindowController;
@Mock
ScreenOffAnimationController mScreenOffAnimationController;
- private NotificationIconAreaController mController;
+ private LegacyNotificationIconAreaControllerImpl mController;
@Mock
private Bubbles mBubbles;
@Mock private DemoModeController mDemoModeController;
@@ -82,7 +82,7 @@
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
- mController = new NotificationIconAreaController(
+ mController = new LegacyNotificationIconAreaControllerImpl(
mContext,
mStatusBarStateController,
mWakeUpCoordinator,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
index 0dc1d9a..6b3bd22 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
@@ -1802,6 +1802,15 @@
assertFalse(ScrimState.UNLOCKED.mAnimateChange);
}
+ @Test
+ public void testNotifScrimAlpha_1f_afterUnlockFinishedAndExpanded() {
+ mScrimController.transitionTo(ScrimState.KEYGUARD);
+ when(mKeyguardUnlockAnimationController.isPlayingCannedUnlockAnimation()).thenReturn(true);
+ mScrimController.transitionTo(ScrimState.UNLOCKED);
+ mScrimController.onUnlockAnimationFinished();
+ assertAlphaAfterExpansion(mNotificationsScrim, 1f, 1f);
+ }
+
private void assertAlphaAfterExpansion(ScrimView scrim, float expectedAlpha, float expansion) {
mScrimController.setRawPanelExpansionFraction(expansion);
finishAnimationsImmediately();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionRepository.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionRepository.kt
index 50ee6a3..ff28753 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionRepository.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionRepository.kt
@@ -52,12 +52,19 @@
override val cdmaRoaming = MutableStateFlow(false)
- override val networkName =
- MutableStateFlow<NetworkNameModel>(NetworkNameModel.Default("default"))
+ override val networkName: MutableStateFlow<NetworkNameModel> =
+ MutableStateFlow(NetworkNameModel.Default(DEFAULT_NETWORK_NAME))
+
+ override val carrierName: MutableStateFlow<NetworkNameModel> =
+ MutableStateFlow(NetworkNameModel.Default(DEFAULT_NETWORK_NAME))
override val isAllowedDuringAirplaneMode = MutableStateFlow(false)
fun setDataEnabled(enabled: Boolean) {
_dataEnabled.value = enabled
}
+
+ companion object {
+ const val DEFAULT_NETWORK_NAME = "default name"
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionsRepository.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionsRepository.kt
index 3591c17..99e4030 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionsRepository.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionsRepository.kt
@@ -75,7 +75,11 @@
override fun getRepoForSubId(subId: Int): MobileConnectionRepository {
return subIdRepos[subId]
- ?: FakeMobileConnectionRepository(subId, tableLogBuffer).also { subIdRepos[subId] = it }
+ ?: FakeMobileConnectionRepository(
+ subId,
+ tableLogBuffer,
+ )
+ .also { subIdRepos[subId] = it }
}
override val defaultDataSubRatConfig = MutableStateFlow(MobileMappings.Config())
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherTest.kt
index 5a887eb..d005972 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherTest.kt
@@ -243,13 +243,29 @@
private val IMMEDIATE = Dispatchers.Main.immediate
private const val SUB_1_ID = 1
+ private const val SUB_1_NAME = "Carrier $SUB_1_ID"
private val SUB_1 =
- mock<SubscriptionInfo>().also { whenever(it.subscriptionId).thenReturn(SUB_1_ID) }
- private val MODEL_1 = SubscriptionModel(subscriptionId = SUB_1_ID)
+ mock<SubscriptionInfo>().also {
+ whenever(it.subscriptionId).thenReturn(SUB_1_ID)
+ whenever(it.carrierName).thenReturn(SUB_1_NAME)
+ }
+ private val MODEL_1 =
+ SubscriptionModel(
+ subscriptionId = SUB_1_ID,
+ carrierName = SUB_1_NAME,
+ )
private const val SUB_2_ID = 2
+ private const val SUB_2_NAME = "Carrier $SUB_2_ID"
private val SUB_2 =
- mock<SubscriptionInfo>().also { whenever(it.subscriptionId).thenReturn(SUB_2_ID) }
- private val MODEL_2 = SubscriptionModel(subscriptionId = SUB_2_ID)
+ mock<SubscriptionInfo>().also {
+ whenever(it.subscriptionId).thenReturn(SUB_2_ID)
+ whenever(it.carrierName).thenReturn(SUB_2_NAME)
+ }
+ private val MODEL_2 =
+ SubscriptionModel(
+ subscriptionId = SUB_2_ID,
+ carrierName = SUB_2_NAME,
+ )
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionParameterizedTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionParameterizedTest.kt
index 7573b28..57f97ec 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionParameterizedTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionParameterizedTest.kt
@@ -38,7 +38,6 @@
import kotlinx.coroutines.Job
import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.UnconfinedTestDispatcher
@@ -140,6 +139,7 @@
launch { conn.carrierNetworkChangeActive.collect {} }
launch { conn.isRoaming.collect {} }
launch { conn.networkName.collect {} }
+ launch { conn.carrierName.collect {} }
launch { conn.isEmergencyOnly.collect {} }
launch { conn.dataConnectionState.collect {} }
}
@@ -163,6 +163,8 @@
assertThat(conn.isRoaming.value).isEqualTo(model.roaming)
assertThat(conn.networkName.value)
.isEqualTo(NetworkNameModel.IntentDerived(model.name))
+ assertThat(conn.carrierName.value)
+ .isEqualTo(NetworkNameModel.SubscriptionDerived("${model.name} ${model.subId}"))
// TODO(b/261029387): check these once we start handling them
assertThat(conn.isEmergencyOnly.value).isFalse()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepositoryTest.kt
index efaf152..2712b70 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepositoryTest.kt
@@ -546,6 +546,7 @@
launch { conn.carrierNetworkChangeActive.collect {} }
launch { conn.isRoaming.collect {} }
launch { conn.networkName.collect {} }
+ launch { conn.carrierName.collect {} }
launch { conn.isEmergencyOnly.collect {} }
launch { conn.dataConnectionState.collect {} }
}
@@ -571,6 +572,8 @@
assertThat(conn.isRoaming.value).isEqualTo(model.roaming)
assertThat(conn.networkName.value)
.isEqualTo(NetworkNameModel.IntentDerived(model.name))
+ assertThat(conn.carrierName.value)
+ .isEqualTo(NetworkNameModel.SubscriptionDerived("${model.name} ${model.subId}"))
// TODO(b/261029387) check these once we start handling them
assertThat(conn.isEmergencyOnly.value).isFalse()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryTest.kt
index 3dd2eaf..9c0cb17 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryTest.kt
@@ -26,6 +26,7 @@
import com.android.systemui.log.table.TableLogBuffer
import com.android.systemui.log.table.TableLogBufferFactory
import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
+import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionRepository
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository
import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepository.Companion.COL_EMERGENCY
@@ -43,6 +44,7 @@
import java.io.PrintWriter
import java.io.StringWriter
import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.test.TestScope
@@ -79,28 +81,51 @@
private val mobileFactory = mock<MobileConnectionRepositoryImpl.Factory>()
private val carrierMergedFactory = mock<CarrierMergedConnectionRepository.Factory>()
+ private val subscriptionModel =
+ MutableStateFlow(
+ SubscriptionModel(
+ subscriptionId = SUB_ID,
+ carrierName = DEFAULT_NAME,
+ )
+ )
+
private lateinit var mobileRepo: FakeMobileConnectionRepository
private lateinit var carrierMergedRepo: FakeMobileConnectionRepository
@Before
fun setUp() {
- mobileRepo = FakeMobileConnectionRepository(SUB_ID, tableLogBuffer)
+ mobileRepo =
+ FakeMobileConnectionRepository(
+ SUB_ID,
+ tableLogBuffer,
+ )
carrierMergedRepo =
- FakeMobileConnectionRepository(SUB_ID, tableLogBuffer).apply {
- // Mimicks the real carrier merged repository
- this.isAllowedDuringAirplaneMode.value = true
- }
+ FakeMobileConnectionRepository(
+ SUB_ID,
+ tableLogBuffer,
+ )
+ .apply {
+ // Mimicks the real carrier merged repository
+ this.isAllowedDuringAirplaneMode.value = true
+ }
whenever(
mobileFactory.build(
eq(SUB_ID),
any(),
- eq(DEFAULT_NAME),
+ any(),
+ eq(DEFAULT_NAME_MODEL),
eq(SEP),
)
)
.thenReturn(mobileRepo)
- whenever(carrierMergedFactory.build(eq(SUB_ID), any())).thenReturn(carrierMergedRepo)
+ whenever(
+ carrierMergedFactory.build(
+ eq(SUB_ID),
+ any(),
+ )
+ )
+ .thenReturn(carrierMergedRepo)
}
@Test
@@ -120,7 +145,8 @@
.build(
SUB_ID,
tableLogBuffer,
- DEFAULT_NAME,
+ subscriptionModel,
+ DEFAULT_NAME_MODEL,
SEP,
)
}
@@ -138,7 +164,11 @@
assertThat(underTest.activeRepo.value).isEqualTo(mobileRepo)
assertThat(underTest.operatorAlphaShort.value).isEqualTo(nonCarrierMergedName)
- verify(carrierMergedFactory, never()).build(SUB_ID, tableLogBuffer)
+ verify(carrierMergedFactory, never())
+ .build(
+ SUB_ID,
+ tableLogBuffer,
+ )
}
@Test
@@ -348,7 +378,8 @@
factory.build(
SUB_ID,
startingIsCarrierMerged = false,
- DEFAULT_NAME,
+ subscriptionModel,
+ DEFAULT_NAME_MODEL,
SEP,
)
@@ -356,7 +387,8 @@
factory.build(
SUB_ID,
startingIsCarrierMerged = false,
- DEFAULT_NAME,
+ subscriptionModel,
+ DEFAULT_NAME_MODEL,
SEP,
)
@@ -388,7 +420,8 @@
factory.build(
SUB_ID,
startingIsCarrierMerged = false,
- DEFAULT_NAME,
+ subscriptionModel,
+ DEFAULT_NAME_MODEL,
SEP,
)
@@ -397,7 +430,8 @@
factory.build(
SUB_ID,
startingIsCarrierMerged = true,
- DEFAULT_NAME,
+ subscriptionModel,
+ DEFAULT_NAME_MODEL,
SEP,
)
@@ -623,7 +657,8 @@
SUB_ID,
startingIsCarrierMerged,
tableLogBuffer,
- DEFAULT_NAME,
+ subscriptionModel,
+ DEFAULT_NAME_MODEL,
SEP,
testScope.backgroundScope,
mobileFactory,
@@ -639,8 +674,9 @@
val realRepo =
MobileConnectionRepositoryImpl(
SUB_ID,
- defaultNetworkName = NetworkNameModel.Default("default"),
- networkNameSeparator = SEP,
+ subscriptionModel,
+ DEFAULT_NAME_MODEL,
+ SEP,
telephonyManager,
systemUiCarrierConfig = mock(),
fakeBroadcastDispatcher,
@@ -654,7 +690,8 @@
mobileFactory.build(
eq(SUB_ID),
any(),
- eq(DEFAULT_NAME),
+ any(),
+ eq(DEFAULT_NAME_MODEL),
eq(SEP),
)
)
@@ -677,7 +714,13 @@
testScope.backgroundScope,
wifiRepository,
)
- whenever(carrierMergedFactory.build(eq(SUB_ID), any())).thenReturn(realRepo)
+ whenever(
+ carrierMergedFactory.build(
+ eq(SUB_ID),
+ any(),
+ )
+ )
+ .thenReturn(realRepo)
return realRepo
}
@@ -690,7 +733,8 @@
private companion object {
const val SUB_ID = 42
- private val DEFAULT_NAME = NetworkNameModel.Default("default name")
+ private val DEFAULT_NAME = "default name"
+ private val DEFAULT_NAME_MODEL = NetworkNameModel.Default(DEFAULT_NAME)
private const val SEP = "-"
private const val BUFFER_SEPARATOR = "|"
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt
index 1ff737b..e50e5e3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt
@@ -62,6 +62,7 @@
import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.DefaultNetworkType
import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.OverrideNetworkType
import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.UnknownNetworkType
+import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
import com.android.systemui.statusbar.pipeline.mobile.data.model.SystemUiCarrierConfig
import com.android.systemui.statusbar.pipeline.mobile.data.model.SystemUiCarrierConfigTest.Companion.configWithOverride
import com.android.systemui.statusbar.pipeline.mobile.data.model.SystemUiCarrierConfigTest.Companion.createTestConfig
@@ -78,6 +79,7 @@
import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.test.TestScope
@@ -109,6 +111,14 @@
private val testDispatcher = UnconfinedTestDispatcher()
private val testScope = TestScope(testDispatcher)
+ private val subscriptionModel: MutableStateFlow<SubscriptionModel?> =
+ MutableStateFlow(
+ SubscriptionModel(
+ subscriptionId = SUB_1_ID,
+ carrierName = DEFAULT_NAME,
+ )
+ )
+
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
@@ -119,7 +129,8 @@
underTest =
MobileConnectionRepositoryImpl(
SUB_1_ID,
- DEFAULT_NAME,
+ subscriptionModel,
+ DEFAULT_NAME_MODEL,
SEP,
telephonyManager,
systemUiCarrierConfig,
@@ -179,6 +190,7 @@
// gsmLevel updates, no change to cdmaLevel
strength = signalStrength(gsmLevel = 3, cdmaLevel = 2, isGsm = true)
+ callback.onSignalStrengthsChanged(strength)
assertThat(latest).isEqualTo(2)
@@ -638,12 +650,51 @@
}
@Test
+ fun networkNameForSubId_updates() =
+ testScope.runTest {
+ var latest: NetworkNameModel? = null
+ val job = underTest.carrierName.onEach { latest = it }.launchIn(this)
+
+ subscriptionModel.value =
+ SubscriptionModel(
+ subscriptionId = SUB_1_ID,
+ carrierName = DEFAULT_NAME,
+ )
+
+ assertThat(latest?.name).isEqualTo(DEFAULT_NAME)
+
+ val updatedName = "Derived Carrier"
+ subscriptionModel.value =
+ SubscriptionModel(
+ subscriptionId = SUB_1_ID,
+ carrierName = updatedName,
+ )
+
+ assertThat(latest?.name).isEqualTo(updatedName)
+
+ job.cancel()
+ }
+
+ @Test
+ fun networkNameForSubId_defaultWhenSubscriptionModelNull() =
+ testScope.runTest {
+ var latest: NetworkNameModel? = null
+ val job = underTest.carrierName.onEach { latest = it }.launchIn(this)
+
+ subscriptionModel.value = null
+
+ assertThat(latest?.name).isEqualTo(DEFAULT_NAME)
+
+ job.cancel()
+ }
+
+ @Test
fun networkName_default() =
testScope.runTest {
var latest: NetworkNameModel? = null
val job = underTest.networkName.onEach { latest = it }.launchIn(this)
- assertThat(latest).isEqualTo(DEFAULT_NAME)
+ assertThat(latest).isEqualTo(DEFAULT_NAME_MODEL)
job.cancel()
}
@@ -701,7 +752,7 @@
fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(context, intentWithoutInfo)
- assertThat(latest).isEqualTo(DEFAULT_NAME)
+ assertThat(latest).isEqualTo(DEFAULT_NAME_MODEL)
job.cancel()
}
@@ -852,8 +903,9 @@
companion object {
private const val SUB_1_ID = 1
- private val DEFAULT_NAME = NetworkNameModel.Default("default name")
- private const val SEP = "-"
+ private val DEFAULT_NAME = "Fake Mobile Network"
+ private val DEFAULT_NAME_MODEL = NetworkNameModel.Default(DEFAULT_NAME)
+ private val SEP = "-"
private const val SPN = "testSpn"
private const val PLMN = "testPlmn"
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionTelephonySmokeTests.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionTelephonySmokeTests.kt
index 4f15aed..ea60aa7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionTelephonySmokeTests.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionTelephonySmokeTests.kt
@@ -36,6 +36,7 @@
import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState
import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType
+import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
import com.android.systemui.statusbar.pipeline.mobile.data.model.SystemUiCarrierConfig
import com.android.systemui.statusbar.pipeline.mobile.data.model.SystemUiCarrierConfigTest
import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionsRepository
@@ -47,6 +48,7 @@
import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.test.TestScope
@@ -97,6 +99,7 @@
@Mock private lateinit var telephonyManager: TelephonyManager
@Mock private lateinit var logger: MobileInputLogger
@Mock private lateinit var tableLogger: TableLogBuffer
+ @Mock private lateinit var subscriptionModel: StateFlow<SubscriptionModel?>
private val mobileMappings = FakeMobileMappingsProxy()
private val systemUiCarrierConfig =
@@ -113,11 +116,16 @@
MockitoAnnotations.initMocks(this)
whenever(telephonyManager.subscriptionId).thenReturn(SUB_1_ID)
- connectionsRepo = FakeMobileConnectionsRepository(mobileMappings, tableLogger)
+ connectionsRepo =
+ FakeMobileConnectionsRepository(
+ mobileMappings,
+ tableLogger,
+ )
underTest =
MobileConnectionRepositoryImpl(
SUB_1_ID,
+ subscriptionModel,
DEFAULT_NAME,
SEP,
telephonyManager,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt
index c8b6f13d..fd05cc4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt
@@ -1190,30 +1190,36 @@
companion object {
// Subscription 1
private const val SUB_1_ID = 1
+ private const val SUB_1_NAME = "Carrier $SUB_1_ID"
private val GROUP_1 = ParcelUuid(UUID.randomUUID())
private val SUB_1 =
mock<SubscriptionInfo>().also {
whenever(it.subscriptionId).thenReturn(SUB_1_ID)
whenever(it.groupUuid).thenReturn(GROUP_1)
+ whenever(it.carrierName).thenReturn(SUB_1_NAME)
}
private val MODEL_1 =
SubscriptionModel(
subscriptionId = SUB_1_ID,
groupUuid = GROUP_1,
+ carrierName = SUB_1_NAME,
)
// Subscription 2
private const val SUB_2_ID = 2
+ private const val SUB_2_NAME = "Carrier $SUB_2_ID"
private val GROUP_2 = ParcelUuid(UUID.randomUUID())
private val SUB_2 =
mock<SubscriptionInfo>().also {
whenever(it.subscriptionId).thenReturn(SUB_2_ID)
whenever(it.groupUuid).thenReturn(GROUP_2)
+ whenever(it.carrierName).thenReturn(SUB_2_NAME)
}
private val MODEL_2 =
SubscriptionModel(
subscriptionId = SUB_2_ID,
groupUuid = GROUP_2,
+ carrierName = SUB_2_NAME,
)
// Subs 3 and 4 are considered to be in the same group ------------------------------------
@@ -1242,9 +1248,14 @@
// Carrier merged subscription
private const val SUB_CM_ID = 5
+ private const val SUB_CM_NAME = "Carrier $SUB_CM_ID"
private val SUB_CM =
- mock<SubscriptionInfo>().also { whenever(it.subscriptionId).thenReturn(SUB_CM_ID) }
- private val MODEL_CM = SubscriptionModel(subscriptionId = SUB_CM_ID)
+ mock<SubscriptionInfo>().also {
+ whenever(it.subscriptionId).thenReturn(SUB_CM_ID)
+ whenever(it.carrierName).thenReturn(SUB_CM_NAME)
+ }
+ private val MODEL_CM =
+ SubscriptionModel(subscriptionId = SUB_CM_ID, carrierName = SUB_CM_NAME)
private val WIFI_INFO_CM =
mock<WifiInfo>().apply {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt
index 8d1da69..a3df785 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt
@@ -44,6 +44,8 @@
override val mobileIsDefault = MutableStateFlow(true)
+ override val isSingleCarrier = MutableStateFlow(true)
+
override val networkTypeIconGroup =
MutableStateFlow<NetworkTypeIconModel>(
NetworkTypeIconModel.DefaultIcon(TelephonyIcons.THREE_G)
@@ -51,6 +53,8 @@
override val networkName = MutableStateFlow(NetworkNameModel.IntentDerived("demo mode"))
+ override val carrierName = MutableStateFlow("demo mode")
+
private val _isEmergencyOnly = MutableStateFlow(false)
override val isEmergencyOnly = _isEmergencyOnly
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt
index b2bbcfd..82b7ec4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt
@@ -64,6 +64,8 @@
override val mobileIsDefault = MutableStateFlow(false)
+ override val isSingleCarrier = MutableStateFlow(true)
+
private val _defaultMobileIconMapping = MutableStateFlow(TEST_MAPPING)
override val defaultMobileIconMapping = _defaultMobileIconMapping
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt
index 58d3804..e3c59ad 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt
@@ -29,6 +29,7 @@
import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.CarrierMergedNetworkType
import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.DefaultNetworkType
import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.OverrideNetworkType
+import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionRepository
import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.FakeMobileIconsInteractor.Companion.FIVE_G_OVERRIDE
import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.FakeMobileIconsInteractor.Companion.FOUR_G
@@ -40,6 +41,7 @@
import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.test.TestScope
@@ -56,6 +58,15 @@
private lateinit var underTest: MobileIconInteractor
private val mobileMappingsProxy = FakeMobileMappingsProxy()
private val mobileIconsInteractor = FakeMobileIconsInteractor(mobileMappingsProxy, mock())
+
+ private val subscriptionModel =
+ MutableStateFlow(
+ SubscriptionModel(
+ subscriptionId = SUB_1_ID,
+ carrierName = DEFAULT_NAME,
+ )
+ )
+
private val connectionRepository = FakeMobileConnectionRepository(SUB_1_ID, mock())
private val testDispatcher = UnconfinedTestDispatcher()
@@ -432,7 +443,7 @@
}
@Test
- fun networkName_usesOperatorAlphaShotWhenNonNullAndRepoIsDefault() =
+ fun networkName_usesOperatorAlphaShortWhenNonNullAndRepoIsDefault() =
testScope.runTest {
var latest: NetworkNameModel? = null
val job = underTest.networkName.onEach { latest = it }.launchIn(this)
@@ -440,7 +451,7 @@
val testOperatorName = "operatorAlphaShort"
// Default network name, operator name is non-null, uses the operator name
- connectionRepository.networkName.value = DEFAULT_NAME
+ connectionRepository.networkName.value = DEFAULT_NAME_MODEL
connectionRepository.operatorAlphaShort.value = testOperatorName
assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived(testOperatorName))
@@ -448,10 +459,39 @@
// Default network name, operator name is null, uses the default
connectionRepository.operatorAlphaShort.value = null
+ assertThat(latest).isEqualTo(DEFAULT_NAME_MODEL)
+
+ // Derived network name, operator name non-null, uses the derived name
+ connectionRepository.networkName.value = DERIVED_NAME_MODEL
+ connectionRepository.operatorAlphaShort.value = testOperatorName
+
+ assertThat(latest).isEqualTo(DERIVED_NAME_MODEL)
+
+ job.cancel()
+ }
+
+ @Test
+ fun networkNameForSubId_usesOperatorAlphaShortWhenNonNullAndRepoIsDefault() =
+ testScope.runTest {
+ var latest: String? = null
+ val job = underTest.carrierName.onEach { latest = it }.launchIn(this)
+
+ val testOperatorName = "operatorAlphaShort"
+
+ // Default network name, operator name is non-null, uses the operator name
+ connectionRepository.carrierName.value = DEFAULT_NAME_MODEL
+ connectionRepository.operatorAlphaShort.value = testOperatorName
+
+ assertThat(latest).isEqualTo(testOperatorName)
+
+ // Default network name, operator name is null, uses the default
+ connectionRepository.operatorAlphaShort.value = null
+
assertThat(latest).isEqualTo(DEFAULT_NAME)
// Derived network name, operator name non-null, uses the derived name
- connectionRepository.networkName.value = DERIVED_NAME
+ connectionRepository.carrierName.value =
+ NetworkNameModel.SubscriptionDerived(DERIVED_NAME)
connectionRepository.operatorAlphaShort.value = testOperatorName
assertThat(latest).isEqualTo(DERIVED_NAME)
@@ -460,6 +500,21 @@
}
@Test
+ fun isSingleCarrier_matchesParent() =
+ testScope.runTest {
+ var latest: Boolean? = null
+ val job = underTest.isSingleCarrier.onEach { latest = it }.launchIn(this)
+
+ mobileIconsInteractor.isSingleCarrier.value = true
+ assertThat(latest).isTrue()
+
+ mobileIconsInteractor.isSingleCarrier.value = false
+ assertThat(latest).isFalse()
+
+ job.cancel()
+ }
+
+ @Test
fun isForceHidden_matchesParent() =
testScope.runTest {
var latest: Boolean? = null
@@ -494,6 +549,7 @@
mobileIconsInteractor.activeDataConnectionHasDataEnabled,
mobileIconsInteractor.alwaysShowDataRatIcon,
mobileIconsInteractor.alwaysUseCdmaLevel,
+ mobileIconsInteractor.isSingleCarrier,
mobileIconsInteractor.mobileIsDefault,
mobileIconsInteractor.defaultMobileIconMapping,
mobileIconsInteractor.defaultMobileIconGroup,
@@ -510,7 +566,9 @@
private const val SUB_1_ID = 1
- private val DEFAULT_NAME = NetworkNameModel.Default("test default name")
- private val DERIVED_NAME = NetworkNameModel.IntentDerived("test derived name")
+ private val DEFAULT_NAME = "test default name"
+ private val DEFAULT_NAME_MODEL = NetworkNameModel.Default(DEFAULT_NAME)
+ private val DERIVED_NAME = "test derived name"
+ private val DERIVED_NAME_MODEL = NetworkNameModel.IntentDerived(DERIVED_NAME)
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt
index 1fb76b0..3e6f909 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt
@@ -527,6 +527,57 @@
}
@Test
+ fun isSingleCarrier_zeroSubscriptions_false() =
+ testScope.runTest {
+ var latest: Boolean? = true
+ val job = underTest.isSingleCarrier.onEach { latest = it }.launchIn(this)
+
+ connectionsRepository.setSubscriptions(emptyList())
+ assertThat(latest).isFalse()
+
+ job.cancel()
+ }
+
+ @Test
+ fun isSingleCarrier_oneSubscription_true() =
+ testScope.runTest {
+ var latest: Boolean? = false
+ val job = underTest.isSingleCarrier.onEach { latest = it }.launchIn(this)
+
+ connectionsRepository.setSubscriptions(listOf(SUB_1))
+ assertThat(latest).isTrue()
+
+ job.cancel()
+ }
+
+ @Test
+ fun isSingleCarrier_twoSubscriptions_false() =
+ testScope.runTest {
+ var latest: Boolean? = true
+ val job = underTest.isSingleCarrier.onEach { latest = it }.launchIn(this)
+
+ connectionsRepository.setSubscriptions(listOf(SUB_1, SUB_2))
+ assertThat(latest).isFalse()
+
+ job.cancel()
+ }
+
+ @Test
+ fun isSingleCarrier_updates() =
+ testScope.runTest {
+ var latest: Boolean? = false
+ val job = underTest.isSingleCarrier.onEach { latest = it }.launchIn(this)
+
+ connectionsRepository.setSubscriptions(listOf(SUB_1))
+ assertThat(latest).isTrue()
+
+ connectionsRepository.setSubscriptions(listOf(SUB_1, SUB_2))
+ assertThat(latest).isFalse()
+
+ job.cancel()
+ }
+
+ @Test
fun mobileIsDefault_mobileFalseAndCarrierMergedFalse_false() =
testScope.runTest {
var latest: Boolean? = null
@@ -745,6 +796,7 @@
subscriptionId = subscriptionIds.first,
isOpportunistic = opportunistic.first,
groupUuid = groupUuid,
+ carrierName = "Carrier ${subscriptionIds.first}"
)
val sub2 =
@@ -752,6 +804,7 @@
subscriptionId = subscriptionIds.second,
isOpportunistic = opportunistic.second,
groupUuid = groupUuid,
+ carrierName = "Carrier ${opportunistic.second}"
)
return Pair(sub1, sub2)
@@ -760,11 +813,13 @@
companion object {
private const val SUB_1_ID = 1
- private val SUB_1 = SubscriptionModel(subscriptionId = SUB_1_ID)
+ private val SUB_1 =
+ SubscriptionModel(subscriptionId = SUB_1_ID, carrierName = "Carrier $SUB_1_ID")
private val CONNECTION_1 = FakeMobileConnectionRepository(SUB_1_ID, mock())
private const val SUB_2_ID = 2
- private val SUB_2 = SubscriptionModel(subscriptionId = SUB_2_ID)
+ private val SUB_2 =
+ SubscriptionModel(subscriptionId = SUB_2_ID, carrierName = "Carrier $SUB_2_ID")
private val CONNECTION_2 = FakeMobileConnectionRepository(SUB_2_ID, mock())
private const val SUB_3_ID = 3
@@ -773,6 +828,7 @@
subscriptionId = SUB_3_ID,
isOpportunistic = true,
groupUuid = ParcelUuid(UUID.randomUUID()),
+ carrierName = "Carrier $SUB_3_ID"
)
private val CONNECTION_3 = FakeMobileConnectionRepository(SUB_3_ID, mock())
@@ -782,6 +838,7 @@
subscriptionId = SUB_4_ID,
isOpportunistic = true,
groupUuid = ParcelUuid(UUID.randomUUID()),
+ carrierName = "Carrier $SUB_4_ID"
)
private val CONNECTION_4 = FakeMobileConnectionRepository(SUB_4_ID, mock())
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelTest.kt
index f0458fa..065dfba 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelTest.kt
@@ -92,15 +92,31 @@
interactor.filteredSubscriptions.value =
listOf(
- SubscriptionModel(subscriptionId = 1, isOpportunistic = false),
+ SubscriptionModel(
+ subscriptionId = 1,
+ isOpportunistic = false,
+ carrierName = "Carrier 1",
+ ),
)
assertThat(latest).isEqualTo(listOf(1))
interactor.filteredSubscriptions.value =
listOf(
- SubscriptionModel(subscriptionId = 2, isOpportunistic = false),
- SubscriptionModel(subscriptionId = 5, isOpportunistic = true),
- SubscriptionModel(subscriptionId = 7, isOpportunistic = true),
+ SubscriptionModel(
+ subscriptionId = 2,
+ isOpportunistic = false,
+ carrierName = "Carrier 2",
+ ),
+ SubscriptionModel(
+ subscriptionId = 5,
+ isOpportunistic = true,
+ carrierName = "Carrier 5",
+ ),
+ SubscriptionModel(
+ subscriptionId = 7,
+ isOpportunistic = true,
+ carrierName = "Carrier 7",
+ ),
)
assertThat(latest).isEqualTo(listOf(2, 5, 7))
@@ -138,6 +154,33 @@
}
@Test
+ fun caching_mobileIconInteractorIsReusedForSameSubId() =
+ testScope.runTest {
+ val interactor1 = underTest.mobileIconInteractorForSub(1)
+ val interactor2 = underTest.mobileIconInteractorForSub(1)
+
+ assertThat(interactor1).isSameInstanceAs(interactor2)
+ }
+
+ @Test
+ fun caching_invalidInteractorssAreRemovedFromCacheWhenSubDisappears() =
+ testScope.runTest {
+ // Retrieve interactors to trigger caching
+ val interactor1 = underTest.mobileIconInteractorForSub(1)
+ val interactor2 = underTest.mobileIconInteractorForSub(2)
+
+ // Both impls are cached
+ assertThat(underTest.mobileIconInteractorSubIdCache)
+ .containsExactly(1, interactor1, 2, interactor2)
+
+ // SUB_1 is removed from the list...
+ interactor.filteredSubscriptions.value = listOf(SUB_2)
+
+ // ... and dropped from the cache
+ assertThat(underTest.mobileIconInteractorSubIdCache).containsExactly(2, interactor2)
+ }
+
+ @Test
fun firstMobileSubShowingNetworkTypeIcon_noSubs_false() =
testScope.runTest {
var latest: Boolean? = null
@@ -308,8 +351,23 @@
}
companion object {
- private val SUB_1 = SubscriptionModel(subscriptionId = 1, isOpportunistic = false)
- private val SUB_2 = SubscriptionModel(subscriptionId = 2, isOpportunistic = false)
- private val SUB_3 = SubscriptionModel(subscriptionId = 3, isOpportunistic = false)
+ private val SUB_1 =
+ SubscriptionModel(
+ subscriptionId = 1,
+ isOpportunistic = false,
+ carrierName = "Carrier 1",
+ )
+ private val SUB_2 =
+ SubscriptionModel(
+ subscriptionId = 2,
+ isOpportunistic = false,
+ carrierName = "Carrier 2",
+ )
+ private val SUB_3 =
+ SubscriptionModel(
+ subscriptionId = 3,
+ isOpportunistic = false,
+ carrierName = "Carrier 3",
+ )
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
index 21e4f5a..a6a2761 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
@@ -32,7 +32,6 @@
import static org.junit.Assume.assumeNotNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
@@ -480,123 +479,45 @@
@Test
public void ifPortraitHalfOpen_drawVerticallyTop() {
- DevicePostureController devicePostureController = mock(DevicePostureController.class);
- when(devicePostureController.getDevicePosture())
- .thenReturn(DevicePostureController.DEVICE_POSTURE_CLOSED);
-
- VolumeDialogImpl dialog = new VolumeDialogImpl(
- getContext(),
- mVolumeDialogController,
- mAccessibilityMgr,
- mDeviceProvisionedController,
- mConfigurationController,
- mMediaOutputDialogFactory,
- mVolumePanelFactory,
- mActivityStarter,
- mInteractionJankMonitor,
- false,
- mCsdWarningDialogFactory,
- devicePostureController,
- mTestableLooper.getLooper(),
- mDumpManager,
- mFeatureFlags
- );
- dialog.init(0 , null);
-
- verify(devicePostureController).addCallback(any());
- dialog.onPostureChanged(DevicePostureController.DEVICE_POSTURE_HALF_OPENED);
+ mDialog.onPostureChanged(DevicePostureController.DEVICE_POSTURE_HALF_OPENED);
mTestableLooper.processAllMessages(); // let dismiss() finish
setOrientation(Configuration.ORIENTATION_PORTRAIT);
// Call show() to trigger layout updates before verifying position
- dialog.show(SHOW_REASON_UNKNOWN);
+ mDialog.show(SHOW_REASON_UNKNOWN);
mTestableLooper.processAllMessages(); // let show() finish before assessing its side-effect
- int gravity = dialog.getWindowGravity();
+ int gravity = mDialog.getWindowGravity();
assertEquals(Gravity.TOP, gravity & Gravity.VERTICAL_GRAVITY_MASK);
-
- cleanUp(dialog);
}
@Test
public void ifPortraitAndOpen_drawCenterVertically() {
- DevicePostureController devicePostureController = mock(DevicePostureController.class);
- when(devicePostureController.getDevicePosture())
- .thenReturn(DevicePostureController.DEVICE_POSTURE_CLOSED);
-
- VolumeDialogImpl dialog = new VolumeDialogImpl(
- getContext(),
- mVolumeDialogController,
- mAccessibilityMgr,
- mDeviceProvisionedController,
- mConfigurationController,
- mMediaOutputDialogFactory,
- mVolumePanelFactory,
- mActivityStarter,
- mInteractionJankMonitor,
- false,
- mCsdWarningDialogFactory,
- devicePostureController,
- mTestableLooper.getLooper(),
- mDumpManager,
- mFeatureFlags
- );
- dialog.init(0, null);
-
- verify(devicePostureController).addCallback(any());
- dialog.onPostureChanged(DevicePostureController.DEVICE_POSTURE_OPENED);
+ mDialog.onPostureChanged(DevicePostureController.DEVICE_POSTURE_OPENED);
mTestableLooper.processAllMessages(); // let dismiss() finish
setOrientation(Configuration.ORIENTATION_PORTRAIT);
- dialog.show(SHOW_REASON_UNKNOWN);
+ mDialog.show(SHOW_REASON_UNKNOWN);
mTestableLooper.processAllMessages(); // let show() finish before assessing its side-effect
- int gravity = dialog.getWindowGravity();
+ int gravity = mDialog.getWindowGravity();
assertEquals(Gravity.CENTER_VERTICAL, gravity & Gravity.VERTICAL_GRAVITY_MASK);
-
- cleanUp(dialog);
}
@Test
public void ifLandscapeAndHalfOpen_drawCenterVertically() {
- DevicePostureController devicePostureController = mock(DevicePostureController.class);
- when(devicePostureController.getDevicePosture())
- .thenReturn(DevicePostureController.DEVICE_POSTURE_CLOSED);
-
- VolumeDialogImpl dialog = new VolumeDialogImpl(
- getContext(),
- mVolumeDialogController,
- mAccessibilityMgr,
- mDeviceProvisionedController,
- mConfigurationController,
- mMediaOutputDialogFactory,
- mVolumePanelFactory,
- mActivityStarter,
- mInteractionJankMonitor,
- false,
- mCsdWarningDialogFactory,
- devicePostureController,
- mTestableLooper.getLooper(),
- mDumpManager,
- mFeatureFlags
- );
- dialog.init(0, null);
-
- verify(devicePostureController).addCallback(any());
- dialog.onPostureChanged(DevicePostureController.DEVICE_POSTURE_HALF_OPENED);
+ mDialog.onPostureChanged(DevicePostureController.DEVICE_POSTURE_HALF_OPENED);
mTestableLooper.processAllMessages(); // let dismiss() finish
setOrientation(Configuration.ORIENTATION_LANDSCAPE);
- dialog.show(SHOW_REASON_UNKNOWN);
+ mDialog.show(SHOW_REASON_UNKNOWN);
mTestableLooper.processAllMessages(); // let show() finish before assessing its side-effect
- int gravity = dialog.getWindowGravity();
+ int gravity = mDialog.getWindowGravity();
assertEquals(Gravity.CENTER_VERTICAL, gravity & Gravity.VERTICAL_GRAVITY_MASK);
-
- cleanUp(dialog);
}
@Test
@@ -607,31 +528,9 @@
@Test
public void dialogDestroy_removesPostureControllerCallback() {
- VolumeDialogImpl dialog = new VolumeDialogImpl(
- getContext(),
- mVolumeDialogController,
- mAccessibilityMgr,
- mDeviceProvisionedController,
- mConfigurationController,
- mMediaOutputDialogFactory,
- mVolumePanelFactory,
- mActivityStarter,
- mInteractionJankMonitor,
- false,
- mCsdWarningDialogFactory,
- mPostureController,
- mTestableLooper.getLooper(),
- mDumpManager,
- mFeatureFlags
- );
- dialog.init(0, null);
-
verify(mPostureController, never()).removeCallback(any());
- dialog.destroy();
-
+ mDialog.destroy();
verify(mPostureController).removeCallback(any());
-
- cleanUp(dialog);
}
private void setOrientation(int orientation) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubbleEducationControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubbleEducationControllerTest.kt
new file mode 100644
index 0000000..94ed608
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubbleEducationControllerTest.kt
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2023 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 android.content.ContentResolver
+import android.content.Context
+import android.content.SharedPreferences
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import androidx.test.filters.SmallTest
+import com.android.systemui.model.SysUiStateTest
+import com.android.wm.shell.bubbles.Bubble
+import com.android.wm.shell.bubbles.BubbleEducationController
+import com.android.wm.shell.bubbles.PREF_MANAGED_EDUCATION
+import com.android.wm.shell.bubbles.PREF_STACK_EDUCATION
+import org.junit.Assert.assertEquals
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyBoolean
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.ArgumentMatchers.anyString
+import org.mockito.Mockito
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+class BubbleEducationControllerTest : SysUiStateTest() {
+ private val sharedPrefsEditor = Mockito.mock(SharedPreferences.Editor::class.java)
+ private val sharedPrefs = Mockito.mock(SharedPreferences::class.java)
+ private val context = Mockito.mock(Context::class.java)
+ private lateinit var sut: BubbleEducationController
+
+ @Before
+ fun setUp() {
+ Mockito.`when`(context.packageName).thenReturn("packageName")
+ Mockito.`when`(context.getSharedPreferences(anyString(), anyInt())).thenReturn(sharedPrefs)
+ Mockito.`when`(context.contentResolver)
+ .thenReturn(Mockito.mock(ContentResolver::class.java))
+ Mockito.`when`(sharedPrefs.edit()).thenReturn(sharedPrefsEditor)
+ sut = BubbleEducationController(context)
+ }
+
+ @Test
+ fun testSeenStackEducation_read() {
+ Mockito.`when`(sharedPrefs.getBoolean(anyString(), anyBoolean())).thenReturn(true)
+ assertEquals(sut.hasSeenStackEducation, true)
+ Mockito.verify(sharedPrefs).getBoolean(PREF_STACK_EDUCATION, false)
+ }
+
+ @Test
+ fun testSeenStackEducation_write() {
+ sut.hasSeenStackEducation = true
+ Mockito.verify(sharedPrefsEditor).putBoolean(PREF_STACK_EDUCATION, true)
+ }
+
+ @Test
+ fun testSeenManageEducation_read() {
+ Mockito.`when`(sharedPrefs.getBoolean(anyString(), anyBoolean())).thenReturn(true)
+ assertEquals(sut.hasSeenManageEducation, true)
+ Mockito.verify(sharedPrefs).getBoolean(PREF_MANAGED_EDUCATION, false)
+ }
+
+ @Test
+ fun testSeenManageEducation_write() {
+ sut.hasSeenManageEducation = true
+ Mockito.verify(sharedPrefsEditor).putBoolean(PREF_MANAGED_EDUCATION, true)
+ }
+
+ @Test
+ fun testShouldShowStackEducation() {
+ val bubble = Mockito.mock(Bubble::class.java)
+ // When bubble is null
+ assertEquals(sut.shouldShowStackEducation(null), false)
+ // When bubble is not conversation
+ Mockito.`when`(bubble.isConversation).thenReturn(false)
+ assertEquals(sut.shouldShowStackEducation(bubble), false)
+ // When bubble is conversation and has seen stack edu
+ Mockito.`when`(bubble.isConversation).thenReturn(true)
+ Mockito.`when`(sharedPrefs.getBoolean(anyString(), anyBoolean())).thenReturn(true)
+ assertEquals(sut.shouldShowStackEducation(bubble), false)
+ // When bubble is conversation and has not seen stack edu
+ Mockito.`when`(bubble.isConversation).thenReturn(true)
+ Mockito.`when`(sharedPrefs.getBoolean(anyString(), anyBoolean())).thenReturn(false)
+ assertEquals(sut.shouldShowStackEducation(bubble), true)
+ }
+
+ @Test
+ fun testShouldShowManageEducation() {
+ val bubble = Mockito.mock(Bubble::class.java)
+ // When bubble is null
+ assertEquals(sut.shouldShowManageEducation(null), false)
+ // When bubble is not conversation
+ Mockito.`when`(bubble.isConversation).thenReturn(false)
+ assertEquals(sut.shouldShowManageEducation(bubble), false)
+ // When bubble is conversation and has seen stack edu
+ Mockito.`when`(bubble.isConversation).thenReturn(true)
+ Mockito.`when`(sharedPrefs.getBoolean(anyString(), anyBoolean())).thenReturn(true)
+ assertEquals(sut.shouldShowManageEducation(bubble), false)
+ // When bubble is conversation and has not seen stack edu
+ Mockito.`when`(bubble.isConversation).thenReturn(true)
+ Mockito.`when`(sharedPrefs.getBoolean(anyString(), anyBoolean())).thenReturn(false)
+ assertEquals(sut.shouldShowManageEducation(bubble), true)
+ }
+}
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index 2d60716..a98cacd 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -3987,14 +3987,14 @@
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.BIND_APPWIDGET, null);
} catch (SecurityException se) {
- if (!isCallerBindAppWidgetWhiteListedLocked(packageName)) {
+ if (!isCallerBindAppWidgetAllowListedLocked(packageName)) {
return false;
}
}
return true;
}
- private boolean isCallerBindAppWidgetWhiteListedLocked(String packageName) {
+ private boolean isCallerBindAppWidgetAllowListedLocked(String packageName) {
final int userId = UserHandle.getCallingUserId();
final int packageUid = getUidForPackage(packageName, userId);
if (packageUid < 0) {
diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
index 315972c..f594170 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
@@ -1225,15 +1225,13 @@
public ContentCaptureOptions getOptions(@UserIdInt int userId,
@NonNull String packageName) {
boolean isContentCaptureReceiverEnabled;
- boolean isContentProtectionReceiverEnabled;
+ boolean isContentProtectionReceiverEnabled =
+ isContentProtectionReceiverEnabled(userId, packageName);
ArraySet<ComponentName> whitelistedComponents = null;
synchronized (mGlobalWhitelistStateLock) {
isContentCaptureReceiverEnabled =
isContentCaptureReceiverEnabled(userId, packageName);
- isContentProtectionReceiverEnabled =
- isContentProtectionReceiverEnabled(userId, packageName);
-
if (!isContentCaptureReceiverEnabled) {
// Full package is not allowlisted: check individual components next
whitelistedComponents = getWhitelistedComponents(userId, packageName);
diff --git a/services/core/java/com/android/server/EventLogTags.logtags b/services/core/java/com/android/server/EventLogTags.logtags
index b67e627..d47a399 100644
--- a/services/core/java/com/android/server/EventLogTags.logtags
+++ b/services/core/java/com/android/server/EventLogTags.logtags
@@ -81,7 +81,7 @@
# when a notification has been clicked
27520 notification_clicked (key|3),(lifespan|1),(freshness|1),(exposure|1),(rank|1),(count|1)
# when a notification action button has been clicked
-27521 notification_action_clicked (key|3),(action_index|1),(lifespan|1),(freshness|1),(exposure|1),(rank|1),(count|1)
+27521 notification_action_clicked (key|3),(piIdentifier|3),(pendingIntent|3),(action_index|1),(lifespan|1),(freshness|1),(exposure|1),(rank|1),(count|1)
# when a notification has been canceled
27530 notification_canceled (key|3),(reason|1),(lifespan|1),(freshness|1),(exposure|1),(rank|1),(count|1),(listener|3)
# replaces 27510 with a row per notification
diff --git a/services/core/java/com/android/server/VcnManagementService.java b/services/core/java/com/android/server/VcnManagementService.java
index c6e9a7d..7acca19 100644
--- a/services/core/java/com/android/server/VcnManagementService.java
+++ b/services/core/java/com/android/server/VcnManagementService.java
@@ -456,7 +456,13 @@
final List<SubscriptionInfo> subscriptionInfos = new ArrayList<>();
Binder.withCleanCallingIdentity(
() -> {
- subscriptionInfos.addAll(subMgr.getSubscriptionsInGroup(subscriptionGroup));
+ List<SubscriptionInfo> subsInGroup =
+ subMgr.getSubscriptionsInGroup(subscriptionGroup);
+ if (subsInGroup == null) {
+ logWtf("Received null from getSubscriptionsInGroup");
+ subsInGroup = Collections.emptyList();
+ }
+ subscriptionInfos.addAll(subsInGroup);
});
for (SubscriptionInfo info : subscriptionInfos) {
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index 1982784..1d670664 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -391,7 +391,6 @@
final boolean wasBtScoRequested = isBluetoothScoRequested();
CommunicationRouteClient client;
-
// Save previous client route in case of failure to start BT SCO audio
AudioDeviceAttributes prevClientDevice = null;
boolean prevPrivileged = false;
@@ -1043,7 +1042,7 @@
synchronized (mBluetoothAudioStateLock) {
mBluetoothScoOn = on;
updateAudioHalBluetoothState();
- postUpdateCommunicationRouteClient(eventSource);
+ postUpdateCommunicationRouteClient(isBluetoothScoRequested(), eventSource);
}
}
@@ -1395,8 +1394,10 @@
MSG_I_SAVE_CLEAR_PREF_DEVICES_FOR_CAPTURE_PRESET, SENDMSG_QUEUE, capturePreset);
}
- /*package*/ void postUpdateCommunicationRouteClient(String eventSource) {
- sendLMsgNoDelay(MSG_L_UPDATE_COMMUNICATION_ROUTE_CLIENT, SENDMSG_QUEUE, eventSource);
+ /*package*/ void postUpdateCommunicationRouteClient(
+ boolean wasBtScoRequested, String eventSource) {
+ sendILMsgNoDelay(MSG_IL_UPDATE_COMMUNICATION_ROUTE_CLIENT, SENDMSG_QUEUE,
+ wasBtScoRequested ? 1 : 0, eventSource);
}
/*package*/ void postSetCommunicationDeviceForClient(CommunicationDeviceInfo info) {
@@ -1708,7 +1709,8 @@
: AudioSystem.STREAM_DEFAULT);
if (btInfo.mProfile == BluetoothProfile.LE_AUDIO
|| btInfo.mProfile == BluetoothProfile.HEARING_AID) {
- onUpdateCommunicationRouteClient("setBluetoothActiveDevice");
+ onUpdateCommunicationRouteClient(isBluetoothScoRequested(),
+ "setBluetoothActiveDevice");
}
}
}
@@ -1762,9 +1764,11 @@
case MSG_I_SET_MODE_OWNER:
synchronized (mSetModeLock) {
synchronized (mDeviceStateLock) {
+ boolean wasBtScoRequested = isBluetoothScoRequested();
mAudioModeOwner = (AudioModeInfo) msg.obj;
if (mAudioModeOwner.mMode != AudioSystem.MODE_RINGTONE) {
- onUpdateCommunicationRouteClient("setNewModeOwner");
+ onUpdateCommunicationRouteClient(
+ wasBtScoRequested, "setNewModeOwner");
}
}
}
@@ -1787,10 +1791,10 @@
}
break;
- case MSG_L_UPDATE_COMMUNICATION_ROUTE_CLIENT:
+ case MSG_IL_UPDATE_COMMUNICATION_ROUTE_CLIENT:
synchronized (mSetModeLock) {
synchronized (mDeviceStateLock) {
- onUpdateCommunicationRouteClient((String) msg.obj);
+ onUpdateCommunicationRouteClient(msg.arg1 == 1, (String) msg.obj);
}
}
break;
@@ -1973,7 +1977,7 @@
private static final int MSG_I_SAVE_CLEAR_PREF_DEVICES_FOR_CAPTURE_PRESET = 38;
private static final int MSG_L_SET_COMMUNICATION_DEVICE_FOR_CLIENT = 42;
- private static final int MSG_L_UPDATE_COMMUNICATION_ROUTE_CLIENT = 43;
+ private static final int MSG_IL_UPDATE_COMMUNICATION_ROUTE_CLIENT = 43;
private static final int MSG_I_SCO_AUDIO_STATE_CHANGED = 44;
private static final int MSG_L_BT_ACTIVE_DEVICE_CHANGE_EXT = 45;
@@ -2330,16 +2334,20 @@
*/
// @GuardedBy("mSetModeLock")
@GuardedBy("mDeviceStateLock")
- private void onUpdateCommunicationRouteClient(String eventSource) {
- updateCommunicationRoute(eventSource);
+ private void onUpdateCommunicationRouteClient(boolean wasBtScoRequested, String eventSource) {
CommunicationRouteClient crc = topCommunicationRouteClient();
if (AudioService.DEBUG_COMM_RTE) {
- Log.v(TAG, "onUpdateCommunicationRouteClient, crc: "
- + crc + " eventSource: " + eventSource);
+ Log.v(TAG, "onUpdateCommunicationRouteClient, crc: " + crc
+ + " wasBtScoRequested: " + wasBtScoRequested + " eventSource: " + eventSource);
}
if (crc != null) {
setCommunicationRouteForClient(crc.getBinder(), crc.getUid(), crc.getDevice(),
BtHelper.SCO_MODE_UNDEFINED, crc.isPrivileged(), eventSource);
+ } else {
+ if (!isBluetoothScoRequested() && wasBtScoRequested) {
+ mBtHelper.stopBluetoothSco(eventSource);
+ }
+ updateCommunicationRoute(eventSource);
}
}
@@ -2403,7 +2411,11 @@
}
@GuardedBy("mDeviceStateLock")
- private boolean communnicationDeviceCompatOn() {
+ // LE Audio: For system server (Telecom) and APKs targeting S and above, we let the audio
+ // policy routing rules select the default communication device.
+ // For older APKs, we force LE Audio headset when connected as those APKs cannot select a LE
+ // Audiodevice explicitly.
+ private boolean communnicationDeviceLeAudioCompatOn() {
return mAudioModeOwner.mMode == AudioSystem.MODE_IN_COMMUNICATION
&& !(CompatChanges.isChangeEnabled(
USE_SET_COMMUNICATION_DEVICE, mAudioModeOwner.mUid)
@@ -2411,19 +2423,25 @@
}
@GuardedBy("mDeviceStateLock")
+ // Hearing Aid: For system server (Telecom) and IN_CALL mode we let the audio
+ // policy routing rules select the default communication device.
+ // For 3p apps and IN_COMMUNICATION mode we force Hearing aid when connected to maintain
+ // backwards compatibility
+ private boolean communnicationDeviceHaCompatOn() {
+ return mAudioModeOwner.mMode == AudioSystem.MODE_IN_COMMUNICATION
+ && !(mAudioModeOwner.mUid == android.os.Process.SYSTEM_UID);
+ }
+
+ @GuardedBy("mDeviceStateLock")
AudioDeviceAttributes getDefaultCommunicationDevice() {
- // For system server (Telecom) and APKs targeting S and above, we let the audio
- // policy routing rules select the default communication device.
- // For older APKs, we force Hearing Aid or LE Audio headset when connected as
- // those APKs cannot select a LE Audio or Hearing Aid device explicitly.
AudioDeviceAttributes device = null;
- if (communnicationDeviceCompatOn()) {
- // If both LE and Hearing Aid are active (thie should not happen),
- // priority to Hearing Aid.
+ // If both LE and Hearing Aid are active (thie should not happen),
+ // priority to Hearing Aid.
+ if (communnicationDeviceHaCompatOn()) {
device = mDeviceInventory.getDeviceOfType(AudioSystem.DEVICE_OUT_HEARING_AID);
- if (device == null) {
- device = mDeviceInventory.getDeviceOfType(AudioSystem.DEVICE_OUT_BLE_HEADSET);
- }
+ }
+ if (device == null && communnicationDeviceLeAudioCompatOn()) {
+ device = mDeviceInventory.getDeviceOfType(AudioSystem.DEVICE_OUT_BLE_HEADSET);
}
return device;
}
@@ -2433,6 +2451,7 @@
List<AudioRecordingConfiguration> recordConfigs) {
synchronized (mSetModeLock) {
synchronized (mDeviceStateLock) {
+ final boolean wasBtScoRequested = isBluetoothScoRequested();
boolean updateCommunicationRoute = false;
for (CommunicationRouteClient crc : mCommunicationRouteClients) {
boolean wasActive = crc.isActive();
@@ -2461,7 +2480,8 @@
}
}
if (updateCommunicationRoute) {
- postUpdateCommunicationRouteClient("updateCommunicationRouteClientsActivity");
+ postUpdateCommunicationRouteClient(
+ wasBtScoRequested, "updateCommunicationRouteClientsActivity");
}
}
}
diff --git a/services/core/java/com/android/server/audio/BtHelper.java b/services/core/java/com/android/server/audio/BtHelper.java
index 3560797..a4d26d3 100644
--- a/services/core/java/com/android/server/audio/BtHelper.java
+++ b/services/core/java/com/android/server/audio/BtHelper.java
@@ -329,7 +329,7 @@
default:
break;
}
- if(broadcast) {
+ if (broadcast) {
broadcastScoConnectionState(scoAudioState);
//FIXME: this is to maintain compatibility with deprecated intent
// AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED. Remove when appropriate.
@@ -718,8 +718,10 @@
checkScoAudioState();
if (state == BluetoothHeadset.STATE_AUDIO_CONNECTED) {
// Make sure that the state transitions to CONNECTING even if we cannot initiate
- // the connection.
- broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_CONNECTING);
+ // the connection except if already connected internally
+ if (mScoAudioState != SCO_STATE_ACTIVE_INTERNAL) {
+ broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_CONNECTING);
+ }
switch (mScoAudioState) {
case SCO_STATE_INACTIVE:
mScoAudioMode = scoAudioMode;
@@ -775,7 +777,7 @@
broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_CONNECTED);
break;
case SCO_STATE_ACTIVE_INTERNAL:
- Log.w(TAG, "requestScoState: already in ACTIVE mode, simply return");
+ // Already in ACTIVE mode, simply return
break;
case SCO_STATE_ACTIVE_EXTERNAL:
/* Confirm SCO Audio connection to requesting app as it is already connected
diff --git a/services/core/java/com/android/server/display/DisplayDevice.java b/services/core/java/com/android/server/display/DisplayDevice.java
index d57dc47..8642fb8 100644
--- a/services/core/java/com/android/server/display/DisplayDevice.java
+++ b/services/core/java/com/android/server/display/DisplayDevice.java
@@ -16,6 +16,9 @@
package com.android.server.display;
+import static android.view.Surface.ROTATION_270;
+import static android.view.Surface.ROTATION_90;
+
import android.annotation.Nullable;
import android.content.Context;
import android.graphics.Point;
@@ -132,12 +135,15 @@
/**
* Returns the default size of the surface associated with the display, or null if the surface
* is not provided for layer mirroring by SurfaceFlinger. For non virtual displays, this will
- * be the actual display device's size.
+ * be the actual display device's size, reflecting the current rotation.
*/
@Nullable
public Point getDisplaySurfaceDefaultSizeLocked() {
DisplayDeviceInfo displayDeviceInfo = getDisplayDeviceInfoLocked();
- return new Point(displayDeviceInfo.width, displayDeviceInfo.height);
+ final boolean isRotated = mCurrentOrientation == ROTATION_90
+ || mCurrentOrientation == ROTATION_270;
+ return isRotated ? new Point(displayDeviceInfo.height, displayDeviceInfo.width)
+ : new Point(displayDeviceInfo.width, displayDeviceInfo.height);
}
/**
@@ -358,7 +364,7 @@
}
boolean isRotated = (mCurrentOrientation == Surface.ROTATION_90
- || mCurrentOrientation == Surface.ROTATION_270);
+ || mCurrentOrientation == ROTATION_270);
DisplayDeviceInfo info = getDisplayDeviceInfoLocked();
viewport.deviceWidth = isRotated ? info.height : info.width;
viewport.deviceHeight = isRotated ? info.width : info.height;
diff --git a/services/core/java/com/android/server/display/DisplayDeviceConfig.java b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
index e5965ef..486cd28 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceConfig.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
@@ -2080,7 +2080,7 @@
/** Loads the refresh rate profiles. */
private void loadRefreshRateZoneProfiles(RefreshRateConfigs refreshRateConfigs) {
- if (refreshRateConfigs == null) {
+ if (refreshRateConfigs == null || refreshRateConfigs.getRefreshRateZoneProfiles() == null) {
return;
}
for (RefreshRateZone zone :
diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java
index 4edc8bc..9c271ff5 100644
--- a/services/core/java/com/android/server/display/LogicalDisplay.java
+++ b/services/core/java/com/android/server/display/LogicalDisplay.java
@@ -441,6 +441,9 @@
if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_ALWAYS_UNLOCKED) != 0) {
mBaseDisplayInfo.flags |= Display.FLAG_ALWAYS_UNLOCKED;
}
+ if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT) != 0) {
+ mBaseDisplayInfo.flags |= Display.FLAG_ROTATES_WITH_CONTENT;
+ }
if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_TOUCH_FEEDBACK_DISABLED) != 0) {
mBaseDisplayInfo.flags |= Display.FLAG_TOUCH_FEEDBACK_DISABLED;
}
diff --git a/services/core/java/com/android/server/location/gnss/GnssListenerMultiplexer.java b/services/core/java/com/android/server/location/gnss/GnssListenerMultiplexer.java
index 567d8ac..f21a9fe 100644
--- a/services/core/java/com/android/server/location/gnss/GnssListenerMultiplexer.java
+++ b/services/core/java/com/android/server/location/gnss/GnssListenerMultiplexer.java
@@ -201,10 +201,10 @@
this::onProviderEnabledChanged;
private final SettingsHelper.GlobalSettingChangedListener
mBackgroundThrottlePackageWhitelistChangedListener =
- this::onBackgroundThrottlePackageWhitelistChanged;
+ this::onBackgroundThrottlePackageAllowlistChanged;
private final SettingsHelper.UserSettingChangedListener
mLocationPackageBlacklistChangedListener =
- this::onLocationPackageBlacklistChanged;
+ this::onLocationPackageDenylistChanged;
private final LocationPermissionsHelper.LocationPermissionsListener
mLocationPermissionsListener =
new LocationPermissionsHelper.LocationPermissionsListener() {
@@ -407,11 +407,11 @@
updateRegistrations(registration -> registration.getIdentity().getUserId() == userId);
}
- private void onBackgroundThrottlePackageWhitelistChanged() {
+ private void onBackgroundThrottlePackageAllowlistChanged() {
updateRegistrations(registration -> true);
}
- private void onLocationPackageBlacklistChanged(int userId) {
+ private void onLocationPackageDenylistChanged(int userId) {
updateRegistrations(registration -> registration.getIdentity().getUserId() == userId);
}
diff --git a/services/core/java/com/android/server/location/injector/SettingsHelper.java b/services/core/java/com/android/server/location/injector/SettingsHelper.java
index 490bfe1..32cbff8 100644
--- a/services/core/java/com/android/server/location/injector/SettingsHelper.java
+++ b/services/core/java/com/android/server/location/injector/SettingsHelper.java
@@ -93,37 +93,37 @@
GlobalSettingChangedListener listener);
/**
- * Check if the given package is blacklisted for location access.
+ * Check if the given package is denylisted for location access.
*/
public abstract boolean isLocationPackageBlacklisted(int userId, String packageName);
/**
- * Add a listener for changes to the location package blacklist. Callbacks occur on an
+ * Add a listener for changes to the location package denylist. Callbacks occur on an
* unspecified thread.
*/
public abstract void addOnLocationPackageBlacklistChangedListener(
UserSettingChangedListener listener);
/**
- * Remove a listener for changes to the location package blacklist.
+ * Remove a listener for changes to the location package denylist.
*/
public abstract void removeOnLocationPackageBlacklistChangedListener(
UserSettingChangedListener listener);
/**
- * Retrieve the background throttle package whitelist.
+ * Retrieve the background throttle package allowlist.
*/
public abstract Set<String> getBackgroundThrottlePackageWhitelist();
/**
- * Add a listener for changes to the background throttle package whitelist. Callbacks occur on
+ * Add a listener for changes to the background throttle package allowlist. Callbacks occur on
* an unspecified thread.
*/
public abstract void addOnBackgroundThrottlePackageWhitelistChangedListener(
GlobalSettingChangedListener listener);
/**
- * Remove a listener for changes to the background throttle package whitelist.
+ * Remove a listener for changes to the background throttle package allowlist.
*/
public abstract void removeOnBackgroundThrottlePackageWhitelistChangedListener(
GlobalSettingChangedListener listener);
@@ -134,14 +134,14 @@
public abstract boolean isGnssMeasurementsFullTrackingEnabled();
/**
- * Add a listener for changes to the background throttle package whitelist. Callbacks occur on
+ * Add a listener for changes to the background throttle package allowlist. Callbacks occur on
* an unspecified thread.
*/
public abstract void addOnGnssMeasurementsFullTrackingEnabledChangedListener(
GlobalSettingChangedListener listener);
/**
- * Remove a listener for changes to the background throttle package whitelist.
+ * Remove a listener for changes to the background throttle package allowlist.
*/
public abstract void removeOnGnssMeasurementsFullTrackingEnabledChangedListener(
GlobalSettingChangedListener listener);
@@ -166,14 +166,14 @@
public abstract PackageTagsList getIgnoreSettingsAllowlist();
/**
- * Add a listener for changes to the ignore settings package whitelist. Callbacks occur on an
+ * Add a listener for changes to the ignore settings package allowlist. Callbacks occur on an
* unspecified thread.
*/
public abstract void addIgnoreSettingsAllowlistChangedListener(
GlobalSettingChangedListener listener);
/**
- * Remove a listener for changes to the ignore settings package whitelist.
+ * Remove a listener for changes to the ignore settings package allowlist.
*/
public abstract void removeIgnoreSettingsAllowlistChangedListener(
GlobalSettingChangedListener listener);
diff --git a/services/core/java/com/android/server/location/injector/SystemSettingsHelper.java b/services/core/java/com/android/server/location/injector/SystemSettingsHelper.java
index 777683e..8bb184c 100644
--- a/services/core/java/com/android/server/location/injector/SystemSettingsHelper.java
+++ b/services/core/java/com/android/server/location/injector/SystemSettingsHelper.java
@@ -65,8 +65,8 @@
*/
public class SystemSettingsHelper extends SettingsHelper {
- private static final String LOCATION_PACKAGE_BLACKLIST = "locationPackagePrefixBlacklist";
- private static final String LOCATION_PACKAGE_WHITELIST = "locationPackagePrefixWhitelist";
+ private static final String LOCATION_PACKAGE_DENYLIST = "locationPackagePrefixBlacklist";
+ private static final String LOCATION_PACKAGE_ALLOWLIST = "locationPackagePrefixWhitelist";
private static final long DEFAULT_BACKGROUND_THROTTLE_INTERVAL_MS = 30 * 60 * 1000;
private static final long DEFAULT_BACKGROUND_THROTTLE_PROXIMITY_ALERT_INTERVAL_MS =
@@ -93,9 +93,9 @@
mGnssMeasurementFullTracking = new BooleanGlobalSetting(context,
ENABLE_GNSS_RAW_MEAS_FULL_TRACKING, FgThread.getHandler());
mLocationPackageBlacklist = new StringListCachedSecureSetting(context,
- LOCATION_PACKAGE_BLACKLIST, FgThread.getHandler());
+ LOCATION_PACKAGE_DENYLIST, FgThread.getHandler());
mLocationPackageWhitelist = new StringListCachedSecureSetting(context,
- LOCATION_PACKAGE_WHITELIST, FgThread.getHandler());
+ LOCATION_PACKAGE_ALLOWLIST, FgThread.getHandler());
mBackgroundThrottlePackageWhitelist = new StringSetCachedGlobalSetting(context,
LOCATION_BACKGROUND_THROTTLE_PACKAGE_WHITELIST,
() -> SystemConfig.getInstance().getAllowUnthrottledLocation(),
diff --git a/services/core/java/com/android/server/net/NetworkPolicyLogger.java b/services/core/java/com/android/server/net/NetworkPolicyLogger.java
index dc8fcb0..85731651 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyLogger.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyLogger.java
@@ -338,8 +338,8 @@
return "App idle state of uid " + uid + ": " + idle;
}
- private static String getAppIdleWlChangedLog(int uid, boolean isWhitelisted) {
- return "App idle whitelist state of uid " + uid + ": " + isWhitelisted;
+ private static String getAppIdleWlChangedLog(int uid, boolean isAllowlisted) {
+ return "App idle whitelist state of uid " + uid + ": " + isAllowlisted;
}
private static String getParoleStateChanged(boolean paroleOn) {
@@ -519,14 +519,14 @@
data.timeStamp = System.currentTimeMillis();
}
- public void appIdleWlChanged(int uid, boolean isWhitelisted) {
+ public void appIdleWlChanged(int uid, boolean isAllowlisted) {
final Data data = getNextSlot();
if (data == null) return;
data.reset();
data.type = EVENT_APP_IDLE_WL_CHANGED;
data.ifield1 = uid;
- data.bfield1 = isWhitelisted;
+ data.bfield1 = isAllowlisted;
data.timeStamp = System.currentTimeMillis();
}
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index c506469..52734a4 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -364,7 +364,7 @@
private static final String TAG_NETWORK_POLICY = "network-policy";
private static final String TAG_UID_POLICY = "uid-policy";
private static final String TAG_APP_POLICY = "app-policy";
- private static final String TAG_WHITELIST = "whitelist";
+ private static final String TAG_ALLOWLIST = "whitelist";
private static final String TAG_RESTRICT_BACKGROUND = "restrict-background";
private static final String TAG_REVOKED_RESTRICT_BACKGROUND = "revoked-restrict-background";
private static final String TAG_XML_UTILS_INT_ARRAY = "int-array";
@@ -858,7 +858,7 @@
}
@GuardedBy("mUidRulesFirstLock")
- private void updatePowerSaveWhitelistUL() {
+ private void updatePowerSaveAllowlistUL() {
int[] whitelist = mPowerWhitelistManager.getWhitelistedAppIds(/* includingIdle */ false);
mPowerSaveWhitelistExceptIdleAppIds.clear();
for (int uid : whitelist) {
@@ -949,7 +949,7 @@
synchronized (mUidRulesFirstLock) {
synchronized (mNetworkPoliciesSecondLock) {
- updatePowerSaveWhitelistUL();
+ updatePowerSaveAllowlistUL();
mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
mPowerManagerInternal.registerLowPowerModeObserver(
new PowerManagerInternal.LowPowerModeListener() {
@@ -1193,7 +1193,7 @@
public void onReceive(Context context, Intent intent) {
// on background handler thread, and POWER_SAVE_WHITELIST_CHANGED is protected
synchronized (mUidRulesFirstLock) {
- updatePowerSaveWhitelistUL();
+ updatePowerSaveAllowlistUL();
updateRulesForRestrictPowerUL();
updateRulesForAppIdleUL();
}
@@ -2683,7 +2683,7 @@
} else {
Slog.w(TAG, "unable to apply policy to UID " + uid + "; ignoring");
}
- } else if (TAG_WHITELIST.equals(tag)) {
+ } else if (TAG_ALLOWLIST.equals(tag)) {
insideAllowlist = true;
} else if (TAG_RESTRICT_BACKGROUND.equals(tag) && insideAllowlist) {
final int uid = readIntAttribute(in, ATTR_UID);
@@ -2693,7 +2693,7 @@
mRestrictBackgroundAllowlistRevokedUids.put(uid, true);
}
} else if (type == END_TAG) {
- if (TAG_WHITELIST.equals(tag)) {
+ if (TAG_ALLOWLIST.equals(tag)) {
insideAllowlist = false;
}
@@ -2869,7 +2869,7 @@
out.endTag(null, TAG_POLICY_LIST);
// write all allowlists
- out.startTag(null, TAG_WHITELIST);
+ out.startTag(null, TAG_ALLOWLIST);
// revoked restrict background allowlist
int size = mRestrictBackgroundAllowlistRevokedUids.size();
@@ -2880,7 +2880,7 @@
out.endTag(null, TAG_REVOKED_RESTRICT_BACKGROUND);
}
- out.endTag(null, TAG_WHITELIST);
+ out.endTag(null, TAG_ALLOWLIST);
out.endDocument();
@@ -4382,7 +4382,7 @@
void updateRulesForPowerSaveUL() {
Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForPowerSaveUL");
try {
- updateRulesForWhitelistedPowerSaveUL(mRestrictPower, FIREWALL_CHAIN_POWERSAVE,
+ updateRulesForAllowlistedPowerSaveUL(mRestrictPower, FIREWALL_CHAIN_POWERSAVE,
mUidFirewallPowerSaveRules);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
@@ -4391,14 +4391,14 @@
@GuardedBy("mUidRulesFirstLock")
void updateRuleForRestrictPowerUL(int uid) {
- updateRulesForWhitelistedPowerSaveUL(uid, mRestrictPower, FIREWALL_CHAIN_POWERSAVE);
+ updateRulesForAllowlistedPowerSaveUL(uid, mRestrictPower, FIREWALL_CHAIN_POWERSAVE);
}
@GuardedBy("mUidRulesFirstLock")
void updateRulesForDeviceIdleUL() {
Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForDeviceIdleUL");
try {
- updateRulesForWhitelistedPowerSaveUL(mDeviceIdleMode, FIREWALL_CHAIN_DOZABLE,
+ updateRulesForAllowlistedPowerSaveUL(mDeviceIdleMode, FIREWALL_CHAIN_DOZABLE,
mUidFirewallDozableRules);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
@@ -4407,26 +4407,26 @@
@GuardedBy("mUidRulesFirstLock")
void updateRuleForDeviceIdleUL(int uid) {
- updateRulesForWhitelistedPowerSaveUL(uid, mDeviceIdleMode, FIREWALL_CHAIN_DOZABLE);
+ updateRulesForAllowlistedPowerSaveUL(uid, mDeviceIdleMode, FIREWALL_CHAIN_DOZABLE);
}
// NOTE: since both fw_dozable and fw_powersave uses the same map
// (mPowerSaveTempWhitelistAppIds) for allowlisting, we can reuse their logic in this method.
@GuardedBy("mUidRulesFirstLock")
- private void updateRulesForWhitelistedPowerSaveUL(boolean enabled, int chain,
+ private void updateRulesForAllowlistedPowerSaveUL(boolean enabled, int chain,
SparseIntArray rules) {
if (enabled) {
- // Sync the whitelists before enabling the chain. We don't care about the rules if
+ // Sync the allowlists before enabling the chain. We don't care about the rules if
// we are disabling the chain.
final SparseIntArray uidRules = rules;
uidRules.clear();
final List<UserInfo> users = mUserManager.getUsers();
for (int ui = users.size() - 1; ui >= 0; ui--) {
UserInfo user = users.get(ui);
- updateRulesForWhitelistedAppIds(uidRules, mPowerSaveTempWhitelistAppIds, user.id);
- updateRulesForWhitelistedAppIds(uidRules, mPowerSaveWhitelistAppIds, user.id);
+ updateRulesForAllowlistedAppIds(uidRules, mPowerSaveTempWhitelistAppIds, user.id);
+ updateRulesForAllowlistedAppIds(uidRules, mPowerSaveWhitelistAppIds, user.id);
if (chain == FIREWALL_CHAIN_POWERSAVE) {
- updateRulesForWhitelistedAppIds(uidRules,
+ updateRulesForAllowlistedAppIds(uidRules,
mPowerSaveWhitelistExceptIdleAppIds, user.id);
}
}
@@ -4441,7 +4441,7 @@
}
}
- private void updateRulesForWhitelistedAppIds(final SparseIntArray uidRules,
+ private void updateRulesForAllowlistedAppIds(final SparseIntArray uidRules,
final SparseBooleanArray whitelistedAppIds, int userId) {
for (int i = whitelistedAppIds.size() - 1; i >= 0; --i) {
if (whitelistedAppIds.valueAt(i)) {
@@ -4502,12 +4502,12 @@
* allowlisted.
*/
@GuardedBy("mUidRulesFirstLock")
- private boolean isWhitelistedFromPowerSaveUL(int uid, boolean deviceIdleMode) {
+ private boolean isAllowlistedFromPowerSaveUL(int uid, boolean deviceIdleMode) {
final int appId = UserHandle.getAppId(uid);
boolean isWhitelisted = mPowerSaveTempWhitelistAppIds.get(appId)
|| mPowerSaveWhitelistAppIds.get(appId);
if (!deviceIdleMode) {
- isWhitelisted = isWhitelisted || isWhitelistedFromPowerSaveExceptIdleUL(uid);
+ isWhitelisted = isWhitelisted || isAllowlistedFromPowerSaveExceptIdleUL(uid);
}
return isWhitelisted;
}
@@ -4517,7 +4517,7 @@
* (eg: Battery Saver and app idle).
*/
@GuardedBy("mUidRulesFirstLock")
- private boolean isWhitelistedFromPowerSaveExceptIdleUL(int uid) {
+ private boolean isAllowlistedFromPowerSaveExceptIdleUL(int uid) {
final int appId = UserHandle.getAppId(uid);
return mPowerSaveWhitelistExceptIdleAppIds.get(appId);
}
@@ -4533,9 +4533,9 @@
// NOTE: since both fw_dozable and fw_powersave uses the same map
// (mPowerSaveTempWhitelistAppIds) for allowlisting, we can reuse their logic in this method.
@GuardedBy("mUidRulesFirstLock")
- private void updateRulesForWhitelistedPowerSaveUL(int uid, boolean enabled, int chain) {
+ private void updateRulesForAllowlistedPowerSaveUL(int uid, boolean enabled, int chain) {
if (enabled) {
- final boolean isWhitelisted = isWhitelistedFromPowerSaveUL(uid,
+ final boolean isWhitelisted = isAllowlistedFromPowerSaveUL(uid,
chain == FIREWALL_CHAIN_DOZABLE);
if (isWhitelisted || isUidForegroundOnRestrictPowerUL(uid)) {
setUidFirewallRuleUL(chain, uid, FIREWALL_RULE_ALLOW);
@@ -4793,7 +4793,7 @@
}
@GuardedBy("mUidRulesFirstLock")
- private void updateRulesForTempWhitelistChangeUL(int appId) {
+ private void updateRulesForTempAllowlistChangeUL(int appId) {
final List<UserInfo> users = mUserManager.getUsers();
final int numUsers = users.size();
for (int i = 0; i < numUsers; i++) {
@@ -5184,7 +5184,7 @@
final boolean isForeground = isUidForegroundOnRestrictPowerUL(uid);
final boolean isTop = isUidTop(uid);
- final boolean isWhitelisted = isWhitelistedFromPowerSaveUL(uid, mDeviceIdleMode);
+ final boolean isWhitelisted = isAllowlistedFromPowerSaveUL(uid, mDeviceIdleMode);
final int oldEffectiveBlockedReasons;
final int newEffectiveBlockedReasons;
@@ -5207,9 +5207,9 @@
newAllowedReasons |= (isSystem(uid) ? ALLOWED_REASON_SYSTEM : 0);
newAllowedReasons |= (isForeground ? ALLOWED_REASON_FOREGROUND : 0);
newAllowedReasons |= (isTop ? ALLOWED_REASON_TOP : 0);
- newAllowedReasons |= (isWhitelistedFromPowerSaveUL(uid, true)
+ newAllowedReasons |= (isAllowlistedFromPowerSaveUL(uid, true)
? ALLOWED_REASON_POWER_SAVE_ALLOWLIST : 0);
- newAllowedReasons |= (isWhitelistedFromPowerSaveExceptIdleUL(uid)
+ newAllowedReasons |= (isAllowlistedFromPowerSaveExceptIdleUL(uid)
? ALLOWED_REASON_POWER_SAVE_EXCEPT_IDLE_ALLOWLIST : 0);
newAllowedReasons |= (uidBlockedState.allowedReasons
& ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS);
@@ -6122,7 +6122,7 @@
} else {
mPowerSaveTempWhitelistAppIds.delete(appId);
}
- updateRulesForTempWhitelistChangeUL(appId);
+ updateRulesForTempAllowlistChangeUL(appId);
}
}
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerShellCommand.java b/services/core/java/com/android/server/net/NetworkPolicyManagerShellCommand.java
index 47bb8f0..34c8a0d 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerShellCommand.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerShellCommand.java
@@ -154,13 +154,13 @@
}
switch(type) {
case "app-idle-whitelist":
- return listAppIdleWhitelist();
+ return listAppIdleAllowlist();
case "wifi-networks":
return listWifiNetworks();
case "restrict-background-whitelist":
- return listRestrictBackgroundWhitelist();
+ return listRestrictBackgroundAllowlist();
case "restrict-background-blacklist":
- return listRestrictBackgroundBlacklist();
+ return listRestrictBackgroundDenylist();
}
pw.println("Error: unknown list type '" + type + "'");
return -1;
@@ -175,11 +175,11 @@
}
switch(type) {
case "restrict-background-whitelist":
- return addRestrictBackgroundWhitelist();
+ return addRestrictBackgroundAllowlist();
case "restrict-background-blacklist":
- return addRestrictBackgroundBlacklist();
+ return addRestrictBackgroundDenylist();
case "app-idle-whitelist":
- return addAppIdleWhitelist();
+ return addAppIdleAllowlist();
}
pw.println("Error: unknown add type '" + type + "'");
return -1;
@@ -194,11 +194,11 @@
}
switch(type) {
case "restrict-background-whitelist":
- return removeRestrictBackgroundWhitelist();
+ return removeRestrictBackgroundAllowlist();
case "restrict-background-blacklist":
- return removeRestrictBackgroundBlacklist();
+ return removeRestrictBackgroundDenylist();
case "app-idle-whitelist":
- return removeAppIdleWhitelist();
+ return removeAppIdleAllowlist();
}
pw.println("Error: unknown remove type '" + type + "'");
return -1;
@@ -241,17 +241,17 @@
return 0;
}
- private int listRestrictBackgroundWhitelist() throws RemoteException {
+ private int listRestrictBackgroundAllowlist() throws RemoteException {
return listUidPolicies("Restrict background whitelisted UIDs",
POLICY_ALLOW_METERED_BACKGROUND);
}
- private int listRestrictBackgroundBlacklist() throws RemoteException {
+ private int listRestrictBackgroundDenylist() throws RemoteException {
return listUidPolicies("Restrict background blacklisted UIDs",
POLICY_REJECT_METERED_BACKGROUND);
}
- private int listAppIdleWhitelist() throws RemoteException {
+ private int listAppIdleAllowlist() throws RemoteException {
final PrintWriter pw = getOutPrintWriter();
final int[] uids = mInterface.getAppIdleWhitelist();
return listUidList("App Idle whitelisted UIDs", uids);
@@ -311,23 +311,23 @@
return 0;
}
- private int addRestrictBackgroundWhitelist() throws RemoteException {
+ private int addRestrictBackgroundAllowlist() throws RemoteException {
return setUidPolicy(POLICY_ALLOW_METERED_BACKGROUND);
}
- private int removeRestrictBackgroundWhitelist() throws RemoteException {
+ private int removeRestrictBackgroundAllowlist() throws RemoteException {
return resetUidPolicy("not whitelisted", POLICY_ALLOW_METERED_BACKGROUND);
}
- private int addRestrictBackgroundBlacklist() throws RemoteException {
+ private int addRestrictBackgroundDenylist() throws RemoteException {
return setUidPolicy(POLICY_REJECT_METERED_BACKGROUND);
}
- private int removeRestrictBackgroundBlacklist() throws RemoteException {
+ private int removeRestrictBackgroundDenylist() throws RemoteException {
return resetUidPolicy("not blacklisted", POLICY_REJECT_METERED_BACKGROUND);
}
- private int setAppIdleWhitelist(boolean isWhitelisted) {
+ private int setAppIdleAllowlist(boolean isWhitelisted) {
final int uid = getUidFromNextArg();
if (uid < 0) {
return uid;
@@ -336,12 +336,12 @@
return 0;
}
- private int addAppIdleWhitelist() throws RemoteException {
- return setAppIdleWhitelist(true);
+ private int addAppIdleAllowlist() throws RemoteException {
+ return setAppIdleAllowlist(true);
}
- private int removeAppIdleWhitelist() throws RemoteException {
- return setAppIdleWhitelist(false);
+ private int removeAppIdleAllowlist() throws RemoteException {
+ return setAppIdleAllowlist(false);
}
private int listWifiNetworks() {
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 15a8c0f..c24e729 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -1194,7 +1194,9 @@
mNotificationRecordLogger.log(
NotificationRecordLogger.NotificationEvent.fromAction(actionIndex,
generatedByAssistant, action.isContextual()), r);
- EventLogTags.writeNotificationActionClicked(key, actionIndex,
+ EventLogTags.writeNotificationActionClicked(key,
+ action.actionIntent.getTarget().toString(),
+ action.actionIntent.getIntent().toString(), actionIndex,
r.getLifespanMs(now), r.getFreshnessMs(now), r.getExposureMs(now),
nv.rank, nv.count);
nv.recycle();
diff --git a/services/core/java/com/android/server/pm/DexOptHelper.java b/services/core/java/com/android/server/pm/DexOptHelper.java
index 39cd888..8bd2982 100644
--- a/services/core/java/com/android/server/pm/DexOptHelper.java
+++ b/services/core/java/com/android/server/pm/DexOptHelper.java
@@ -1050,7 +1050,7 @@
context.unregisterReceiver(this);
artManager.scheduleBackgroundDexoptJob();
}
- }, new IntentFilter(Intent.ACTION_BOOT_COMPLETED));
+ }, new IntentFilter(Intent.ACTION_LOCKED_BOOT_COMPLETED));
}
/**
diff --git a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java
index 1567af0..189eb20 100644
--- a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java
+++ b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java
@@ -3055,7 +3055,7 @@
*
* TODO(b/155513789): Remove this in favor of collecting certificates during the original parse
* call if requested. Leaving this as an optional method for the caller means we have to
- * construct a dummy ParseInput.
+ * construct a placeholder ParseInput.
*/
@CheckResult
public static ParseResult<SigningDetails> getSigningDetails(ParseInput input,
diff --git a/services/core/java/com/android/server/utils/quota/CountQuotaTracker.java b/services/core/java/com/android/server/utils/quota/CountQuotaTracker.java
index 9bf046c..3b930f7 100644
--- a/services/core/java/com/android/server/utils/quota/CountQuotaTracker.java
+++ b/services/core/java/com/android/server/utils/quota/CountQuotaTracker.java
@@ -28,6 +28,7 @@
import android.os.Looper;
import android.os.Message;
import android.util.ArrayMap;
+import android.util.IndentingPrintWriter;
import android.util.LongArrayQueue;
import android.util.Slog;
import android.util.TimeUtils;
@@ -36,7 +37,6 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.IndentingPrintWriter;
import java.util.function.Consumer;
import java.util.function.Function;
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index d0f86c0..71502c6 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -4375,7 +4375,6 @@
// Reset the last saved PiP snap fraction on removal.
mDisplayContent.mPinnedTaskController.onActivityHidden(mActivityComponent);
mDisplayContent.onRunningActivityChanged();
- mWmService.mEmbeddedWindowController.onActivityRemoved(this);
mRemovingFromDisplay = false;
}
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index fcf6587..ff2c719 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -2596,9 +2596,6 @@
final int callingUid = Binder.getCallingUid();
final long ident = Binder.clearCallingIdentity();
try {
- // When a task is locked, dismiss the root pinned task if it exists
- mRootWindowContainer.removeRootTasksInWindowingModes(WINDOWING_MODE_PINNED);
-
getLockTaskController().startLockTaskMode(task, isSystemCaller, callingUid);
} finally {
Binder.restoreCallingIdentity(ident);
diff --git a/services/core/java/com/android/server/wm/AsyncRotationController.java b/services/core/java/com/android/server/wm/AsyncRotationController.java
index 2eceecc..0250475 100644
--- a/services/core/java/com/android/server/wm/AsyncRotationController.java
+++ b/services/core/java/com/android/server/wm/AsyncRotationController.java
@@ -172,10 +172,9 @@
if (recents != null && recents.isNavigationBarAttachedToApp()) {
return;
}
- } else if (navigationBarCanMove || mTransitionOp == OP_CHANGE_MAY_SEAMLESS) {
+ } else if (navigationBarCanMove || mTransitionOp == OP_CHANGE_MAY_SEAMLESS
+ || mDisplayContent.mTransitionController.mNavigationBarAttachedToApp) {
action = Operation.ACTION_SEAMLESS;
- } else if (mDisplayContent.mTransitionController.mNavigationBarAttachedToApp) {
- return;
}
mTargetWindowTokens.put(w.mToken, new Operation(action));
return;
@@ -294,6 +293,11 @@
finishOp(mTargetWindowTokens.keyAt(i));
}
mTargetWindowTokens.clear();
+ onAllCompleted();
+ }
+
+ private void onAllCompleted() {
+ if (DEBUG) Slog.d(TAG, "onAllCompleted");
if (mTimeoutRunnable != null) {
mService.mH.removeCallbacks(mTimeoutRunnable);
}
@@ -333,7 +337,7 @@
if (DEBUG) Slog.d(TAG, "Complete directly " + token.getTopChild());
finishOp(token);
if (mTargetWindowTokens.isEmpty()) {
- if (mTimeoutRunnable != null) mService.mH.removeCallbacks(mTimeoutRunnable);
+ onAllCompleted();
return true;
}
}
@@ -411,14 +415,18 @@
if (mDisplayContent.mInputMethodWindow == null) return;
final WindowToken imeWindowToken = mDisplayContent.mInputMethodWindow.mToken;
if (isTargetToken(imeWindowToken)) return;
+ hideImmediately(imeWindowToken, Operation.ACTION_TOGGLE_IME);
+ if (DEBUG) Slog.d(TAG, "hideImeImmediately " + imeWindowToken.getTopChild());
+ }
+
+ private void hideImmediately(WindowToken token, @Operation.Action int action) {
final boolean original = mHideImmediately;
mHideImmediately = true;
- final Operation op = new Operation(Operation.ACTION_TOGGLE_IME);
- mTargetWindowTokens.put(imeWindowToken, op);
- fadeWindowToken(false /* show */, imeWindowToken, ANIMATION_TYPE_TOKEN_TRANSFORM);
- op.mLeash = imeWindowToken.getAnimationLeash();
+ final Operation op = new Operation(action);
+ mTargetWindowTokens.put(token, op);
+ fadeWindowToken(false /* show */, token, ANIMATION_TYPE_TOKEN_TRANSFORM);
+ op.mLeash = token.getAnimationLeash();
mHideImmediately = original;
- if (DEBUG) Slog.d(TAG, "hideImeImmediately " + imeWindowToken.getTopChild());
}
/** Returns {@code true} if the window will rotate independently. */
@@ -428,11 +436,20 @@
|| isTargetToken(w.mToken);
}
- /** Returns {@code true} if the controller will run fade animations on the window. */
+ /**
+ * Returns {@code true} if the rotation transition appearance of the window is currently
+ * managed by this controller.
+ */
boolean isTargetToken(WindowToken token) {
return mTargetWindowTokens.containsKey(token);
}
+ /** Returns {@code true} if the controller will run fade animations on the window. */
+ boolean hasFadeOperation(WindowToken token) {
+ final Operation op = mTargetWindowTokens.get(token);
+ return op != null && op.mAction == Operation.ACTION_FADE;
+ }
+
/**
* Whether the insets animation leash should use previous position when running fade animation
* or seamless transformation in a rotated display.
@@ -564,7 +581,18 @@
return false;
}
final Operation op = mTargetWindowTokens.get(w.mToken);
- if (op == null) return false;
+ if (op == null) {
+ // If a window becomes visible after the rotation transition is requested but before
+ // the transition is ready, hide it by an animation leash so it won't be flickering
+ // by drawing the rotated content before applying projection transaction of display.
+ // And it will fade in after the display transition is finished.
+ if (mTransitionOp == OP_APP_SWITCH && !mIsStartTransactionCommitted
+ && canBeAsync(w.mToken)) {
+ hideImmediately(w.mToken, Operation.ACTION_FADE);
+ if (DEBUG) Slog.d(TAG, "Hide on finishDrawing " + w.mToken.getTopChild());
+ }
+ return false;
+ }
if (DEBUG) Slog.d(TAG, "handleFinishDrawing " + w);
if (postDrawTransaction == null || !mIsSyncDrawRequested
|| canDrawBeforeStartTransaction(op)) {
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 81750055..6499c8c 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -6499,6 +6499,13 @@
}
/**
+ * @return whether the physical display has a fixed orientation and cannot be rotated.
+ */
+ boolean isDisplayOrientationFixed() {
+ return (mDisplayInfo.flags & Display.FLAG_ROTATES_WITH_CONTENT) == 0;
+ }
+
+ /**
* @return whether AOD is showing on this display
*/
boolean isAodShowing() {
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
index ed3fad0..94df77a5 100644
--- a/services/core/java/com/android/server/wm/DisplayRotation.java
+++ b/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -434,7 +434,8 @@
final boolean isTv = mContext.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_LEANBACK);
mDefaultFixedToUserRotation =
- (isCar || isTv || mService.mIsPc || mDisplayContent.forceDesktopMode())
+ (isCar || isTv || mService.mIsPc || mDisplayContent.forceDesktopMode()
+ || mDisplayContent.isDisplayOrientationFixed())
// For debug purposes the next line turns this feature off with:
// $ adb shell setprop config.override_forced_orient true
// $ adb shell wm size reset
diff --git a/services/core/java/com/android/server/wm/EmbeddedWindowController.java b/services/core/java/com/android/server/wm/EmbeddedWindowController.java
index 98027bb..c9bae12 100644
--- a/services/core/java/com/android/server/wm/EmbeddedWindowController.java
+++ b/services/core/java/com/android/server/wm/EmbeddedWindowController.java
@@ -135,19 +135,6 @@
return mWindowsByWindowToken.get(windowToken);
}
- void onActivityRemoved(ActivityRecord activityRecord) {
- for (int i = mWindows.size() - 1; i >= 0; i--) {
- final EmbeddedWindow window = mWindows.valueAt(i);
- if (window.mHostActivityRecord == activityRecord) {
- final WindowProcessController processController =
- mAtmService.getProcessController(window.mOwnerPid, window.mOwnerUid);
- if (processController != null) {
- processController.removeHostActivity(activityRecord);
- }
- }
- }
- }
-
static class EmbeddedWindow implements InputTarget {
final IWindow mClient;
@Nullable final WindowState mHostWindowState;
@@ -230,6 +217,13 @@
mInputChannel.dispose();
mInputChannel = null;
}
+ if (mHostActivityRecord != null) {
+ final WindowProcessController wpc =
+ mWmService.mAtmService.getProcessController(mOwnerPid, mOwnerUid);
+ if (wpc != null) {
+ wpc.removeHostActivity(mHostActivityRecord);
+ }
+ }
}
@Override
diff --git a/services/core/java/com/android/server/wm/LockTaskController.java b/services/core/java/com/android/server/wm/LockTaskController.java
index 0c98fb5..830f785 100644
--- a/services/core/java/com/android/server/wm/LockTaskController.java
+++ b/services/core/java/com/android/server/wm/LockTaskController.java
@@ -19,6 +19,7 @@
import static android.app.ActivityManager.LOCK_TASK_MODE_LOCKED;
import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
import static android.app.ActivityManager.LOCK_TASK_MODE_PINNED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.content.Context.DEVICE_POLICY_SERVICE;
import static android.content.Context.STATUS_BAR_SERVICE;
@@ -669,6 +670,9 @@
}
}
+ // When a task is locked, dismiss the root pinned task if it exists
+ mSupervisor.mRootWindowContainer.removeRootTasksInWindowingModes(WINDOWING_MODE_PINNED);
+
// System can only initiate screen pinning, not full lock task mode
ProtoLog.w(WM_DEBUG_LOCKTASK, "%s", isSystemCaller ? "Locking pinned" : "Locking fully");
setLockTaskMode(task, isSystemCaller ? LOCK_TASK_MODE_PINNED : LOCK_TASK_MODE_LOCKED,
diff --git a/services/core/java/com/android/server/wm/NavBarFadeAnimationController.java b/services/core/java/com/android/server/wm/NavBarFadeAnimationController.java
index 2e5474e..79b26d2 100644
--- a/services/core/java/com/android/server/wm/NavBarFadeAnimationController.java
+++ b/services/core/java/com/android/server/wm/NavBarFadeAnimationController.java
@@ -86,7 +86,7 @@
ANIMATION_TYPE_TOKEN_TRANSFORM);
if (controller == null) {
fadeAnim.run();
- } else if (!controller.isTargetToken(mNavigationBar.mToken)) {
+ } else if (!controller.hasFadeOperation(mNavigationBar.mToken)) {
// If fade rotation animation is running and the nav bar is not controlled by it:
// - For fade-in animation, defer the animation until fade rotation animation finishes.
// - For fade-out animation, just play the animation.
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index f1fb17b..44632c9 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -1930,11 +1930,6 @@
break;
}
- final AsyncRotationController asyncRotationController = dc.getAsyncRotationController();
- if (asyncRotationController != null) {
- asyncRotationController.accept(navWindow);
- }
-
if (animate) {
final NavBarFadeAnimationController controller =
new NavBarFadeAnimationController(dc);
diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java
index 48cca32..5b466a0 100644
--- a/services/core/java/com/android/server/wm/TransitionController.java
+++ b/services/core/java/com/android/server/wm/TransitionController.java
@@ -1124,14 +1124,15 @@
+ "track #%d", transition.getSyncId(), track);
}
}
- if (sync) {
+ transition.mAnimationTrack = track;
+ info.setTrack(track);
+ mTrackCount = Math.max(mTrackCount, track + 1);
+ if (sync && mTrackCount > 1) {
+ // If there are >1 tracks, mark as sync so that all tracks finish.
info.setFlags(info.getFlags() | TransitionInfo.FLAG_SYNC);
ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Marking #%d animation as SYNC.",
transition.getSyncId());
}
- transition.mAnimationTrack = track;
- info.setTrack(track);
- mTrackCount = Math.max(mTrackCount, track + 1);
}
void updateAnimatingState(SurfaceControl.Transaction t) {
diff --git a/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp b/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp
index c4583c2..98482b8 100644
--- a/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp
+++ b/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp
@@ -54,6 +54,9 @@
using android::meminfo::ProcMemInfo;
using namespace android::meminfo;
+static const size_t kPageSize = getpagesize();
+static const size_t kPageMask = ~(kPageSize - 1);
+
#define COMPACT_ACTION_FILE_FLAG 1
#define COMPACT_ACTION_ANON_FLAG 2
@@ -64,7 +67,7 @@
#define ASYNC_RECEIVED_WHILE_FROZEN (2)
#define TXNS_PENDING_WHILE_FROZEN (4)
-#define MAX_RW_COUNT (INT_MAX & PAGE_MASK)
+#define MAX_RW_COUNT (INT_MAX & kPageMask)
// Defines the maximum amount of VMAs we can send per process_madvise syscall.
// Currently this is set to UIO_MAXIOV which is the maximum segments allowed by
@@ -233,7 +236,6 @@
// process_madvise on failure
int madviseVmasFromBatch(unique_fd& pidfd, VmaBatch& batch, int madviseType,
uint64_t* outBytesProcessed) {
- static const size_t kPageSize = getpagesize();
if (batch.totalVmas == 0 || batch.totalBytes == 0) {
// No VMAs in Batch, skip.
*outBytesProcessed = 0;
diff --git a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageManagerTests.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageManagerTests.java
index dc92376..ba13c99 100644
--- a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageManagerTests.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageManagerTests.java
@@ -56,7 +56,7 @@
import android.os.RemoteException;
import android.os.StatFs;
import android.os.SystemClock;
-import android.platform.test.annotations.Presubmit;
+import android.platform.test.annotations.Postsubmit;
import android.provider.DeviceConfig;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
@@ -93,7 +93,7 @@
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;
-@Presubmit
+@Postsubmit
public class PackageManagerTests extends AndroidTestCase {
private static final boolean localLOGV = true;
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceTest.java
new file mode 100644
index 0000000..4fd8f26
--- /dev/null
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceTest.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.display;
+
+import static android.view.Surface.ROTATION_0;
+import static android.view.Surface.ROTATION_180;
+import static android.view.Surface.ROTATION_270;
+import static android.view.Surface.ROTATION_90;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.platform.test.annotations.Presubmit;
+import android.view.SurfaceControl;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Tests for the {@link DisplayDevice} class.
+ *
+ * Build/Install/Run:
+ * atest DisplayServicesTests:DisplayDeviceTest
+ */
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class DisplayDeviceTest {
+ private final DisplayDeviceInfo mDisplayDeviceInfo = new DisplayDeviceInfo();
+ private static final int WIDTH = 500;
+ private static final int HEIGHT = 900;
+ private static final Point PORTRAIT_SIZE = new Point(WIDTH, HEIGHT);
+ private static final Point LANDSCAPE_SIZE = new Point(HEIGHT, WIDTH);
+
+ @Mock
+ private SurfaceControl.Transaction mMockTransaction;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ mDisplayDeviceInfo.width = WIDTH;
+ mDisplayDeviceInfo.height = HEIGHT;
+ mDisplayDeviceInfo.rotation = ROTATION_0;
+ }
+
+ @Test
+ public void testGetDisplaySurfaceDefaultSizeLocked_notRotated() {
+ DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo);
+ assertThat(displayDevice.getDisplaySurfaceDefaultSizeLocked()).isEqualTo(PORTRAIT_SIZE);
+ }
+
+ @Test
+ public void testGetDisplaySurfaceDefaultSizeLocked_rotation0() {
+ DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo);
+ displayDevice.setProjectionLocked(mMockTransaction, ROTATION_0, new Rect(), new Rect());
+ assertThat(displayDevice.getDisplaySurfaceDefaultSizeLocked()).isEqualTo(PORTRAIT_SIZE);
+ }
+
+ @Test
+ public void testGetDisplaySurfaceDefaultSizeLocked_rotation90() {
+ DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo);
+ displayDevice.setProjectionLocked(mMockTransaction, ROTATION_90, new Rect(), new Rect());
+ assertThat(displayDevice.getDisplaySurfaceDefaultSizeLocked()).isEqualTo(LANDSCAPE_SIZE);
+ }
+
+ @Test
+ public void testGetDisplaySurfaceDefaultSizeLocked_rotation180() {
+ DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo);
+ displayDevice.setProjectionLocked(mMockTransaction, ROTATION_180, new Rect(), new Rect());
+ assertThat(displayDevice.getDisplaySurfaceDefaultSizeLocked()).isEqualTo(PORTRAIT_SIZE);
+ }
+
+ @Test
+ public void testGetDisplaySurfaceDefaultSizeLocked_rotation270() {
+ DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo);
+ displayDevice.setProjectionLocked(mMockTransaction, ROTATION_270, new Rect(), new Rect());
+ assertThat(displayDevice.getDisplaySurfaceDefaultSizeLocked()).isEqualTo(LANDSCAPE_SIZE);
+ }
+
+ private static class FakeDisplayDevice extends DisplayDevice {
+ private final DisplayDeviceInfo mDisplayDeviceInfo;
+
+ FakeDisplayDevice(DisplayDeviceInfo displayDeviceInfo) {
+ super(null, null, "", InstrumentationRegistry.getInstrumentation().getContext());
+ mDisplayDeviceInfo = displayDeviceInfo;
+ }
+
+ @Override
+ public boolean hasStableUniqueId() {
+ return false;
+ }
+
+ @Override
+ public DisplayDeviceInfo getDisplayDeviceInfoLocked() {
+ return mDisplayDeviceInfo;
+ }
+ }
+}
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
index d16c9c5..50cf169 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
@@ -477,6 +477,41 @@
}
@Test
+ public void testCreateVirtualRotatesWithContent() throws RemoteException {
+ DisplayManagerService displayManager =
+ new DisplayManagerService(mContext, mBasicInjector);
+ registerDefaultDisplays(displayManager);
+
+ // This is effectively the DisplayManager service published to ServiceManager.
+ DisplayManagerService.BinderService bs = displayManager.new BinderService();
+
+ String uniqueId = "uniqueId --- Rotates with Content Test";
+ int width = 600;
+ int height = 800;
+ int dpi = 320;
+ int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT;
+
+ when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
+ final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(
+ VIRTUAL_DISPLAY_NAME, width, height, dpi);
+ builder.setFlags(flags);
+ builder.setUniqueId(uniqueId);
+ int displayId = bs.createVirtualDisplay(builder.build(), /* callback= */ mMockAppToken,
+ /* projection= */ null, PACKAGE_NAME);
+ verify(mMockProjectionService, never()).setContentRecordingSession(any(),
+ nullable(IMediaProjection.class));
+
+ displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class));
+
+ // flush the handler
+ displayManager.getDisplayHandler().runWithScissors(() -> {}, /* now= */ 0);
+
+ DisplayDeviceInfo ddi = displayManager.getDisplayDeviceInfoInternal(displayId);
+ assertNotNull(ddi);
+ assertTrue((ddi.flags & DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT) != 0);
+ }
+
+ @Test
public void testCreateVirtualDisplayOwnFocus() throws RemoteException {
DisplayManagerService displayManager =
new DisplayManagerService(mContext, mBasicInjector);
diff --git a/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayTest.java b/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayTest.java
index 2065479..c0128ae 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayTest.java
@@ -69,7 +69,6 @@
mDisplayDeviceInfo.copyFrom(new DisplayDeviceInfo());
mDisplayDeviceInfo.width = DISPLAY_WIDTH;
mDisplayDeviceInfo.height = DISPLAY_HEIGHT;
- mDisplayDeviceInfo.flags = DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT;
mDisplayDeviceInfo.touch = DisplayDeviceInfo.TOUCH_INTERNAL;
mDisplayDeviceInfo.modeId = MODE_ID;
mDisplayDeviceInfo.supportedModes = new Display.Mode[] {new Display.Mode(MODE_ID,
@@ -112,8 +111,18 @@
mLogicalDisplay.configureDisplayLocked(t, mDisplayDevice, false);
assertEquals(expectedPosition, mLogicalDisplay.getDisplayPosition());
- expectedPosition.set(40, -20);
DisplayInfo displayInfo = new DisplayInfo();
+ displayInfo.logicalWidth = DISPLAY_WIDTH;
+ displayInfo.logicalHeight = DISPLAY_HEIGHT;
+ // Rotation doesn't matter when the FLAG_ROTATES_WITH_CONTENT is absent.
+ displayInfo.rotation = Surface.ROTATION_90;
+ mLogicalDisplay.setDisplayInfoOverrideFromWindowManagerLocked(displayInfo);
+ mLogicalDisplay.configureDisplayLocked(t, mDisplayDevice, false);
+ assertEquals(expectedPosition, mLogicalDisplay.getDisplayPosition());
+
+ expectedPosition.set(40, -20);
+ mDisplayDeviceInfo.flags = DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT;
+ mLogicalDisplay.updateLocked(mDeviceRepo);
displayInfo.logicalWidth = DISPLAY_HEIGHT;
displayInfo.logicalHeight = DISPLAY_WIDTH;
displayInfo.rotation = Surface.ROTATION_90;
diff --git a/services/tests/servicestests/src/com/android/server/CertBlacklisterTest.java b/services/tests/servicestests/src/com/android/server/CertBlacklisterTest.java
index 90df786..45e7f35 100644
--- a/services/tests/servicestests/src/com/android/server/CertBlacklisterTest.java
+++ b/services/tests/servicestests/src/com/android/server/CertBlacklisterTest.java
@@ -34,10 +34,10 @@
*/
public class CertBlacklisterTest extends AndroidTestCase {
- private static final String BLACKLIST_ROOT = System.getenv("ANDROID_DATA") + "/misc/keychain/";
+ private static final String DENYLIST_ROOT = System.getenv("ANDROID_DATA") + "/misc/keychain/";
- public static final String PUBKEY_PATH = BLACKLIST_ROOT + "pubkey_blacklist.txt";
- public static final String SERIAL_PATH = BLACKLIST_ROOT + "serial_blacklist.txt";
+ public static final String PUBKEY_PATH = DENYLIST_ROOT + "pubkey_blacklist.txt";
+ public static final String SERIAL_PATH = DENYLIST_ROOT + "serial_blacklist.txt";
public static final String PUBKEY_KEY = "pubkey_blacklist";
public static final String SERIAL_KEY = "serial_blacklist";
diff --git a/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java b/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java
index 9ca84d3..ce15c6d 100644
--- a/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java
@@ -218,7 +218,7 @@
@Test
public void updateRuleSet_notSystemApp() throws Exception {
- whitelistUsAsRuleProvider();
+ allowlistUsAsRuleProvider();
makeUsSystemApp(false);
Rule rule =
new Rule(
@@ -237,7 +237,7 @@
@Test
public void updateRuleSet_authorized() throws Exception {
- whitelistUsAsRuleProvider();
+ allowlistUsAsRuleProvider();
makeUsSystemApp();
Rule rule =
new Rule(
@@ -251,7 +251,7 @@
@Test
public void updateRuleSet_correctMethodCall() throws Exception {
- whitelistUsAsRuleProvider();
+ allowlistUsAsRuleProvider();
makeUsSystemApp();
IntentSender mockReceiver = mock(IntentSender.class);
List<Rule> rules =
@@ -271,7 +271,7 @@
@Test
public void updateRuleSet_fail() throws Exception {
- whitelistUsAsRuleProvider();
+ allowlistUsAsRuleProvider();
makeUsSystemApp();
doThrow(new IOException()).when(mIntegrityFileManager).writeRules(any(), any(), any());
IntentSender mockReceiver = mock(IntentSender.class);
@@ -292,7 +292,7 @@
@Test
public void broadcastReceiverRegistration() throws Exception {
- whitelistUsAsRuleProvider();
+ allowlistUsAsRuleProvider();
makeUsSystemApp();
ArgumentCaptor<IntentFilter> intentFilterCaptor =
ArgumentCaptor.forClass(IntentFilter.class);
@@ -308,7 +308,7 @@
@Test
public void handleBroadcast_correctArgs() throws Exception {
- whitelistUsAsRuleProvider();
+ allowlistUsAsRuleProvider();
makeUsSystemApp();
ArgumentCaptor<BroadcastReceiver> broadcastReceiverCaptor =
ArgumentCaptor.forClass(BroadcastReceiver.class);
@@ -345,7 +345,7 @@
@Test
public void handleBroadcast_correctArgs_multipleCerts() throws Exception {
- whitelistUsAsRuleProvider();
+ allowlistUsAsRuleProvider();
makeUsSystemApp();
ArgumentCaptor<BroadcastReceiver> broadcastReceiverCaptor =
ArgumentCaptor.forClass(BroadcastReceiver.class);
@@ -368,7 +368,7 @@
@Test
public void handleBroadcast_correctArgs_sourceStamp() throws Exception {
- whitelistUsAsRuleProvider();
+ allowlistUsAsRuleProvider();
makeUsSystemApp();
ArgumentCaptor<BroadcastReceiver> broadcastReceiverCaptor =
ArgumentCaptor.forClass(BroadcastReceiver.class);
@@ -393,7 +393,7 @@
@Test
public void handleBroadcast_allow() throws Exception {
- whitelistUsAsRuleProvider();
+ allowlistUsAsRuleProvider();
makeUsSystemApp();
ArgumentCaptor<BroadcastReceiver> broadcastReceiverCaptor =
ArgumentCaptor.forClass(BroadcastReceiver.class);
@@ -412,7 +412,7 @@
@Test
public void handleBroadcast_reject() throws Exception {
- whitelistUsAsRuleProvider();
+ allowlistUsAsRuleProvider();
makeUsSystemApp();
ArgumentCaptor<BroadcastReceiver> broadcastReceiverCaptor =
ArgumentCaptor.forClass(BroadcastReceiver.class);
@@ -438,7 +438,7 @@
@Test
public void handleBroadcast_notInitialized() throws Exception {
- whitelistUsAsRuleProvider();
+ allowlistUsAsRuleProvider();
makeUsSystemApp();
when(mIntegrityFileManager.initialized()).thenReturn(false);
ArgumentCaptor<BroadcastReceiver> broadcastReceiverCaptor =
@@ -459,7 +459,7 @@
@Test
public void verifierAsInstaller_skipIntegrityVerification() throws Exception {
- whitelistUsAsRuleProvider();
+ allowlistUsAsRuleProvider();
makeUsSystemApp();
setIntegrityCheckIncludesRuleProvider(false);
ArgumentCaptor<BroadcastReceiver> broadcastReceiverCaptor =
@@ -480,7 +480,7 @@
@Test
public void getCurrentRules() throws Exception {
- whitelistUsAsRuleProvider();
+ allowlistUsAsRuleProvider();
makeUsSystemApp();
Rule rule = new Rule(IntegrityFormula.Application.packageNameEquals("package"), Rule.DENY);
when(mIntegrityFileManager.readRules(any())).thenReturn(Arrays.asList(rule));
@@ -490,7 +490,7 @@
@Test
public void getWhitelistedRuleProviders_returnsEmptyForNonSystemApps() throws Exception {
- whitelistUsAsRuleProvider();
+ allowlistUsAsRuleProvider();
makeUsSystemApp(false);
assertThat(mService.getWhitelistedRuleProviders()).isEmpty();
@@ -498,13 +498,13 @@
@Test
public void getWhitelistedRuleProviders() throws Exception {
- whitelistUsAsRuleProvider();
+ allowlistUsAsRuleProvider();
makeUsSystemApp();
assertThat(mService.getWhitelistedRuleProviders()).containsExactly(TEST_FRAMEWORK_PACKAGE);
}
- private void whitelistUsAsRuleProvider() {
+ private void allowlistUsAsRuleProvider() {
Resources mockResources = mock(Resources.class);
when(mockResources.getStringArray(R.array.config_integrityRuleProviderPackages))
.thenReturn(new String[] {TEST_FRAMEWORK_PACKAGE});
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/KeySyncTaskTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/KeySyncTaskTest.java
index cc1100b..5654c89 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/KeySyncTaskTest.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/KeySyncTaskTest.java
@@ -469,7 +469,7 @@
verify(mTestOnlyInsecureCertificateHelper, atLeast(1))
.isTestOnlyCertificateAlias(eq(TEST_ROOT_CERT_ALIAS));
- // no whitelists check
+ // no allowlists check
verify(mTestOnlyInsecureCertificateHelper, never())
.doesCredentialSupportInsecureMode(anyInt(), any());
verify(mTestOnlyInsecureCertificateHelper, never())
diff --git a/services/tests/servicestests/src/com/android/server/os/BugreportManagerServiceImplTest.java b/services/tests/servicestests/src/com/android/server/os/BugreportManagerServiceImplTest.java
index 24029b1..fc27edc 100644
--- a/services/tests/servicestests/src/com/android/server/os/BugreportManagerServiceImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/os/BugreportManagerServiceImplTest.java
@@ -35,6 +35,7 @@
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -68,6 +69,27 @@
mBugreportFileManager = new BugreportManagerServiceImpl.BugreportFileManager();
}
+ @After
+ public void tearDown() throws Exception {
+ // Changes to RoleManager persist between tests, so we need to clear out any funny
+ // business we did in previous tests.
+ RoleManager roleManager = mContext.getSystemService(RoleManager.class);
+ CallbackFuture future = new CallbackFuture();
+ runWithShellPermissionIdentity(
+ () -> {
+ roleManager.setBypassingRoleQualification(false);
+ roleManager.removeRoleHolderAsUser(
+ "android.app.role.SYSTEM_AUTOMOTIVE_PROJECTION",
+ mContext.getPackageName(),
+ /* flags= */ 0,
+ Process.myUserHandle(),
+ mContext.getMainExecutor(),
+ future);
+ });
+
+ assertThat(future.get()).isEqualTo(true);
+ }
+
@Test
public void testBugreportFileManagerFileExists() {
Pair<Integer, String> callingInfo = new Pair<>(mCallingUid, mCallingPackage);
@@ -131,14 +153,17 @@
new BugreportManagerServiceImpl.Injector(mContext, new ArraySet<>()));
RoleManager roleManager = mContext.getSystemService(RoleManager.class);
CallbackFuture future = new CallbackFuture();
- runWithShellPermissionIdentity(() -> roleManager.setBypassingRoleQualification(true));
- runWithShellPermissionIdentity(() -> roleManager.addRoleHolderAsUser(
- "android.app.role.SYSTEM_AUTOMOTIVE_PROJECTION",
- mContext.getPackageName(),
- /* flags= */ 0,
- Process.myUserHandle(),
- mContext.getMainExecutor(),
- future));
+ runWithShellPermissionIdentity(
+ () -> {
+ roleManager.setBypassingRoleQualification(true);
+ roleManager.addRoleHolderAsUser(
+ "android.app.role.SYSTEM_AUTOMOTIVE_PROJECTION",
+ mContext.getPackageName(),
+ /* flags= */ 0,
+ Process.myUserHandle(),
+ mContext.getMainExecutor(),
+ future);
+ });
assertThat(future.get()).isEqualTo(true);
mService.cancelBugreport(Binder.getCallingUid(), mContext.getPackageName());
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserSystemPackageInstallerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserSystemPackageInstallerTest.java
index cca924e..7798644 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserSystemPackageInstallerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserSystemPackageInstallerTest.java
@@ -117,7 +117,7 @@
for (int userId : mRemoveUsers) {
um.removeUser(userId);
}
- setUserTypePackageWhitelistMode(mOriginalWhitelistMode);
+ setUserTypePackageAllowlistMode(mOriginalWhitelistMode);
}
/**
@@ -184,7 +184,7 @@
}
}
- final ArrayMap<String, Long> expectedOutput = getNewPackageToWhitelistedBitSetMap();
+ final ArrayMap<String, Long> expectedOutput = getNewPackageToAllowlistedBitSetMap();
expectedOutput.put("com.android.package1", expectedUserTypeBitSet1);
expectedOutput.put("com.android.package2", expectedUserTypeBitSet2);
expectedOutput.put("com.android.package3", expectedUserTypeBitSet3);
@@ -227,7 +227,7 @@
}
};
- final ArrayMap<String, Long> expectedOutput = getNewPackageToWhitelistedBitSetMap();
+ final ArrayMap<String, Long> expectedOutput = getNewPackageToAllowlistedBitSetMap();
expectedOutput.put("com.android.package2", 0L);
expectedOutput.put("com.android.package3", 0L);
expectedOutput.put("com.android.package4", 0L);
@@ -340,7 +340,7 @@
public void testPackagesForCreateUser_full() {
final String userTypeToCreate = USER_TYPE_FULL_SECONDARY;
final long userTypeMask = mUserSystemPackageInstaller.getUserTypeMask(userTypeToCreate);
- setUserTypePackageWhitelistMode(USER_TYPE_PACKAGE_WHITELIST_MODE_ENFORCE);
+ setUserTypePackageAllowlistMode(USER_TYPE_PACKAGE_WHITELIST_MODE_ENFORCE);
PackageManager pm = mContext.getPackageManager();
final SystemConfig sysConfig = new SystemConfigTestClass(true);
@@ -384,7 +384,7 @@
*/
@Test
public void testInstallOverlayPackagesExplicitMode() {
- setUserTypePackageWhitelistMode(USER_TYPE_PACKAGE_WHITELIST_MODE_ENFORCE);
+ setUserTypePackageAllowlistMode(USER_TYPE_PACKAGE_WHITELIST_MODE_ENFORCE);
final String[] userTypes = new String[]{"type"};
final long maskOfType = 0b0001L;
@@ -453,49 +453,49 @@
*/
@Test
public void testSetWhitelistEnabledMode() {
- setUserTypePackageWhitelistMode(USER_TYPE_PACKAGE_WHITELIST_MODE_DISABLE);
+ setUserTypePackageAllowlistMode(USER_TYPE_PACKAGE_WHITELIST_MODE_DISABLE);
assertFalse(mUserSystemPackageInstaller.isLogMode());
assertFalse(mUserSystemPackageInstaller.isEnforceMode());
assertFalse(mUserSystemPackageInstaller.isImplicitWhitelistMode());
assertFalse(mUserSystemPackageInstaller.isImplicitWhitelistSystemMode());
assertFalse(mUserSystemPackageInstaller.isIgnoreOtaMode());
- setUserTypePackageWhitelistMode(USER_TYPE_PACKAGE_WHITELIST_MODE_LOG);
+ setUserTypePackageAllowlistMode(USER_TYPE_PACKAGE_WHITELIST_MODE_LOG);
assertTrue(mUserSystemPackageInstaller.isLogMode());
assertFalse(mUserSystemPackageInstaller.isEnforceMode());
assertFalse(mUserSystemPackageInstaller.isImplicitWhitelistMode());
assertFalse(mUserSystemPackageInstaller.isImplicitWhitelistSystemMode());
assertFalse(mUserSystemPackageInstaller.isIgnoreOtaMode());
- setUserTypePackageWhitelistMode(USER_TYPE_PACKAGE_WHITELIST_MODE_ENFORCE);
+ setUserTypePackageAllowlistMode(USER_TYPE_PACKAGE_WHITELIST_MODE_ENFORCE);
assertFalse(mUserSystemPackageInstaller.isLogMode());
assertTrue(mUserSystemPackageInstaller.isEnforceMode());
assertFalse(mUserSystemPackageInstaller.isImplicitWhitelistMode());
assertFalse(mUserSystemPackageInstaller.isImplicitWhitelistSystemMode());
assertFalse(mUserSystemPackageInstaller.isIgnoreOtaMode());
- setUserTypePackageWhitelistMode(USER_TYPE_PACKAGE_WHITELIST_MODE_IMPLICIT_WHITELIST);
+ setUserTypePackageAllowlistMode(USER_TYPE_PACKAGE_WHITELIST_MODE_IMPLICIT_WHITELIST);
assertFalse(mUserSystemPackageInstaller.isLogMode());
assertFalse(mUserSystemPackageInstaller.isEnforceMode());
assertTrue(mUserSystemPackageInstaller.isImplicitWhitelistMode());
assertFalse(mUserSystemPackageInstaller.isImplicitWhitelistSystemMode());
assertFalse(mUserSystemPackageInstaller.isIgnoreOtaMode());
- setUserTypePackageWhitelistMode(USER_TYPE_PACKAGE_WHITELIST_MODE_IMPLICIT_WHITELIST_SYSTEM);
+ setUserTypePackageAllowlistMode(USER_TYPE_PACKAGE_WHITELIST_MODE_IMPLICIT_WHITELIST_SYSTEM);
assertFalse(mUserSystemPackageInstaller.isLogMode());
assertFalse(mUserSystemPackageInstaller.isEnforceMode());
assertFalse(mUserSystemPackageInstaller.isImplicitWhitelistMode());
assertTrue(mUserSystemPackageInstaller.isImplicitWhitelistSystemMode());
assertFalse(mUserSystemPackageInstaller.isIgnoreOtaMode());
- setUserTypePackageWhitelistMode(USER_TYPE_PACKAGE_WHITELIST_MODE_IGNORE_OTA);
+ setUserTypePackageAllowlistMode(USER_TYPE_PACKAGE_WHITELIST_MODE_IGNORE_OTA);
assertFalse(mUserSystemPackageInstaller.isLogMode());
assertFalse(mUserSystemPackageInstaller.isEnforceMode());
assertFalse(mUserSystemPackageInstaller.isImplicitWhitelistMode());
assertFalse(mUserSystemPackageInstaller.isImplicitWhitelistSystemMode());
assertTrue(mUserSystemPackageInstaller.isIgnoreOtaMode());
- setUserTypePackageWhitelistMode(
+ setUserTypePackageAllowlistMode(
USER_TYPE_PACKAGE_WHITELIST_MODE_LOG | USER_TYPE_PACKAGE_WHITELIST_MODE_ENFORCE);
assertTrue(mUserSystemPackageInstaller.isLogMode());
assertTrue(mUserSystemPackageInstaller.isEnforceMode());
@@ -503,7 +503,7 @@
assertFalse(mUserSystemPackageInstaller.isImplicitWhitelistSystemMode());
assertFalse(mUserSystemPackageInstaller.isIgnoreOtaMode());
- setUserTypePackageWhitelistMode(USER_TYPE_PACKAGE_WHITELIST_MODE_IMPLICIT_WHITELIST
+ setUserTypePackageAllowlistMode(USER_TYPE_PACKAGE_WHITELIST_MODE_IMPLICIT_WHITELIST
| USER_TYPE_PACKAGE_WHITELIST_MODE_ENFORCE);
assertFalse(mUserSystemPackageInstaller.isLogMode());
assertTrue(mUserSystemPackageInstaller.isEnforceMode());
@@ -513,7 +513,7 @@
}
/** Sets the allowlist mode to the desired value via adb's setprop. */
- private void setUserTypePackageWhitelistMode(int mode) {
+ private void setUserTypePackageAllowlistMode(int mode) {
UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
try {
String result = uiDevice.executeShellCommand(String.format("setprop %s %d",
@@ -526,7 +526,7 @@
}
/** @see UserSystemPackageInstaller#mWhitelistedPackagesForUserTypes */
- private ArrayMap<String, Long> getNewPackageToWhitelistedBitSetMap() {
+ private ArrayMap<String, Long> getNewPackageToAllowlistedBitSetMap() {
final ArrayMap<String, Long> pkgBitSetMap = new ArrayMap<>();
// "android" is always treated as allowlisted for all types, regardless of the xml file.
pkgBitSetMap.put("android", ~0L);
diff --git a/services/tests/servicestests/src/com/android/server/power/hint/OWNERS b/services/tests/servicestests/src/com/android/server/power/hint/OWNERS
new file mode 100644
index 0000000..c28c07a
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/power/hint/OWNERS
@@ -0,0 +1,2 @@
+include /ADPF_OWNERS
+
diff --git a/services/tests/servicestests/utils/com/android/server/testutils/TestHandler.java b/services/tests/servicestests/utils/com/android/server/testutils/TestHandler.java
index 22d383a..fc5213c 100644
--- a/services/tests/servicestests/utils/com/android/server/testutils/TestHandler.java
+++ b/services/tests/servicestests/utils/com/android/server/testutils/TestHandler.java
@@ -82,7 +82,7 @@
uptimeMillis = uptimeMillis - SystemClock.uptimeMillis() + mClock.getAsLong();
}
- // post a dummy queue entry to keep track of message removal
+ // post a sentinel queue entry to keep track of message removal
return super.sendMessageAtTime(msg, Long.MAX_VALUE)
&& mMessages.add(new MsgInfo(Message.obtain(msg), uptimeMillis, mMessageCount));
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index bdee99b..6a6fa3f 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -6043,6 +6043,49 @@
}
@Test
+ public void testVisitUris_styleExtrasWithoutStyle() {
+ Notification notification = new Notification.Builder(mContext, "a")
+ .setSmallIcon(android.R.drawable.sym_def_app_icon)
+ .build();
+
+ Notification.MessagingStyle messagingStyle = new Notification.MessagingStyle(
+ personWithIcon("content://user"))
+ .addHistoricMessage(new Notification.MessagingStyle.Message("Heyhey!",
+ System.currentTimeMillis(),
+ personWithIcon("content://historicalMessenger")))
+ .addMessage(new Notification.MessagingStyle.Message("Are you there",
+ System.currentTimeMillis(),
+ personWithIcon("content://messenger")))
+ .setShortcutIcon(
+ Icon.createWithContentUri("content://conversationShortcut"));
+ messagingStyle.addExtras(notification.extras); // Instead of Builder.setStyle(style).
+
+ Notification.CallStyle callStyle = Notification.CallStyle.forOngoingCall(
+ personWithIcon("content://caller"),
+ PendingIntent.getActivity(mContext, 0, new Intent(),
+ PendingIntent.FLAG_IMMUTABLE))
+ .setVerificationIcon(Icon.createWithContentUri("content://callVerification"));
+ callStyle.addExtras(notification.extras); // Same.
+
+ Consumer<Uri> visitor = (Consumer<Uri>) spy(Consumer.class);
+ notification.visitUris(visitor);
+
+ verify(visitor).accept(eq(Uri.parse("content://user")));
+ verify(visitor).accept(eq(Uri.parse("content://historicalMessenger")));
+ verify(visitor).accept(eq(Uri.parse("content://messenger")));
+ verify(visitor).accept(eq(Uri.parse("content://conversationShortcut")));
+ verify(visitor).accept(eq(Uri.parse("content://caller")));
+ verify(visitor).accept(eq(Uri.parse("content://callVerification")));
+ }
+
+ private static Person personWithIcon(String iconUri) {
+ return new Person.Builder()
+ .setName("Mr " + iconUri)
+ .setIcon(Icon.createWithContentUri(iconUri))
+ .build();
+ }
+
+ @Test
public void testVisitUris_wearableExtender() {
Icon actionIcon = Icon.createWithContentUri("content://media/action");
Icon wearActionIcon = Icon.createWithContentUri("content://media/wearAction");
@@ -7752,7 +7795,8 @@
public void testOnNotificationActionClick() {
final int actionIndex = 2;
final Notification.Action action =
- new Notification.Action.Builder(null, "text", null).build();
+ new Notification.Action.Builder(null, "text", PendingIntent.getActivity(
+ mContext, 0, new Intent(), PendingIntent.FLAG_IMMUTABLE)).build();
final boolean generatedByAssistant = false;
NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
@@ -7776,7 +7820,8 @@
public void testOnAssistantNotificationActionClick() {
final int actionIndex = 1;
final Notification.Action action =
- new Notification.Action.Builder(null, "text", null).build();
+ new Notification.Action.Builder(null, "text", PendingIntent.getActivity(
+ mContext, 0, new Intent(), PendingIntent.FLAG_IMMUTABLE)).build();
final boolean generatedByAssistant = true;
NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java
index f757330..1617093 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java
@@ -1176,6 +1176,15 @@
+ " fixed to user rotation.", mTarget.isFixedToUserRotation());
}
+ @Test
+ public void testIsFixedToUserRotation_displayContentOrientationFixed() throws Exception {
+ mBuilder.build();
+ when(mMockDisplayContent.isDisplayOrientationFixed()).thenReturn(true);
+
+ assertFalse("Display rotation should respect app requested orientation if"
+ + " the display has fixed orientation.", mTarget.isFixedToUserRotation());
+ }
+
private void moveTimeForward(long timeMillis) {
sCurrentUptimeMillis += timeMillis;
sClock.fastForward(timeMillis);
diff --git a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
index b4f1176..7544fda 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
@@ -39,6 +39,7 @@
import static android.window.TransitionInfo.FLAG_IS_WALLPAPER;
import static android.window.TransitionInfo.FLAG_MOVED_TO_TOP;
import static android.window.TransitionInfo.FLAG_SHOW_WALLPAPER;
+import static android.window.TransitionInfo.FLAG_SYNC;
import static android.window.TransitionInfo.FLAG_TRANSLUCENT;
import static android.window.TransitionInfo.isIndependent;
@@ -1186,6 +1187,7 @@
final WindowState statusBar = createWindow(null, TYPE_STATUS_BAR, "statusBar");
makeWindowVisible(statusBar);
mDisplayContent.getDisplayPolicy().addWindowLw(statusBar, statusBar.mAttrs);
+ final WindowState navBar = createWindow(null, TYPE_NAVIGATION_BAR, "navBar");
final ActivityRecord app = createActivityRecord(mDisplayContent);
final Transition transition = app.mTransitionController.createTransition(TRANSIT_OPEN);
app.mTransitionController.requestStartTransition(transition, app.getTask(),
@@ -1215,9 +1217,17 @@
mDisplayContent.mTransitionController.dispatchLegacyAppTransitionFinished(app);
assertTrue(mDisplayContent.hasTopFixedRotationLaunchingApp());
+ // The bar was invisible so it is not handled by the controller. But if it becomes visible
+ // and drawn before the transition starts,
+ assertFalse(asyncRotationController.isTargetToken(navBar.mToken));
+ navBar.finishDrawing(null /* postDrawTransaction */, Integer.MAX_VALUE);
+ assertTrue(asyncRotationController.isTargetToken(navBar.mToken));
+
player.startTransition();
// Non-app windows should not be collected.
assertFalse(mDisplayContent.mTransitionController.isCollecting(statusBar.mToken));
+ // Avoid DeviceStateController disturbing the test by triggering another rotation change.
+ doReturn(false).when(mDisplayContent).updateRotationUnchecked();
onRotationTransactionReady(player, mWm.mTransactionFactory.get()).onTransactionCommitted();
assertEquals(ROTATION_ANIMATION_SEAMLESS, player.mLastReady.getChange(
@@ -2384,6 +2394,37 @@
assertFalse(controller.isCollecting());
}
+ @Test
+ public void testNoSyncFlagIfOneTrack() {
+ final TransitionController controller = mAtm.getTransitionController();
+ final TestTransitionPlayer player = registerTestTransitionPlayer();
+
+ mSyncEngine = createTestBLASTSyncEngine();
+ controller.setSyncEngine(mSyncEngine);
+
+ final Transition transitA = createTestTransition(TRANSIT_OPEN, controller);
+ final Transition transitB = createTestTransition(TRANSIT_OPEN, controller);
+ final Transition transitC = createTestTransition(TRANSIT_OPEN, controller);
+
+ controller.startCollectOrQueue(transitA, (deferred) -> {});
+ controller.startCollectOrQueue(transitB, (deferred) -> {});
+ controller.startCollectOrQueue(transitC, (deferred) -> {});
+
+ // Verify that, as-long as there is <= 1 track, we won't get a SYNC flag
+ transitA.start();
+ transitA.setAllReady();
+ mSyncEngine.tryFinishForTest(transitA.getSyncId());
+ assertTrue((player.mLastReady.getFlags() & FLAG_SYNC) == 0);
+ transitB.start();
+ transitB.setAllReady();
+ mSyncEngine.tryFinishForTest(transitB.getSyncId());
+ assertTrue((player.mLastReady.getFlags() & FLAG_SYNC) == 0);
+ transitC.start();
+ transitC.setAllReady();
+ mSyncEngine.tryFinishForTest(transitC.getSyncId());
+ assertTrue((player.mLastReady.getFlags() & FLAG_SYNC) == 0);
+ }
+
private static void makeTaskOrganized(Task... tasks) {
final ITaskOrganizer organizer = mock(ITaskOrganizer.class);
for (Task t : tasks) {
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
index 58da4b43..3d78a1d 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
@@ -54,6 +54,7 @@
import android.service.voice.HotwordDetectionService;
import android.service.voice.HotwordDetectionServiceFailure;
import android.service.voice.HotwordDetector;
+import android.service.voice.IDetectorSessionStorageService;
import android.service.voice.IMicrophoneHotwordDetectionVoiceInteractionCallback;
import android.service.voice.ISandboxedDetectionService;
import android.service.voice.IVisualQueryDetectionVoiceInteractionCallback;
@@ -69,6 +70,7 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.app.IHotwordRecognitionStatusCallback;
import com.android.internal.app.IVisualQueryDetectionAttentionListener;
+import com.android.internal.infra.AndroidFuture;
import com.android.internal.infra.ServiceConnector;
import com.android.server.LocalServices;
import com.android.server.pm.permission.PermissionManagerServiceInternal;
@@ -157,6 +159,8 @@
@NonNull private ServiceConnection mRemoteVisualQueryDetectionService;
@GuardedBy("mLock")
@Nullable private IBinder mAudioFlinger;
+
+ @Nullable private IHotwordRecognitionStatusCallback mHotwordRecognitionCallback;
@GuardedBy("mLock")
private boolean mDebugHotwordLogging = false;
@@ -694,6 +698,7 @@
updateContentCaptureManager(connection);
updateSpeechService(connection);
updateServiceIdentity(connection);
+ updateStorageService(connection);
return connection;
}
}
@@ -910,6 +915,7 @@
mVoiceInteractionServiceUid, mVoiceInteractorIdentity,
mScheduledExecutorService, mDebugHotwordLogging, mRemoteExceptionListener);
}
+ mHotwordRecognitionCallback = callback;
mDetectorSessions.put(detectorType, session);
session.initialize(options, sharedMemory);
}
@@ -1035,6 +1041,23 @@
}));
}
+ private void updateStorageService(ServiceConnection connection) {
+ connection.run(service -> {
+ service.registerRemoteStorageService(new IDetectorSessionStorageService.Stub() {
+ @Override
+ public void openFile(String filename, AndroidFuture future)
+ throws RemoteException {
+ Slog.v(TAG, "BinderCallback#onFileOpen");
+ try {
+ mHotwordRecognitionCallback.onOpenFile(filename, future);
+ } catch (RemoteException e) {
+ e.rethrowFromSystemServer();
+ }
+ }
+ });
+ });
+ }
+
private void addServiceUidForAudioPolicy(int uid) {
mScheduledExecutorService.execute(() -> {
AudioManagerInternal audioManager =
diff --git a/telecomm/OWNERS b/telecomm/OWNERS
index dcaf858..b57b7c7 100644
--- a/telecomm/OWNERS
+++ b/telecomm/OWNERS
@@ -4,7 +4,6 @@
tgunn@google.com
xiaotonj@google.com
rgreenwalt@google.com
-chinmayd@google.com
grantmenke@google.com
pmadapurmath@google.com
tjstuart@google.com
\ No newline at end of file
diff --git a/tests/ApkVerityTest/ApkVerityTestApp/feature_split/src/com/android/apkverity/feature_x/DummyActivity.java b/tests/ApkVerityTest/ApkVerityTestApp/feature_split/src/com/android/apkverity/feature_x/DummyActivity.java
index 0f694c2..fe91260 100644
--- a/tests/ApkVerityTest/ApkVerityTestApp/feature_split/src/com/android/apkverity/feature_x/DummyActivity.java
+++ b/tests/ApkVerityTest/ApkVerityTestApp/feature_split/src/com/android/apkverity/feature_x/DummyActivity.java
@@ -18,5 +18,5 @@
import android.app.Activity;
-/** Dummy class just to generate some dex */
+/** Placeholder class just to generate some dex */
public class DummyActivity extends Activity {}
diff --git a/tests/ApkVerityTest/ApkVerityTestApp/src/com/android/apkverity/DummyActivity.java b/tests/ApkVerityTest/ApkVerityTestApp/src/com/android/apkverity/DummyActivity.java
index 837c7be..a7bd771 100644
--- a/tests/ApkVerityTest/ApkVerityTestApp/src/com/android/apkverity/DummyActivity.java
+++ b/tests/ApkVerityTest/ApkVerityTestApp/src/com/android/apkverity/DummyActivity.java
@@ -18,5 +18,5 @@
import android.app.Activity;
-/** Dummy class just to generate some dex */
+/** Placeholder class just to generate some dex */
public class DummyActivity extends Activity {}
diff --git a/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/GraphExporter.java b/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/GraphExporter.java
index 0013965..4b7ca53 100644
--- a/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/GraphExporter.java
+++ b/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/GraphExporter.java
@@ -113,7 +113,7 @@
getDotName(target.getFilter().getName()) + ":" +
getDotName(target.getName()) + "_IN;\n" );
} else {
- // Found a unconnected output port, add dummy node
+ // Found a unconnected output port, add placeholder node
String color = filter.getSignature().getOutputPortInfo(portName).isRequired()
? "red" : "blue"; // red for unconnected, required ports
dotFile.write(" " +
@@ -131,7 +131,7 @@
if(target != null) {
// Found a connection -- nothing to do, connections have been written out above
} else {
- // Found a unconnected input port, add dummy node
+ // Found a unconnected input port, add placeholder node
String color = filter.getSignature().getInputPortInfo(portName).isRequired()
? "red" : "blue"; // red for unconnected, required ports
dotFile.write(" " +
diff --git a/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/MffContext.java b/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/MffContext.java
index b7212f9..6bd6c18 100644
--- a/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/MffContext.java
+++ b/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/MffContext.java
@@ -66,9 +66,9 @@
/**
* On older Android versions the Camera may need a SurfaceView to render into in order to
- * function. You may specify a dummy SurfaceView here if you do not want the context to
+ * function. You may specify a placeholder SurfaceView here if you do not want the context to
* create its own view. Note, that your view may or may not be used. You cannot rely on
- * your dummy view to be used by the Camera. If you pass null, no dummy view will be used.
+ * your placeholder view to be used by the Camera. If you pass null, no placeholder view will be used.
* In this case your application may not run correctly on older devices if you use the
* camera. This flag has no effect if you do not require the camera.
*/
@@ -104,7 +104,7 @@
/** The current context state. */
private State mState = new State();
- /** A dummy SurfaceView that is required for Camera operation on older devices. */
+ /** A placeholder SurfaceView that is required for Camera operation on older devices. */
private SurfaceView mDummySurfaceView = null;
/** Handler to execute code in the context's thread, such as issuing callbacks. */
@@ -126,7 +126,7 @@
* multiple MffContexts, however data between them cannot be shared. The context must be
* created in a thread with a Looper (such as the main/UI thread).
*
- * On older versions of Android, the MffContext may create a visible dummy view for the
+ * On older versions of Android, the MffContext may create a visible placeholder view for the
* camera to render into. This is a 1x1 SurfaceView that is placed into the top-left corner.
*
* @param context The application context to attach the MffContext to.
@@ -142,7 +142,7 @@
* multiple MffContexts, however data between them cannot be shared. The context must be
* created in a thread with a Looper (such as the main/UI thread).
*
- * On older versions of Android, the MffContext may create a visible dummy view for the
+ * On older versions of Android, the MffContext may create a visible placeholder view for the
* camera to render into. This is a 1x1 SurfaceView that is placed into the top-left corner.
* You may alternatively specify your own SurfaceView in the configuration.
*
diff --git a/tests/DynamicCodeLoggerIntegrationTests/src/com/android/dcl/Simple.java b/tests/DynamicCodeLoggerIntegrationTests/src/com/android/dcl/Simple.java
index e995a26..2ca91fb 100644
--- a/tests/DynamicCodeLoggerIntegrationTests/src/com/android/dcl/Simple.java
+++ b/tests/DynamicCodeLoggerIntegrationTests/src/com/android/dcl/Simple.java
@@ -16,7 +16,7 @@
package com.android.dcl;
-/** Dummy class which is built into a jar purely so we can pass it to DexClassLoader. */
+/** Placeholder class which is built into a jar purely so we can pass it to DexClassLoader. */
public final class Simple {
public Simple() {}
}
diff --git a/tests/FlickerTests/Android.bp b/tests/FlickerTests/Android.bp
index 1d423ca..2ccc0fa 100644
--- a/tests/FlickerTests/Android.bp
+++ b/tests/FlickerTests/Android.bp
@@ -97,6 +97,7 @@
"flickerlib-helpers",
"platform-test-annotations",
"wm-flicker-common-app-helpers",
+ "wm-shell-flicker-utils",
],
data: [
":FlickerTestApp",
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/splitscreen/EnterSystemSplitTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/splitscreen/EnterSystemSplitTest.kt
new file mode 100644
index 0000000..87231c8
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/splitscreen/EnterSystemSplitTest.kt
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.activityembedding.splitscreen
+
+import android.platform.test.annotations.Presubmit
+import android.platform.test.annotations.RequiresDevice
+import android.tools.common.datatypes.Rect
+import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
+import android.tools.device.flicker.legacy.FlickerBuilder
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
+import android.tools.device.traces.parsers.toFlickerComponent
+import com.android.server.wm.flicker.helpers.ActivityEmbeddingAppHelper
+import com.android.server.wm.flicker.activityembedding.ActivityEmbeddingTestBase
+import com.android.server.wm.flicker.testapp.ActivityOptions
+import com.android.wm.shell.flicker.utils.*
+import org.junit.FixMethodOrder
+import org.junit.Ignore
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/***
+ * Test entering System SplitScreen with Activity Embedding Split and another app.
+ *
+ * Setup: Launch A|B in split and secondaryApp, return to home.
+ * Transitions: Let AE Split A|B enter splitscreen with secondaryApp. Resulting in A|B|secondaryApp.
+ *
+ * To run this test: `atest FlickerTestsOther:EnterSystemSplitTest`
+ */
+@RequiresDevice
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class EnterSystemSplitTest(flicker: LegacyFlickerTest) :
+ ActivityEmbeddingTestBase(flicker) {
+
+ private val secondaryApp = SplitScreenUtils.getPrimary(instrumentation)
+ override val transition: FlickerBuilder.() -> Unit = {
+ setup {
+ testApp.launchViaIntent(wmHelper)
+ testApp.launchSecondaryActivity(wmHelper)
+ secondaryApp.launchViaIntent(wmHelper)
+ tapl.goHome()
+ wmHelper
+ .StateSyncBuilder()
+ .withAppTransitionIdle()
+ .withHomeActivityVisible()
+ .waitForAndVerify()
+ startDisplayBounds =
+ wmHelper.currentState.layerState.physicalDisplayBounds ?:
+ error("Display not found")
+ }
+ transitions {
+ SplitScreenUtils.enterSplit(wmHelper, tapl, device, testApp, secondaryApp)
+ SplitScreenUtils.waitForSplitComplete(wmHelper, testApp, secondaryApp)
+ }
+ }
+
+ @Presubmit
+ @Test
+ fun splitScreenDividerBecomesVisible() = flicker.splitScreenDividerBecomesVisible()
+
+ @Presubmit
+ @Test
+ fun activityEmbeddingSplitLayerBecomesVisible() {
+ flicker.splitAppLayerBoundsIsVisibleAtEnd(
+ testApp, landscapePosLeft = tapl.isTablet, portraitPosTop = false)
+ }
+
+ @Presubmit
+ @Test
+ fun activityEmbeddingSplitWindowBecomesVisible() = flicker.appWindowIsVisibleAtEnd(testApp)
+
+ @Presubmit
+ @Test
+ fun secondaryLayerBecomesVisible() {
+ flicker.splitAppLayerBoundsIsVisibleAtEnd(
+ secondaryApp, landscapePosLeft = !tapl.isTablet, portraitPosTop = true)
+ }
+
+ @Presubmit
+ @Test
+ fun secondaryAppWindowBecomesVisible() = flicker.appWindowIsVisibleAtEnd(secondaryApp)
+
+ /**
+ * After the transition there should be both ActivityEmbedding activities,
+ * SplitScreenPrimaryActivity and the system split divider on screen.
+ * Verify the layers are in expected sizes.
+ */
+ @Presubmit
+ @Test
+ fun activityEmbeddingSplitSurfaceAreEven() {
+ flicker.assertLayersEnd {
+ val leftAELayerRegion =
+ visibleRegion(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
+ val rightAELayerRegion =
+ visibleRegion(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
+ val secondaryAppLayerRegion =
+ visibleRegion(
+ ActivityOptions.SplitScreen.Primary.COMPONENT.toFlickerComponent())
+ val systemDivider = visibleRegion(SPLIT_SCREEN_DIVIDER_COMPONENT)
+ leftAELayerRegion
+ .plus(rightAELayerRegion.region)
+ .plus(secondaryAppLayerRegion.region)
+ .plus(systemDivider.region)
+ .coversExactly(startDisplayBounds)
+ check { "ActivityEmbeddingSplitHeight" }
+ .that(leftAELayerRegion.region.height)
+ .isEqual(rightAELayerRegion.region.height)
+ check { "SystemSplitHeight" }
+ .that(rightAELayerRegion.region.height)
+ .isEqual(secondaryAppLayerRegion.region.height)
+ // TODO(b/292283182): Remove this special case handling.
+ check { "ActivityEmbeddingSplitWidth" }
+ .that(Math.abs(
+ leftAELayerRegion.region.width - rightAELayerRegion.region.width))
+ .isLower(2)
+ check { "SystemSplitWidth" }
+ .that(Math.abs(secondaryAppLayerRegion.region.width -
+ 2 * rightAELayerRegion.region.width))
+ .isLower(2)
+ }
+ }
+
+ /**
+ * Verify the windows are in expected sizes.
+ */
+ @Presubmit
+ @Test
+ fun activityEmbeddingSplitWindowsAreEven() {
+ flicker.assertWmEnd {
+ val leftAEWindowRegion =
+ visibleRegion(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
+ val rightAEWindowRegion =
+ visibleRegion(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
+ // There's no window for the divider bar.
+ val secondaryAppLayerRegion =
+ visibleRegion(
+ ActivityOptions.SplitScreen.Primary.COMPONENT.toFlickerComponent())
+ check { "ActivityEmbeddingSplitHeight" }
+ .that(leftAEWindowRegion.region.height)
+ .isEqual(rightAEWindowRegion.region.height)
+ check { "SystemSplitHeight" }
+ .that(rightAEWindowRegion.region.height)
+ .isEqual(secondaryAppLayerRegion.region.height)
+ check { "ActivityEmbeddingSplitWidth" }
+ .that(Math.abs(
+ leftAEWindowRegion.region.width - rightAEWindowRegion.region.width))
+ .isLower(2)
+ check { "SystemSplitWidth" }
+ .that(Math.abs(secondaryAppLayerRegion.region.width -
+ 2 * rightAEWindowRegion.region.width))
+ .isLower(2)
+ }
+ }
+
+ @Ignore("Not applicable to this CUJ.")
+ override fun visibleLayersShownMoreThanOneConsecutiveEntry() {}
+
+ companion object {
+ /** {@inheritDoc} */
+ private var startDisplayBounds = Rect.EMPTY
+ /**
+ * Creates the test configurations.
+ *
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * navigation modes.
+ */
+ @Parameterized.Parameters(name = "{0}")
+ @JvmStatic
+ fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
+ }
+}
\ No newline at end of file
diff --git a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeStressTestUtil.java b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeStressTestUtil.java
index c9b5c96..12556bc 100644
--- a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeStressTestUtil.java
+++ b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeStressTestUtil.java
@@ -154,7 +154,7 @@
* <p>The given {@code pred} will be called on the main thread.
*/
public static void waitOnMainUntil(String message, Callable<Boolean> pred) {
- eventually(() -> assertWithMessage(message).that(pred.call()).isTrue(), TIMEOUT);
+ eventually(() -> assertWithMessage(message).that(callOnMainSync(pred)).isTrue(), TIMEOUT);
}
/** Waits until IME is shown, or throws on timeout. */
diff --git a/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerTestService.java b/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerTestService.java
index 3567c08..cc6cebf 100644
--- a/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerTestService.java
+++ b/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerTestService.java
@@ -469,7 +469,7 @@
}
}
- // Create a few dummy models if we didn't load anything.
+ // Create a few placeholder models if we didn't load anything.
if (!loadedModel) {
Properties dummyModelProperties = new Properties();
for (String name : new String[]{"1", "2", "3"}) {
diff --git a/tests/libs-permissions/system_ext/java/com/android/test/libs/system_ext/LibsSystemExtTest.java b/tests/libs-permissions/system_ext/java/com/android/test/libs/system_ext/LibsSystemExtTest.java
index 9999aba..673c73a 100644
--- a/tests/libs-permissions/system_ext/java/com/android/test/libs/system_ext/LibsSystemExtTest.java
+++ b/tests/libs-permissions/system_ext/java/com/android/test/libs/system_ext/LibsSystemExtTest.java
@@ -22,7 +22,7 @@
public class LibsSystemExtTest {
/**
- * Dummy method for testing.
+ * Placeholder method for testing.
*/
public static void test() {
}
diff --git a/tools/aapt/AaptAssets.cpp b/tools/aapt/AaptAssets.cpp
index 899d268..b94d14f 100644
--- a/tools/aapt/AaptAssets.cpp
+++ b/tools/aapt/AaptAssets.cpp
@@ -219,7 +219,7 @@
if (numTags >= 1) {
const String8& lang = parts[0];
if (isAlpha(lang) && (lang.length() == 2 || lang.length() == 3)) {
- setLanguage(lang.string());
+ setLanguage(lang.c_str());
valid = true;
}
}
@@ -232,11 +232,11 @@
const String8& part2 = parts[1];
if ((part2.length() == 2 && isAlpha(part2)) ||
(part2.length() == 3 && isNumber(part2))) {
- setRegion(part2.string());
+ setRegion(part2.c_str());
} else if (part2.length() == 4 && isAlpha(part2)) {
- setScript(part2.string());
+ setScript(part2.c_str());
} else if (part2.length() >= 4 && part2.length() <= 8) {
- setVariant(part2.string());
+ setVariant(part2.c_str());
} else {
valid = false;
}
@@ -249,9 +249,9 @@
const String8& part3 = parts[2];
if (((part3.length() == 2 && isAlpha(part3)) ||
(part3.length() == 3 && isNumber(part3))) && script[0]) {
- setRegion(part3.string());
+ setRegion(part3.c_str());
} else if (part3.length() >= 4 && part3.length() <= 8) {
- setVariant(part3.string());
+ setVariant(part3.c_str());
} else {
valid = false;
}
@@ -262,7 +262,7 @@
const String8& part4 = parts[3];
if (part4.length() >= 4 && part4.length() <= 8) {
- setVariant(part4.string());
+ setVariant(part4.c_str());
} else {
valid = false;
}
@@ -310,7 +310,7 @@
break;
default:
fprintf(stderr, "ERROR: Invalid BCP 47 tag in directory name %s\n",
- part.string());
+ part.c_str());
return -1;
}
} else if (subtags.size() == 3) {
@@ -324,7 +324,7 @@
} else if (subtags[1].size() == 2 || subtags[1].size() == 3) {
setRegion(subtags[1]);
} else {
- fprintf(stderr, "ERROR: Invalid BCP 47 tag in directory name %s\n", part.string());
+ fprintf(stderr, "ERROR: Invalid BCP 47 tag in directory name %s\n", part.c_str());
return -1;
}
@@ -341,14 +341,14 @@
setRegion(subtags[2]);
setVariant(subtags[3]);
} else {
- fprintf(stderr, "ERROR: Invalid BCP 47 tag in directory name: %s\n", part.string());
+ fprintf(stderr, "ERROR: Invalid BCP 47 tag in directory name: %s\n", part.c_str());
return -1;
}
return ++currentIndex;
} else {
if ((part.length() == 2 || part.length() == 3)
- && isAlpha(part) && strcmp("car", part.string())) {
+ && isAlpha(part) && strcmp("car", part.c_str())) {
setLanguage(part);
if (++currentIndex == size) {
return size;
@@ -358,8 +358,8 @@
}
part = parts[currentIndex];
- if (part.string()[0] == 'r' && part.length() == 3) {
- setRegion(part.string() + 1);
+ if (part.c_str()[0] == 'r' && part.length() == 3) {
+ setRegion(part.c_str() + 1);
if (++currentIndex == size) {
return size;
}
@@ -524,8 +524,8 @@
ssize_t index = mFiles.indexOfKey(file->getGroupEntry());
if (index >= 0 && overwriteDuplicate) {
fprintf(stderr, "warning: overwriting '%s' with '%s'\n",
- mFiles[index]->getSourceFile().string(),
- file->getSourceFile().string());
+ mFiles[index]->getSourceFile().c_str(),
+ file->getSourceFile().c_str());
removeFile(index);
index = -1;
}
@@ -545,7 +545,7 @@
const sp<AaptFile>& originalFile = mFiles.valueAt(index);
SourcePos(file->getSourceFile(), -1)
.error("Duplicate file.\n%s: Original is here. %s",
- originalFile->getPrintableSource().string(),
+ originalFile->getPrintableSource().c_str(),
(withoutVersion.version != 0) ? "The version qualifier may be implied." : "");
return UNKNOWN_ERROR;
}
@@ -557,21 +557,21 @@
void AaptGroup::print(const String8& prefix) const
{
- printf("%s%s\n", prefix.string(), getPath().string());
+ printf("%s%s\n", prefix.c_str(), getPath().c_str());
const size_t N=mFiles.size();
size_t i;
for (i=0; i<N; i++) {
sp<AaptFile> file = mFiles.valueAt(i);
const AaptGroupEntry& e = file->getGroupEntry();
if (file->hasData()) {
- printf("%s Gen: (%s) %d bytes\n", prefix.string(), e.toDirName(String8()).string(),
+ printf("%s Gen: (%s) %d bytes\n", prefix.c_str(), e.toDirName(String8()).c_str(),
(int)file->getSize());
} else {
- printf("%s Src: (%s) %s\n", prefix.string(), e.toDirName(String8()).string(),
- file->getPrintableSource().string());
+ printf("%s Src: (%s) %s\n", prefix.c_str(), e.toDirName(String8()).c_str(),
+ file->getPrintableSource().c_str());
}
- //printf("%s File Group Entry: %s\n", prefix.string(),
- // file->getGroupEntry().toDirName(String8()).string());
+ //printf("%s File Group Entry: %s\n", prefix.c_str(),
+ // file->getGroupEntry().toDirName(String8()).c_str());
}
}
@@ -660,9 +660,9 @@
{
DIR* dir = NULL;
- dir = opendir(srcDir.string());
+ dir = opendir(srcDir.c_str());
if (dir == NULL) {
- fprintf(stderr, "ERROR: opendir(%s): %s\n", srcDir.string(), strerror(errno));
+ fprintf(stderr, "ERROR: opendir(%s): %s\n", srcDir.c_str(), strerror(errno));
return UNKNOWN_ERROR;
}
@@ -676,7 +676,7 @@
if (entry == NULL)
break;
- if (isHidden(srcDir.string(), entry->d_name))
+ if (isHidden(srcDir.c_str(), entry->d_name))
continue;
String8 name(entry->d_name);
@@ -701,8 +701,8 @@
String8 pathName(srcDir);
FileType type;
- pathName.appendPath(fileNames[i].string());
- type = getFileType(pathName.string());
+ pathName.appendPath(fileNames[i].c_str());
+ type = getFileType(pathName.c_str());
if (type == kFileTypeDirectory) {
sp<AaptDir> subdir;
bool notAdded = false;
@@ -732,7 +732,7 @@
} else {
if (bundle->getVerbose())
- printf(" (ignoring non-file/dir '%s')\n", pathName.string());
+ printf(" (ignoring non-file/dir '%s')\n", pathName.c_str());
}
}
@@ -745,7 +745,7 @@
const size_t ND = mDirs.size();
size_t i;
for (i = 0; i < NF; i++) {
- if (!validateFileName(mFiles.valueAt(i)->getLeaf().string())) {
+ if (!validateFileName(mFiles.valueAt(i)->getLeaf().c_str())) {
SourcePos(mFiles.valueAt(i)->getPrintableSource(), -1).error(
"Invalid filename. Unable to add.");
return UNKNOWN_ERROR;
@@ -753,11 +753,11 @@
size_t j;
for (j = i+1; j < NF; j++) {
- if (strcasecmp(mFiles.valueAt(i)->getLeaf().string(),
- mFiles.valueAt(j)->getLeaf().string()) == 0) {
+ if (strcasecmp(mFiles.valueAt(i)->getLeaf().c_str(),
+ mFiles.valueAt(j)->getLeaf().c_str()) == 0) {
SourcePos(mFiles.valueAt(i)->getPrintableSource(), -1).error(
"File is case-insensitive equivalent to: %s",
- mFiles.valueAt(j)->getPrintableSource().string());
+ mFiles.valueAt(j)->getPrintableSource().c_str());
return UNKNOWN_ERROR;
}
@@ -766,18 +766,18 @@
}
for (j = 0; j < ND; j++) {
- if (strcasecmp(mFiles.valueAt(i)->getLeaf().string(),
- mDirs.valueAt(j)->getLeaf().string()) == 0) {
+ if (strcasecmp(mFiles.valueAt(i)->getLeaf().c_str(),
+ mDirs.valueAt(j)->getLeaf().c_str()) == 0) {
SourcePos(mFiles.valueAt(i)->getPrintableSource(), -1).error(
"File conflicts with dir from: %s",
- mDirs.valueAt(j)->getPrintableSource().string());
+ mDirs.valueAt(j)->getPrintableSource().c_str());
return UNKNOWN_ERROR;
}
}
}
for (i = 0; i < ND; i++) {
- if (!validateFileName(mDirs.valueAt(i)->getLeaf().string())) {
+ if (!validateFileName(mDirs.valueAt(i)->getLeaf().c_str())) {
SourcePos(mDirs.valueAt(i)->getPrintableSource(), -1).error(
"Invalid directory name, unable to add.");
return UNKNOWN_ERROR;
@@ -785,11 +785,11 @@
size_t j;
for (j = i+1; j < ND; j++) {
- if (strcasecmp(mDirs.valueAt(i)->getLeaf().string(),
- mDirs.valueAt(j)->getLeaf().string()) == 0) {
+ if (strcasecmp(mDirs.valueAt(i)->getLeaf().c_str(),
+ mDirs.valueAt(j)->getLeaf().c_str()) == 0) {
SourcePos(mDirs.valueAt(i)->getPrintableSource(), -1).error(
"Directory is case-insensitive equivalent to: %s",
- mDirs.valueAt(j)->getPrintableSource().string());
+ mDirs.valueAt(j)->getPrintableSource().c_str());
return UNKNOWN_ERROR;
}
}
@@ -846,12 +846,12 @@
const AaptSymbolEntry& entry = javaSymbols->mSymbols.valueAt(i);
ssize_t pos = mSymbols.indexOfKey(name);
if (pos < 0) {
- entry.sourcePos.error("Symbol '%s' declared with <java-symbol> not defined\n", name.string());
+ entry.sourcePos.error("Symbol '%s' declared with <java-symbol> not defined\n", name.c_str());
err = UNKNOWN_ERROR;
continue;
}
//printf("**** setting symbol #%d/%d %s to isJavaSymbol=%d\n",
- // i, N, name.string(), entry.isJavaSymbol ? 1 : 0);
+ // i, N, name.c_str(), entry.isJavaSymbol ? 1 : 0);
mSymbols.editValueAt(pos).isJavaSymbol = entry.isJavaSymbol;
}
@@ -862,11 +862,11 @@
ssize_t pos = mNestedSymbols.indexOfKey(name);
if (pos < 0) {
SourcePos pos;
- pos.error("Java symbol dir %s not defined\n", name.string());
+ pos.error("Java symbol dir %s not defined\n", name.c_str());
err = UNKNOWN_ERROR;
continue;
}
- //printf("**** applying java symbols in dir %s\n", name.string());
+ //printf("**** applying java symbols in dir %s\n", name.c_str());
status_t myerr = mNestedSymbols.valueAt(pos)->applyJavaSymbols(symbols);
if (myerr != NO_ERROR) {
err = myerr;
@@ -1131,9 +1131,9 @@
{
ssize_t err = 0;
- DIR* dir = opendir(srcDir.string());
+ DIR* dir = opendir(srcDir.c_str());
if (dir == NULL) {
- fprintf(stderr, "ERROR: opendir(%s): %s\n", srcDir.string(), strerror(errno));
+ fprintf(stderr, "ERROR: opendir(%s): %s\n", srcDir.c_str(), strerror(errno));
return UNKNOWN_ERROR;
}
@@ -1149,7 +1149,7 @@
break;
}
- if (isHidden(srcDir.string(), entry->d_name)) {
+ if (isHidden(srcDir.c_str(), entry->d_name)) {
continue;
}
@@ -1160,7 +1160,7 @@
String8 resType;
bool b = group.initFromDirName(entry->d_name, &resType);
if (!b) {
- fprintf(stderr, "invalid resource directory name: %s %s\n", srcDir.string(),
+ fprintf(stderr, "invalid resource directory name: %s %s\n", srcDir.c_str(),
entry->d_name);
err = -1;
continue;
@@ -1168,7 +1168,7 @@
if (bundle->getMaxResVersion() != NULL && group.getVersionString().length() != 0) {
int maxResInt = atoi(bundle->getMaxResVersion());
- const char *verString = group.getVersionString().string();
+ const char *verString = group.getVersionString().c_str();
int dirVersionInt = atoi(verString + 1); // skip 'v' in version name
if (dirVersionInt > maxResInt) {
fprintf(stderr, "max res %d, skipping %s\n", maxResInt, entry->d_name);
@@ -1176,7 +1176,7 @@
}
}
- FileType type = getFileType(subdirName.string());
+ FileType type = getFileType(subdirName.c_str());
if (type == kFileTypeDirectory) {
sp<AaptDir> dir = makeDir(resType);
@@ -1200,7 +1200,7 @@
}
} else {
if (bundle->getVerbose()) {
- fprintf(stderr, " (ignoring file '%s')\n", subdirName.string());
+ fprintf(stderr, " (ignoring file '%s')\n", subdirName.c_str());
}
}
}
@@ -1248,7 +1248,7 @@
String8 remain;
if (entryName.walkPath(&remain) == kResourceDir) {
// these are the resources, pull their type out of the directory name
- kind.initFromDirName(remain.walkPath().string(), &resType);
+ kind.initFromDirName(remain.walkPath().c_str(), &resType);
} else {
// these are untyped and don't have an AaptGroupEntry
}
@@ -1263,7 +1263,7 @@
sp<AaptFile> file = new AaptFile(entryName, kind, resType);
status_t err = dir->addLeafFile(entryName.getPathLeaf(), file);
if (err != NO_ERROR) {
- fprintf(stderr, "err=%s entryName=%s\n", strerror(err), entryName.string());
+ fprintf(stderr, "err=%s entryName=%s\n", strerror(err), entryName.c_str());
count = err;
goto bail;
}
@@ -1273,7 +1273,7 @@
if (entryName == "AndroidManifest.xml") {
printf("AndroidManifest.xml\n");
}
- printf("\n\nfile: %s\n", entryName.string());
+ printf("\n\nfile: %s\n", entryName.c_str());
#endif
size_t len = entry->getUncompressedLen();
@@ -1317,9 +1317,9 @@
uint32_t preferredDensity = 0;
if (bundle->getPreferredDensity().size() > 0) {
ResTable_config preferredConfig;
- if (!AaptConfig::parseDensity(bundle->getPreferredDensity().string(), &preferredConfig)) {
+ if (!AaptConfig::parseDensity(bundle->getPreferredDensity().c_str(), &preferredConfig)) {
fprintf(stderr, "Error parsing preferred density: %s\n",
- bundle->getPreferredDensity().string());
+ bundle->getPreferredDensity().c_str());
return UNKNOWN_ERROR;
}
preferredDensity = preferredConfig.density;
@@ -1332,11 +1332,11 @@
if (bundle->getVerbose()) {
if (!reqFilter->isEmpty()) {
printf("Applying required filter: %s\n",
- bundle->getConfigurations().string());
+ bundle->getConfigurations().c_str());
}
if (preferredDensity > 0) {
printf("Applying preferred density filter: %s\n",
- bundle->getPreferredDensity().string());
+ bundle->getPreferredDensity().c_str());
}
}
@@ -1385,7 +1385,7 @@
if (!reqFilter->match(config)) {
if (bundle->getVerbose()) {
printf("Pruning unneeded resource: %s\n",
- file->getPrintableSource().string());
+ file->getPrintableSource().c_str());
}
grp->removeFile(k);
k--;
@@ -1453,7 +1453,7 @@
if (bestDensity != config.density) {
if (bundle->getVerbose()) {
printf("Pruning unneeded resource: %s\n",
- file->getPrintableSource().string());
+ file->getPrintableSource().c_str());
}
grp->removeFile(k);
k--;
@@ -1495,10 +1495,10 @@
ssize_t pos = mSymbols.indexOfKey(name);
if (pos < 0) {
SourcePos pos;
- pos.error("Java symbol dir %s not defined\n", name.string());
+ pos.error("Java symbol dir %s not defined\n", name.c_str());
return UNKNOWN_ERROR;
}
- //printf("**** applying java symbols in dir %s\n", name.string());
+ //printf("**** applying java symbols in dir %s\n", name.c_str());
status_t err = mSymbols.valueAt(pos)->applyJavaSymbols(symbols);
if (err != NO_ERROR) {
return err;
@@ -1510,7 +1510,7 @@
bool AaptAssets::isJavaSymbol(const AaptSymbolEntry& sym, bool includePrivate) const {
//printf("isJavaSymbol %s: public=%d, includePrivate=%d, isJavaSymbol=%d\n",
- // sym.name.string(), sym.isPublic ? 1 : 0, includePrivate ? 1 : 0,
+ // sym.name.c_str(), sym.isPublic ? 1 : 0, includePrivate ? 1 : 0,
// sym.isJavaSymbol ? 1 : 0);
if (!mHavePrivateSymbols) return true;
if (sym.isPublic) return true;
@@ -1529,12 +1529,12 @@
const size_t packageIncludeCount = includes.size();
for (size_t i = 0; i < packageIncludeCount; i++) {
if (bundle->getVerbose()) {
- printf("Including resources from package: %s\n", includes[i].string());
+ printf("Including resources from package: %s\n", includes[i].c_str());
}
if (!mIncludedAssets.addAssetPath(includes[i], NULL)) {
fprintf(stderr, "ERROR: Asset package include '%s' not found.\n",
- includes[i].string());
+ includes[i].c_str());
return UNKNOWN_ERROR;
}
}
@@ -1543,12 +1543,12 @@
if (!featureOfBase.isEmpty()) {
if (bundle->getVerbose()) {
printf("Including base feature resources from package: %s\n",
- featureOfBase.string());
+ featureOfBase.c_str());
}
if (!mIncludedAssets.addAssetPath(featureOfBase, NULL)) {
fprintf(stderr, "ERROR: base feature package '%s' not found.\n",
- featureOfBase.string());
+ featureOfBase.c_str());
return UNKNOWN_ERROR;
}
}
@@ -1581,23 +1581,23 @@
innerPrefix.append(" ");
String8 innerInnerPrefix(innerPrefix);
innerInnerPrefix.append(" ");
- printf("%sConfigurations:\n", prefix.string());
+ printf("%sConfigurations:\n", prefix.c_str());
const size_t N=mGroupEntries.size();
for (size_t i=0; i<N; i++) {
String8 cname = mGroupEntries.itemAt(i).toDirName(String8());
- printf("%s %s\n", prefix.string(),
- cname != "" ? cname.string() : "(default)");
+ printf("%s %s\n", prefix.c_str(),
+ cname != "" ? cname.c_str() : "(default)");
}
- printf("\n%sFiles:\n", prefix.string());
+ printf("\n%sFiles:\n", prefix.c_str());
AaptDir::print(innerPrefix);
- printf("\n%sResource Dirs:\n", prefix.string());
+ printf("\n%sResource Dirs:\n", prefix.c_str());
const Vector<sp<AaptDir> >& resdirs = mResDirs;
const size_t NR = resdirs.size();
for (size_t i=0; i<NR; i++) {
const sp<AaptDir>& d = resdirs.itemAt(i);
- printf("%s Type %s\n", prefix.string(), d->getLeaf().string());
+ printf("%s Type %s\n", prefix.c_str(), d->getLeaf().c_str());
d->print(innerInnerPrefix);
}
}
@@ -1631,7 +1631,7 @@
NULL
};
const char*const* k = KEYWORDS;
- const char*const s = symbol.string();
+ const char*const s = symbol.c_str();
while (*k) {
if (0 == strcmp(s, *k)) {
return false;
diff --git a/tools/aapt/AaptAssets.h b/tools/aapt/AaptAssets.h
index eadd48a..498fc4e 100644
--- a/tools/aapt/AaptAssets.h
+++ b/tools/aapt/AaptAssets.h
@@ -463,7 +463,7 @@
if (valid_symbol_name(symbol)) {
return true;
}
- pos.error("invalid %s: '%s'\n", label, symbol.string());
+ pos.error("invalid %s: '%s'\n", label, symbol.c_str());
return false;
}
AaptSymbolEntry& edit_symbol(const String8& symbol, const SourcePos* pos) {
diff --git a/tools/aapt/AaptConfig.cpp b/tools/aapt/AaptConfig.cpp
index 0aca45e..7578f79 100644
--- a/tools/aapt/AaptConfig.cpp
+++ b/tools/aapt/AaptConfig.cpp
@@ -39,7 +39,7 @@
ssize_t index = 0;
ssize_t localeIndex = 0;
const ssize_t N = parts.size();
- const char* part = parts[index].string();
+ const char* part = parts[index].c_str();
if (str.length() == 0) {
goto success;
@@ -50,7 +50,7 @@
if (index == N) {
goto success;
}
- part = parts[index].string();
+ part = parts[index].c_str();
}
if (parseMnc(part, &config)) {
@@ -58,7 +58,7 @@
if (index == N) {
goto success;
}
- part = parts[index].string();
+ part = parts[index].c_str();
}
// Locale spans a few '-' separators, so we let it
@@ -72,7 +72,7 @@
if (index >= N) {
goto success;
}
- part = parts[index].string();
+ part = parts[index].c_str();
}
if (parseLayoutDirection(part, &config)) {
@@ -80,7 +80,7 @@
if (index == N) {
goto success;
}
- part = parts[index].string();
+ part = parts[index].c_str();
}
if (parseSmallestScreenWidthDp(part, &config)) {
@@ -88,7 +88,7 @@
if (index == N) {
goto success;
}
- part = parts[index].string();
+ part = parts[index].c_str();
}
if (parseScreenWidthDp(part, &config)) {
@@ -96,7 +96,7 @@
if (index == N) {
goto success;
}
- part = parts[index].string();
+ part = parts[index].c_str();
}
if (parseScreenHeightDp(part, &config)) {
@@ -104,7 +104,7 @@
if (index == N) {
goto success;
}
- part = parts[index].string();
+ part = parts[index].c_str();
}
if (parseScreenLayoutSize(part, &config)) {
@@ -112,7 +112,7 @@
if (index == N) {
goto success;
}
- part = parts[index].string();
+ part = parts[index].c_str();
}
if (parseScreenLayoutLong(part, &config)) {
@@ -120,7 +120,7 @@
if (index == N) {
goto success;
}
- part = parts[index].string();
+ part = parts[index].c_str();
}
if (parseScreenRound(part, &config)) {
@@ -128,7 +128,7 @@
if (index == N) {
goto success;
}
- part = parts[index].string();
+ part = parts[index].c_str();
}
if (parseWideColorGamut(part, &config)) {
@@ -136,7 +136,7 @@
if (index == N) {
goto success;
}
- part = parts[index].string();
+ part = parts[index].c_str();
}
if (parseHdr(part, &config)) {
@@ -144,7 +144,7 @@
if (index == N) {
goto success;
}
- part = parts[index].string();
+ part = parts[index].c_str();
}
if (parseOrientation(part, &config)) {
@@ -152,7 +152,7 @@
if (index == N) {
goto success;
}
- part = parts[index].string();
+ part = parts[index].c_str();
}
if (parseUiModeType(part, &config)) {
@@ -160,7 +160,7 @@
if (index == N) {
goto success;
}
- part = parts[index].string();
+ part = parts[index].c_str();
}
if (parseUiModeNight(part, &config)) {
@@ -168,7 +168,7 @@
if (index == N) {
goto success;
}
- part = parts[index].string();
+ part = parts[index].c_str();
}
if (parseDensity(part, &config)) {
@@ -176,7 +176,7 @@
if (index == N) {
goto success;
}
- part = parts[index].string();
+ part = parts[index].c_str();
}
if (parseTouchscreen(part, &config)) {
@@ -184,7 +184,7 @@
if (index == N) {
goto success;
}
- part = parts[index].string();
+ part = parts[index].c_str();
}
if (parseKeysHidden(part, &config)) {
@@ -192,7 +192,7 @@
if (index == N) {
goto success;
}
- part = parts[index].string();
+ part = parts[index].c_str();
}
if (parseKeyboard(part, &config)) {
@@ -200,7 +200,7 @@
if (index == N) {
goto success;
}
- part = parts[index].string();
+ part = parts[index].c_str();
}
if (parseNavHidden(part, &config)) {
@@ -208,7 +208,7 @@
if (index == N) {
goto success;
}
- part = parts[index].string();
+ part = parts[index].c_str();
}
if (parseNavigation(part, &config)) {
@@ -216,7 +216,7 @@
if (index == N) {
goto success;
}
- part = parts[index].string();
+ part = parts[index].c_str();
}
if (parseScreenSize(part, &config)) {
@@ -224,7 +224,7 @@
if (index == N) {
goto success;
}
- part = parts[index].string();
+ part = parts[index].c_str();
}
if (parseVersion(part, &config)) {
@@ -232,7 +232,7 @@
if (index == N) {
goto success;
}
- part = parts[index].string();
+ part = parts[index].c_str();
}
// Unrecognized.
@@ -773,8 +773,8 @@
if (y == name || *y != 0) return false;
String8 yName(x, y-x);
- uint16_t w = (uint16_t)atoi(xName.string());
- uint16_t h = (uint16_t)atoi(yName.string());
+ uint16_t w = (uint16_t)atoi(xName.c_str());
+ uint16_t h = (uint16_t)atoi(yName.c_str());
if (w < h) {
return false;
}
@@ -805,7 +805,7 @@
String8 xName(name, x-name);
if (out) {
- out->smallestScreenWidthDp = (uint16_t)atoi(xName.string());
+ out->smallestScreenWidthDp = (uint16_t)atoi(xName.c_str());
}
return true;
@@ -827,7 +827,7 @@
String8 xName(name, x-name);
if (out) {
- out->screenWidthDp = (uint16_t)atoi(xName.string());
+ out->screenWidthDp = (uint16_t)atoi(xName.c_str());
}
return true;
@@ -849,7 +849,7 @@
String8 xName(name, x-name);
if (out) {
- out->screenHeightDp = (uint16_t)atoi(xName.string());
+ out->screenHeightDp = (uint16_t)atoi(xName.c_str());
}
return true;
@@ -875,7 +875,7 @@
String8 sdkName(name, s-name);
if (out) {
- out->sdkVersion = (uint16_t)atoi(sdkName.string());
+ out->sdkVersion = (uint16_t)atoi(sdkName.c_str());
out->minorVersion = 0;
}
diff --git a/tools/aapt/AaptUtil.cpp b/tools/aapt/AaptUtil.cpp
index 293e144..e82860d 100644
--- a/tools/aapt/AaptUtil.cpp
+++ b/tools/aapt/AaptUtil.cpp
@@ -23,7 +23,7 @@
Vector<String8> split(const String8& str, const char sep) {
Vector<String8> parts;
- const char* p = str.string();
+ const char* p = str.c_str();
const char* q;
while (true) {
@@ -41,7 +41,7 @@
Vector<String8> splitAndLowerCase(const String8& str, const char sep) {
Vector<String8> parts;
- const char* p = str.string();
+ const char* p = str.c_str();
const char* q;
while (true) {
diff --git a/tools/aapt/ApkBuilder.cpp b/tools/aapt/ApkBuilder.cpp
index 01e02e2..335c43b 100644
--- a/tools/aapt/ApkBuilder.cpp
+++ b/tools/aapt/ApkBuilder.cpp
@@ -36,7 +36,7 @@
if (splitConfigs.count(*iter) > 0) {
// Can't have overlapping configurations.
fprintf(stderr, "ERROR: Split configuration '%s' is already defined "
- "in another split.\n", iter->toString().string());
+ "in another split.\n", iter->toString().c_str());
return ALREADY_EXISTS;
}
}
@@ -115,10 +115,10 @@
}
void ApkSplit::print() const {
- fprintf(stderr, "APK Split '%s'\n", mName.string());
+ fprintf(stderr, "APK Split '%s'\n", mName.c_str());
std::set<OutputEntry>::const_iterator iter = mFiles.begin();
for (; iter != mFiles.end(); iter++) {
- fprintf(stderr, " %s (%s)\n", iter->getPath().string(), iter->getFile()->getSourceFile().string());
+ fprintf(stderr, " %s (%s)\n", iter->getPath().c_str(), iter->getFile()->getSourceFile().c_str());
}
}
diff --git a/tools/aapt/CacheUpdater.h b/tools/aapt/CacheUpdater.h
index 6fa96d6..2dc143c 100644
--- a/tools/aapt/CacheUpdater.h
+++ b/tools/aapt/CacheUpdater.h
@@ -66,7 +66,7 @@
// Check optomistically to see if all directories exist.
// If something in the path doesn't exist, then walk the path backwards
// and find the place to start creating directories forward.
- if (stat(path.string(),&s) == -1) {
+ if (stat(path.c_str(),&s) == -1) {
// Walk backwards to find place to start creating directories
existsPath = path;
do {
@@ -74,7 +74,7 @@
// the string of paths to create.
toCreate = existsPath.getPathLeaf().appendPath(toCreate);
existsPath = existsPath.getPathDir();
- } while (stat(existsPath.string(),&s) == -1);
+ } while (stat(existsPath.c_str(),&s) == -1);
// Walk forwards and build directories as we go
do {
@@ -82,9 +82,9 @@
existsPath.appendPath(toCreate.walkPath(&remains));
toCreate = remains;
#ifdef _WIN32
- _mkdir(existsPath.string());
+ _mkdir(existsPath.c_str());
#else
- mkdir(existsPath.string(), S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP);
+ mkdir(existsPath.c_str(), S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP);
#endif
} while (remains.length() > 0);
} //if
@@ -93,8 +93,8 @@
// Delete a file
virtual void deleteFile(String8 path)
{
- if (remove(path.string()) != 0)
- fprintf(stderr,"ERROR DELETING %s\n",path.string());
+ if (remove(path.c_str()) != 0)
+ fprintf(stderr,"ERROR DELETING %s\n",path.c_str());
};
// Process an image from source out to dest
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index 51cf38b..5a06b10 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -240,13 +240,13 @@
}
if (value.dataType == Res_value::TYPE_STRING) {
String8 result = AaptXml::getResolvedAttribute(resTable, tree, attrRes, outError);
- printf("%s='%s'", attrLabel.string(),
- ResTable::normalizeForOutput(result.string()).string());
+ printf("%s='%s'", attrLabel.c_str(),
+ ResTable::normalizeForOutput(result.c_str()).c_str());
} else if (Res_value::TYPE_FIRST_INT <= value.dataType &&
value.dataType <= Res_value::TYPE_LAST_INT) {
- printf("%s='%d'", attrLabel.string(), value.data);
+ printf("%s='%d'", attrLabel.c_str(), value.data);
} else {
- printf("%s='0x%x'", attrLabel.string(), (int)value.data);
+ printf("%s='0x%x'", attrLabel.c_str(), (int)value.data);
}
}
@@ -355,21 +355,21 @@
static void printUsesPermission(const String8& name, bool optional=false, int maxSdkVersion=-1,
const String8& requiredFeature = String8(),
const String8& requiredNotFeature = String8()) {
- printf("uses-permission: name='%s'", ResTable::normalizeForOutput(name.string()).string());
+ printf("uses-permission: name='%s'", ResTable::normalizeForOutput(name.c_str()).c_str());
if (maxSdkVersion != -1) {
printf(" maxSdkVersion='%d'", maxSdkVersion);
}
if (requiredFeature.length() > 0) {
- printf(" requiredFeature='%s'", requiredFeature.string());
+ printf(" requiredFeature='%s'", requiredFeature.c_str());
}
if (requiredNotFeature.length() > 0) {
- printf(" requiredNotFeature='%s'", requiredNotFeature.string());
+ printf(" requiredNotFeature='%s'", requiredNotFeature.c_str());
}
printf("\n");
if (optional) {
printf("optional-permission: name='%s'",
- ResTable::normalizeForOutput(name.string()).string());
+ ResTable::normalizeForOutput(name.c_str()).c_str());
if (maxSdkVersion != -1) {
printf(" maxSdkVersion='%d'", maxSdkVersion);
}
@@ -380,7 +380,7 @@
static void printUsesPermissionSdk23(const String8& name, int maxSdkVersion=-1) {
printf("uses-permission-sdk-23: ");
- printf("name='%s'", ResTable::normalizeForOutput(name.string()).string());
+ printf("name='%s'", ResTable::normalizeForOutput(name.c_str()).c_str());
if (maxSdkVersion != -1) {
printf(" maxSdkVersion='%d'", maxSdkVersion);
}
@@ -390,11 +390,11 @@
static void printUsesImpliedPermission(const String8& name, const String8& reason,
const int32_t maxSdkVersion = -1) {
printf("uses-implied-permission: name='%s'",
- ResTable::normalizeForOutput(name.string()).string());
+ ResTable::normalizeForOutput(name.c_str()).c_str());
if (maxSdkVersion != -1) {
printf(" maxSdkVersion='%d'", maxSdkVersion);
}
- printf(" reason='%s'\n", ResTable::normalizeForOutput(reason.string()).string());
+ printf(" reason='%s'\n", ResTable::normalizeForOutput(reason.c_str()).c_str());
}
Vector<String8> getNfcAidCategories(AssetManager& assets, const String8& xmlPath, bool offHost,
@@ -556,7 +556,7 @@
static void printFeatureGroupImpl(const FeatureGroup& grp,
const KeyedVector<String8, ImpliedFeature>* impliedFeatures) {
- printf("feature-group: label='%s'\n", grp.label.string());
+ printf("feature-group: label='%s'\n", grp.label.c_str());
if (grp.openGLESVersion > 0) {
printf(" uses-gl-es: '0x%x'\n", grp.openGLESVersion);
@@ -570,7 +570,7 @@
const String8& featureName = grp.features.keyAt(i);
printf(" uses-feature%s: name='%s'", (required ? "" : "-not-required"),
- ResTable::normalizeForOutput(featureName.string()).string());
+ ResTable::normalizeForOutput(featureName.c_str()).c_str());
if (version > 0) {
printf(" version='%d'", version);
@@ -589,15 +589,15 @@
}
String8 printableFeatureName(ResTable::normalizeForOutput(
- impliedFeature.name.string()));
+ impliedFeature.name.c_str()));
const char* sdk23Suffix = impliedFeature.impliedBySdk23 ? "-sdk-23" : "";
- printf(" uses-feature%s: name='%s'\n", sdk23Suffix, printableFeatureName.string());
+ printf(" uses-feature%s: name='%s'\n", sdk23Suffix, printableFeatureName.c_str());
printf(" uses-implied-feature%s: name='%s' reason='", sdk23Suffix,
- printableFeatureName.string());
+ printableFeatureName.c_str());
const size_t numReasons = impliedFeature.reasons.size();
for (size_t j = 0; j < numReasons; j++) {
- printf("%s", impliedFeature.reasons[j].string());
+ printf("%s", impliedFeature.reasons[j].c_str());
if (j + 2 < numReasons) {
printf(", ");
} else if (j + 1 < numReasons) {
@@ -649,43 +649,43 @@
bool impliedBySdk23Permission) {
if (name == "android.permission.CAMERA") {
addImpliedFeature(impliedFeatures, "android.hardware.camera",
- String8::format("requested %s permission", name.string()),
+ String8::format("requested %s permission", name.c_str()),
impliedBySdk23Permission);
} else if (name == "android.permission.ACCESS_FINE_LOCATION") {
if (targetSdk < SDK_LOLLIPOP) {
addImpliedFeature(impliedFeatures, "android.hardware.location.gps",
- String8::format("requested %s permission", name.string()),
+ String8::format("requested %s permission", name.c_str()),
impliedBySdk23Permission);
addImpliedFeature(impliedFeatures, "android.hardware.location.gps",
String8::format("targetSdkVersion < %d", SDK_LOLLIPOP),
impliedBySdk23Permission);
}
addImpliedFeature(impliedFeatures, "android.hardware.location",
- String8::format("requested %s permission", name.string()),
+ String8::format("requested %s permission", name.c_str()),
impliedBySdk23Permission);
} else if (name == "android.permission.ACCESS_COARSE_LOCATION") {
if (targetSdk < SDK_LOLLIPOP) {
addImpliedFeature(impliedFeatures, "android.hardware.location.network",
- String8::format("requested %s permission", name.string()),
+ String8::format("requested %s permission", name.c_str()),
impliedBySdk23Permission);
addImpliedFeature(impliedFeatures, "android.hardware.location.network",
String8::format("targetSdkVersion < %d", SDK_LOLLIPOP),
impliedBySdk23Permission);
}
addImpliedFeature(impliedFeatures, "android.hardware.location",
- String8::format("requested %s permission", name.string()),
+ String8::format("requested %s permission", name.c_str()),
impliedBySdk23Permission);
} else if (name == "android.permission.ACCESS_MOCK_LOCATION" ||
name == "android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" ||
name == "android.permission.INSTALL_LOCATION_PROVIDER") {
addImpliedFeature(impliedFeatures, "android.hardware.location",
- String8::format("requested %s permission", name.string()),
+ String8::format("requested %s permission", name.c_str()),
impliedBySdk23Permission);
} else if (name == "android.permission.BLUETOOTH" ||
name == "android.permission.BLUETOOTH_ADMIN") {
if (targetSdk > SDK_DONUT) {
addImpliedFeature(impliedFeatures, "android.hardware.bluetooth",
- String8::format("requested %s permission", name.string()),
+ String8::format("requested %s permission", name.c_str()),
impliedBySdk23Permission);
addImpliedFeature(impliedFeatures, "android.hardware.bluetooth",
String8::format("targetSdkVersion > %d", SDK_DONUT),
@@ -693,13 +693,13 @@
}
} else if (name == "android.permission.RECORD_AUDIO") {
addImpliedFeature(impliedFeatures, "android.hardware.microphone",
- String8::format("requested %s permission", name.string()),
+ String8::format("requested %s permission", name.c_str()),
impliedBySdk23Permission);
} else if (name == "android.permission.ACCESS_WIFI_STATE" ||
name == "android.permission.CHANGE_WIFI_STATE" ||
name == "android.permission.CHANGE_WIFI_MULTICAST_STATE") {
addImpliedFeature(impliedFeatures, "android.hardware.wifi",
- String8::format("requested %s permission", name.string()),
+ String8::format("requested %s permission", name.c_str()),
impliedBySdk23Permission);
} else if (name == "android.permission.CALL_PHONE" ||
name == "android.permission.CALL_PRIVILEGED" ||
@@ -746,7 +746,7 @@
for (size_t i = 0; i < bundle->getPackageIncludes().size(); i++) {
const String8& assetPath = bundle->getPackageIncludes()[i];
if (!assets.addAssetPath(assetPath, NULL)) {
- fprintf(stderr, "ERROR: included asset path %s could not be loaded\n", assetPath.string());
+ fprintf(stderr, "ERROR: included asset path %s could not be loaded\n", assetPath.c_str());
return 1;
}
}
@@ -890,7 +890,7 @@
goto bail;
}
String8 tag(ctag16);
- //printf("Depth %d tag %s\n", depth, tag.string());
+ //printf("Depth %d tag %s\n", depth, tag.c_str());
if (depth == 1) {
if (tag != "manifest") {
SourcePos(manifestFile, tree.getLineNumber()).error(
@@ -898,14 +898,14 @@
goto bail;
}
String8 pkg = AaptXml::getAttribute(tree, NULL, "package", NULL);
- printf("package: %s\n", ResTable::normalizeForOutput(pkg.string()).string());
+ printf("package: %s\n", ResTable::normalizeForOutput(pkg.c_str()).c_str());
} else if (depth == 2) {
if (tag == "permission") {
String8 error;
String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error);
if (error != "") {
SourcePos(manifestFile, tree.getLineNumber()).error(
- "ERROR getting 'android:name': %s", error.string());
+ "ERROR getting 'android:name': %s", error.c_str());
goto bail;
}
@@ -915,13 +915,13 @@
goto bail;
}
printf("permission: %s\n",
- ResTable::normalizeForOutput(name.string()).string());
+ ResTable::normalizeForOutput(name.c_str()).c_str());
} else if (tag == "uses-permission") {
String8 error;
String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error);
if (error != "") {
SourcePos(manifestFile, tree.getLineNumber()).error(
- "ERROR getting 'android:name' attribute: %s", error.string());
+ "ERROR getting 'android:name' attribute: %s", error.c_str());
goto bail;
}
@@ -938,7 +938,7 @@
String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error);
if (error != "") {
SourcePos(manifestFile, tree.getLineNumber()).error(
- "ERROR getting 'android:name' attribute: %s", error.string());
+ "ERROR getting 'android:name' attribute: %s", error.c_str());
goto bail;
}
@@ -1138,7 +1138,7 @@
const size_t N = supportedInput.size();
for (size_t i=0; i<N; i++) {
printf("%s", ResTable::normalizeForOutput(
- supportedInput[i].string()).string());
+ supportedInput[i].c_str()).c_str());
if (i != N - 1) {
printf("' '");
} else {
@@ -1157,27 +1157,27 @@
printf("launchable-activity:");
if (aName.length() > 0) {
printf(" name='%s' ",
- ResTable::normalizeForOutput(aName.string()).string());
+ ResTable::normalizeForOutput(aName.c_str()).c_str());
}
printf(" label='%s' icon='%s'\n",
- ResTable::normalizeForOutput(activityLabel.string())
- .string(),
- ResTable::normalizeForOutput(activityIcon.string())
- .string());
+ ResTable::normalizeForOutput(activityLabel.c_str())
+ .c_str(),
+ ResTable::normalizeForOutput(activityIcon.c_str())
+ .c_str());
}
if (isLeanbackLauncherActivity) {
printf("leanback-launchable-activity:");
if (aName.length() > 0) {
printf(" name='%s' ",
- ResTable::normalizeForOutput(aName.string()).string());
+ ResTable::normalizeForOutput(aName.c_str()).c_str());
}
printf(" label='%s' icon='%s' banner='%s'\n",
- ResTable::normalizeForOutput(activityLabel.string())
- .string(),
- ResTable::normalizeForOutput(activityIcon.string())
- .string(),
- ResTable::normalizeForOutput(activityBanner.string())
- .string());
+ ResTable::normalizeForOutput(activityLabel.c_str())
+ .c_str(),
+ ResTable::normalizeForOutput(activityIcon.c_str())
+ .c_str(),
+ ResTable::normalizeForOutput(activityBanner.c_str())
+ .c_str());
}
}
if (!hasIntentFilter) {
@@ -1265,7 +1265,7 @@
goto bail;
}
String8 tag(ctag16);
- //printf("Depth %d, %s\n", depth, tag.string());
+ //printf("Depth %d, %s\n", depth, tag.c_str());
if (depth == 1) {
if (tag != "manifest") {
SourcePos(manifestFile, tree.getLineNumber()).error(
@@ -1274,13 +1274,13 @@
}
pkg = AaptXml::getAttribute(tree, NULL, "package", NULL);
printf("package: name='%s' ",
- ResTable::normalizeForOutput(pkg.string()).string());
+ ResTable::normalizeForOutput(pkg.c_str()).c_str());
int32_t versionCode = AaptXml::getIntegerAttribute(tree, VERSION_CODE_ATTR,
&error);
if (error != "") {
SourcePos(manifestFile, tree.getLineNumber()).error(
"ERROR getting 'android:versionCode' attribute: %s",
- error.string());
+ error.c_str());
goto bail;
}
if (versionCode > 0) {
@@ -1293,16 +1293,16 @@
if (error != "") {
SourcePos(manifestFile, tree.getLineNumber()).error(
"ERROR getting 'android:versionName' attribute: %s",
- error.string());
+ error.c_str());
goto bail;
}
printf("versionName='%s'",
- ResTable::normalizeForOutput(versionName.string()).string());
+ ResTable::normalizeForOutput(versionName.c_str()).c_str());
String8 splitName = AaptXml::getAttribute(tree, NULL, "split");
if (!splitName.isEmpty()) {
printf(" split='%s'", ResTable::normalizeForOutput(
- splitName.string()).string());
+ splitName.c_str()).c_str());
}
// For 'platformBuildVersionName', using both string and int type as a fallback
@@ -1313,7 +1313,7 @@
AaptXml::getIntegerAttribute(tree, NULL, "platformBuildVersionName", 0,
NULL);
if (platformBuildVersionName != "") {
- printf(" platformBuildVersionName='%s'", platformBuildVersionName.string());
+ printf(" platformBuildVersionName='%s'", platformBuildVersionName.c_str());
} else if (platformBuildVersionNameInt > 0) {
printf(" platformBuildVersionName='%d'", platformBuildVersionNameInt);
}
@@ -1326,7 +1326,7 @@
AaptXml::getIntegerAttribute(tree, NULL, "platformBuildVersionCode", 0,
NULL);
if (platformBuildVersionCode != "") {
- printf(" platformBuildVersionCode='%s'", platformBuildVersionCode.string());
+ printf(" platformBuildVersionCode='%s'", platformBuildVersionCode.c_str());
} else if (platformBuildVersionCodeInt > 0) {
printf(" platformBuildVersionCode='%d'", platformBuildVersionCodeInt);
}
@@ -1336,7 +1336,7 @@
if (error != "") {
SourcePos(manifestFile, tree.getLineNumber()).error(
"ERROR getting 'android:compileSdkVersion' attribute: %s",
- error.string());
+ error.c_str());
goto bail;
}
if (compileSdkVersion > 0) {
@@ -1347,7 +1347,7 @@
COMPILE_SDK_VERSION_CODENAME_ATTR, &error);
if (compileSdkVersionCodename != "") {
printf(" compileSdkVersionCodename='%s'", ResTable::normalizeForOutput(
- compileSdkVersionCodename.string()).string());
+ compileSdkVersionCodename.c_str()).c_str());
}
printf("\n");
@@ -1357,7 +1357,7 @@
if (error != "") {
SourcePos(manifestFile, tree.getLineNumber()).error(
"ERROR getting 'android:installLocation' attribute: %s",
- error.string());
+ error.c_str());
goto bail;
}
@@ -1387,7 +1387,7 @@
String8 label;
const size_t NL = locales.size();
for (size_t i=0; i<NL; i++) {
- const char* localeStr = locales[i].string();
+ const char* localeStr = locales[i].c_str();
assets.setConfiguration(config, localeStr != NULL ? localeStr : "");
String8 llabel = AaptXml::getResolvedAttribute(res, tree, LABEL_ATTR,
&error);
@@ -1395,13 +1395,13 @@
if (localeStr == NULL || strlen(localeStr) == 0) {
label = llabel;
printf("application-label:'%s'\n",
- ResTable::normalizeForOutput(llabel.string()).string());
+ ResTable::normalizeForOutput(llabel.c_str()).c_str());
} else {
if (label == "") {
label = llabel;
}
printf("application-label-%s:'%s'\n", localeStr,
- ResTable::normalizeForOutput(llabel.string()).string());
+ ResTable::normalizeForOutput(llabel.c_str()).c_str());
}
}
}
@@ -1415,7 +1415,7 @@
&error);
if (icon != "") {
printf("application-icon-%d:'%s'\n", densities[i],
- ResTable::normalizeForOutput(icon.string()).string());
+ ResTable::normalizeForOutput(icon.c_str()).c_str());
}
}
assets.setConfiguration(config);
@@ -1423,7 +1423,7 @@
String8 icon = AaptXml::getResolvedAttribute(res, tree, ICON_ATTR, &error);
if (error != "") {
SourcePos(manifestFile, tree.getLineNumber()).error(
- "ERROR getting 'android:icon' attribute: %s", error.string());
+ "ERROR getting 'android:icon' attribute: %s", error.c_str());
goto bail;
}
int32_t testOnly = AaptXml::getIntegerAttribute(tree, TEST_ONLY_ATTR, 0,
@@ -1431,7 +1431,7 @@
if (error != "") {
SourcePos(manifestFile, tree.getLineNumber()).error(
"ERROR getting 'android:testOnly' attribute: %s",
- error.string());
+ error.c_str());
goto bail;
}
@@ -1439,15 +1439,15 @@
&error);
if (error != "") {
SourcePos(manifestFile, tree.getLineNumber()).error(
- "ERROR getting 'android:banner' attribute: %s", error.string());
+ "ERROR getting 'android:banner' attribute: %s", error.c_str());
goto bail;
}
printf("application: label='%s' ",
- ResTable::normalizeForOutput(label.string()).string());
- printf("icon='%s'", ResTable::normalizeForOutput(icon.string()).string());
+ ResTable::normalizeForOutput(label.c_str()).c_str());
+ printf("icon='%s'", ResTable::normalizeForOutput(icon.c_str()).c_str());
if (banner != "") {
printf(" banner='%s'",
- ResTable::normalizeForOutput(banner.string()).string());
+ ResTable::normalizeForOutput(banner.c_str()).c_str());
}
printf("\n");
if (testOnly != 0) {
@@ -1458,7 +1458,7 @@
ISGAME_ATTR, 0, &error);
if (error != "") {
SourcePos(manifestFile, tree.getLineNumber()).error(
- "ERROR getting 'android:isGame' attribute: %s", error.string());
+ "ERROR getting 'android:isGame' attribute: %s", error.c_str());
goto bail;
}
if (isGame != 0) {
@@ -1470,7 +1470,7 @@
if (error != "") {
SourcePos(manifestFile, tree.getLineNumber()).error(
"ERROR getting 'android:debuggable' attribute: %s",
- error.string());
+ error.c_str());
goto bail;
}
if (debuggable != 0) {
@@ -1500,12 +1500,12 @@
if (error != "") {
SourcePos(manifestFile, tree.getLineNumber()).error(
"ERROR getting 'android:minSdkVersion' attribute: %s",
- error.string());
+ error.c_str());
goto bail;
}
if (name == "Donut") targetSdk = SDK_DONUT;
printf("sdkVersion:'%s'\n",
- ResTable::normalizeForOutput(name.string()).string());
+ ResTable::normalizeForOutput(name.c_str()).c_str());
} else if (code != -1) {
targetSdk = code;
printf("sdkVersion:'%d'\n", code);
@@ -1522,7 +1522,7 @@
if (error != "") {
SourcePos(manifestFile, tree.getLineNumber()).error(
"ERROR getting 'android:targetSdkVersion' attribute: %s",
- error.string());
+ error.c_str());
goto bail;
}
if (name == "Donut" && targetSdk < SDK_DONUT) {
@@ -1532,7 +1532,7 @@
targetSdk = SDK_CUR_DEVELOPMENT;
}
printf("targetSdkVersion:'%s'\n",
- ResTable::normalizeForOutput(name.string()).string());
+ ResTable::normalizeForOutput(name.c_str()).c_str());
} else if (code != -1) {
if (targetSdk < code) {
targetSdk = code;
@@ -1592,7 +1592,7 @@
group.label = AaptXml::getResolvedAttribute(res, tree, LABEL_ATTR, &error);
if (error != "") {
SourcePos(manifestFile, tree.getLineNumber()).error(
- "ERROR getting 'android:label' attribute: %s", error.string());
+ "ERROR getting 'android:label' attribute: %s", error.c_str());
goto bail;
}
featureGroups.add(group);
@@ -1608,7 +1608,7 @@
if (error != "") {
SourcePos(manifestFile, tree.getLineNumber()).error(
"failed to read attribute 'android:required': %s",
- error.string());
+ error.c_str());
goto bail;
}
@@ -1617,7 +1617,7 @@
if (error != "") {
SourcePos(manifestFile, tree.getLineNumber()).error(
"failed to read attribute 'android:version': %s",
- error.string());
+ error.c_str());
goto bail;
}
@@ -1638,7 +1638,7 @@
String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error);
if (error != "") {
SourcePos(manifestFile, tree.getLineNumber()).error(
- "ERROR getting 'android:name' attribute: %s", error.string());
+ "ERROR getting 'android:name' attribute: %s", error.c_str());
goto bail;
}
@@ -1682,7 +1682,7 @@
String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error);
if (error != "") {
SourcePos(manifestFile, tree.getLineNumber()).error(
- "ERROR getting 'android:name' attribute: %s", error.string());
+ "ERROR getting 'android:name' attribute: %s", error.c_str());
goto bail;
}
@@ -1701,37 +1701,37 @@
String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error);
if (name != "" && error == "") {
printf("uses-package:'%s'\n",
- ResTable::normalizeForOutput(name.string()).string());
+ ResTable::normalizeForOutput(name.c_str()).c_str());
} else {
SourcePos(manifestFile, tree.getLineNumber()).error(
- "ERROR getting 'android:name' attribute: %s", error.string());
+ "ERROR getting 'android:name' attribute: %s", error.c_str());
goto bail;
}
} else if (tag == "original-package") {
String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error);
if (name != "" && error == "") {
printf("original-package:'%s'\n",
- ResTable::normalizeForOutput(name.string()).string());
+ ResTable::normalizeForOutput(name.c_str()).c_str());
} else {
SourcePos(manifestFile, tree.getLineNumber()).error(
- "ERROR getting 'android:name' attribute: %s", error.string());
+ "ERROR getting 'android:name' attribute: %s", error.c_str());
goto bail;
}
} else if (tag == "supports-gl-texture") {
String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error);
if (name != "" && error == "") {
printf("supports-gl-texture:'%s'\n",
- ResTable::normalizeForOutput(name.string()).string());
+ ResTable::normalizeForOutput(name.c_str()).c_str());
} else {
SourcePos(manifestFile, tree.getLineNumber()).error(
- "ERROR getting 'android:name' attribute: %s", error.string());
+ "ERROR getting 'android:name' attribute: %s", error.c_str());
goto bail;
}
} else if (tag == "compatible-screens") {
printCompatibleScreens(tree, &error);
if (error != "") {
SourcePos(manifestFile, tree.getLineNumber()).error(
- "ERROR getting compatible screens: %s", error.string());
+ "ERROR getting compatible screens: %s", error.c_str());
goto bail;
}
depth--;
@@ -1742,8 +1742,8 @@
&error);
if (publicKey != "" && error == "") {
printf("package-verifier: name='%s' publicKey='%s'\n",
- ResTable::normalizeForOutput(name.string()).string(),
- ResTable::normalizeForOutput(publicKey.string()).string());
+ ResTable::normalizeForOutput(name.c_str()).c_str(),
+ ResTable::normalizeForOutput(publicKey.c_str()).c_str());
}
}
}
@@ -1769,7 +1769,7 @@
if (error != "") {
SourcePos(manifestFile, tree.getLineNumber()).error(
"ERROR getting 'android:name' attribute: %s",
- error.string());
+ error.c_str());
goto bail;
}
@@ -1778,7 +1778,7 @@
if (error != "") {
SourcePos(manifestFile, tree.getLineNumber()).error(
"ERROR getting 'android:label' attribute: %s",
- error.string());
+ error.c_str());
goto bail;
}
@@ -1787,7 +1787,7 @@
if (error != "") {
SourcePos(manifestFile, tree.getLineNumber()).error(
"ERROR getting 'android:icon' attribute: %s",
- error.string());
+ error.c_str());
goto bail;
}
@@ -1796,7 +1796,7 @@
if (error != "") {
SourcePos(manifestFile, tree.getLineNumber()).error(
"ERROR getting 'android:banner' attribute: %s",
- error.string());
+ error.c_str());
goto bail;
}
@@ -1824,14 +1824,14 @@
if (error != "") {
SourcePos(manifestFile, tree.getLineNumber()).error(
"ERROR getting 'android:name' attribute for uses-library"
- " %s", error.string());
+ " %s", error.c_str());
goto bail;
}
int req = AaptXml::getIntegerAttribute(tree,
REQUIRED_ATTR, 1);
printf("uses-library%s:'%s'\n",
req ? "" : "-not-required", ResTable::normalizeForOutput(
- libraryName.string()).string());
+ libraryName.c_str()).c_str());
} else if (tag == "receiver") {
withinReceiver = true;
receiverName = AaptXml::getAttribute(tree, NAME_ATTR, &error);
@@ -1839,7 +1839,7 @@
if (error != "") {
SourcePos(manifestFile, tree.getLineNumber()).error(
"ERROR getting 'android:name' attribute for receiver:"
- " %s", error.string());
+ " %s", error.c_str());
goto bail;
}
@@ -1853,7 +1853,7 @@
SourcePos(manifestFile, tree.getLineNumber()).error(
"ERROR getting 'android:permission' attribute for"
" receiver '%s': %s",
- receiverName.string(), error.string());
+ receiverName.c_str(), error.c_str());
}
} else if (tag == "service") {
withinService = true;
@@ -1862,7 +1862,7 @@
if (error != "") {
SourcePos(manifestFile, tree.getLineNumber()).error(
"ERROR getting 'android:name' attribute for "
- "service:%s", error.string());
+ "service:%s", error.c_str());
goto bail;
}
@@ -1887,7 +1887,7 @@
} else {
SourcePos(manifestFile, tree.getLineNumber()).error(
"ERROR getting 'android:permission' attribute for "
- "service '%s': %s", serviceName.string(), error.string());
+ "service '%s': %s", serviceName.c_str(), error.c_str());
}
} else if (tag == "provider") {
withinProvider = true;
@@ -1897,7 +1897,7 @@
if (error != "") {
SourcePos(manifestFile, tree.getLineNumber()).error(
"ERROR getting 'android:exported' attribute for provider:"
- " %s", error.string());
+ " %s", error.c_str());
goto bail;
}
@@ -1906,7 +1906,7 @@
if (error != "") {
SourcePos(manifestFile, tree.getLineNumber()).error(
"ERROR getting 'android:grantUriPermissions' attribute for "
- "provider: %s", error.string());
+ "provider: %s", error.c_str());
goto bail;
}
@@ -1915,7 +1915,7 @@
if (error != "") {
SourcePos(manifestFile, tree.getLineNumber()).error(
"ERROR getting 'android:permission' attribute for "
- "provider: %s", error.string());
+ "provider: %s", error.c_str());
goto bail;
}
@@ -1928,11 +1928,11 @@
if (error != "") {
SourcePos(manifestFile, tree.getLineNumber()).error(
"ERROR getting 'android:name' attribute for "
- "meta-data: %s", error.string());
+ "meta-data: %s", error.c_str());
goto bail;
}
printf("meta-data: name='%s' ",
- ResTable::normalizeForOutput(metaDataName.string()).string());
+ ResTable::normalizeForOutput(metaDataName.c_str()).c_str());
printResolvedResourceAttribute(res, tree, VALUE_ATTR, String8("value"),
&error);
if (error != "") {
@@ -1944,7 +1944,7 @@
SourcePos(manifestFile, tree.getLineNumber()).error(
"ERROR getting 'android:value' or "
"'android:resource' attribute for "
- "meta-data: %s", error.string());
+ "meta-data: %s", error.c_str());
goto bail;
}
}
@@ -1956,7 +1956,7 @@
} else {
SourcePos(manifestFile, tree.getLineNumber()).error(
"ERROR getting 'android:name' attribute: %s",
- error.string());
+ error.c_str());
goto bail;
}
}
@@ -1969,13 +1969,13 @@
Feature feature(true);
int32_t featureVers = AaptXml::getIntegerAttribute(
- tree, androidSchema.string(), "version", 0, &error);
+ tree, androidSchema.c_str(), "version", 0, &error);
if (error == "") {
feature.version = featureVers;
} else {
SourcePos(manifestFile, tree.getLineNumber()).error(
"failed to read attribute 'android:version': %s",
- error.string());
+ error.c_str());
goto bail;
}
@@ -2016,8 +2016,8 @@
if (error != "") {
SourcePos(manifestFile, tree.getLineNumber()).error(
"ERROR getting 'android:name' attribute for "
- "meta-data tag in service '%s': %s", serviceName.string(),
- error.string());
+ "meta-data tag in service '%s': %s", serviceName.c_str(),
+ error.c_str());
goto bail;
}
@@ -2034,7 +2034,7 @@
SourcePos(manifestFile, tree.getLineNumber()).error(
"ERROR getting 'android:resource' attribute for "
"meta-data tag in service '%s': %s",
- serviceName.string(), error.string());
+ serviceName.c_str(), error.c_str());
goto bail;
}
@@ -2043,7 +2043,7 @@
if (error != "") {
SourcePos(manifestFile, tree.getLineNumber()).error(
"ERROR getting AID category for service '%s'",
- serviceName.string());
+ serviceName.c_str());
goto bail;
}
@@ -2064,7 +2064,7 @@
action = AaptXml::getAttribute(tree, NAME_ATTR, &error);
if (error != "") {
SourcePos(manifestFile, tree.getLineNumber()).error(
- "ERROR getting 'android:name' attribute: %s", error.string());
+ "ERROR getting 'android:name' attribute: %s", error.c_str());
goto bail;
}
@@ -2120,7 +2120,7 @@
String8 category = AaptXml::getAttribute(tree, NAME_ATTR, &error);
if (error != "") {
SourcePos(manifestFile, tree.getLineNumber()).error(
- "ERROR getting 'name' attribute: %s", error.string());
+ "ERROR getting 'name' attribute: %s", error.c_str());
goto bail;
}
if (withinActivity) {
@@ -2352,7 +2352,7 @@
printf("locales:");
const size_t NL = locales.size();
for (size_t i=0; i<NL; i++) {
- const char* localeStr = locales[i].string();
+ const char* localeStr = locales[i].c_str();
if (localeStr == NULL || strlen(localeStr) == 0) {
localeStr = "--_--";
}
@@ -2373,7 +2373,7 @@
SortedVector<String8> architectures;
for (size_t i=0; i<dir->getFileCount(); i++) {
architectures.add(ResTable::normalizeForOutput(
- dir->getFileName(i).string()));
+ dir->getFileName(i).c_str()));
}
bool outputAltNativeCode = false;
@@ -2401,7 +2401,7 @@
}
if (index >= 0) {
- printf("native-code: '%s'\n", architectures[index].string());
+ printf("native-code: '%s'\n", architectures[index].c_str());
architectures.removeAt(index);
outputAltNativeCode = true;
}
@@ -2414,7 +2414,7 @@
}
printf("native-code:");
for (size_t i = 0; i < archCount; i++) {
- printf(" '%s'", architectures[i].string());
+ printf(" '%s'", architectures[i].c_str());
}
printf("\n");
}
@@ -2428,7 +2428,7 @@
res.getConfigurations(&configs);
const size_t N = configs.size();
for (size_t i=0; i<N; i++) {
- printf("%s\n", configs[i].toString().string());
+ printf("%s\n", configs[i].toString().c_str());
}
} else {
fprintf(stderr, "ERROR: unknown dump option '%s'\n", option);
@@ -2486,15 +2486,15 @@
for (int i = 1; i < bundle->getFileSpecCount(); i++) {
const char* fileName = bundle->getFileSpecEntry(i);
- if (strcasecmp(String8(fileName).getPathExtension().string(), ".gz") == 0) {
+ if (strcasecmp(String8(fileName).getPathExtension().c_str(), ".gz") == 0) {
printf(" '%s'... (from gzip)\n", fileName);
- result = zip->addGzip(fileName, String8(fileName).getBasePath().string(), NULL);
+ result = zip->addGzip(fileName, String8(fileName).getBasePath().c_str(), NULL);
} else {
if (bundle->getJunkPath()) {
String8 storageName = String8(fileName).getPathLeaf();
printf(" '%s' as '%s'...\n", fileName,
- ResTable::normalizeForOutput(storageName.string()).string());
- result = zip->add(fileName, storageName.string(),
+ ResTable::normalizeForOutput(storageName.c_str()).c_str());
+ result = zip->add(fileName, storageName.c_str(),
bundle->getCompressionMethod(), NULL);
} else {
printf(" '%s'...\n", fileName);
@@ -2581,7 +2581,7 @@
for (size_t i = 0; i < numDirs; i++) {
bool ignore = ignoreConfig;
const sp<AaptDir>& subDir = dir->getDirs().valueAt(i);
- const char* dirStr = subDir->getLeaf().string();
+ const char* dirStr = subDir->getLeaf().c_str();
if (!ignore && strstr(dirStr, "mipmap") == dirStr) {
ignore = true;
}
@@ -2604,7 +2604,7 @@
}
if (err != NO_ERROR) {
fprintf(stderr, "Failed to add %s (%s) to builder.\n",
- gp->getPath().string(), gp->getFiles()[j]->getPrintableSource().string());
+ gp->getPath().c_str(), gp->getFiles()[j]->getPrintableSource().c_str());
return err;
}
}
@@ -2620,13 +2620,13 @@
String8 ext(original.getPathExtension());
if (ext == String8(".apk")) {
return String8::format("%s_%s%s",
- original.getBasePath().string(),
- split->getDirectorySafeName().string(),
- ext.string());
+ original.getBasePath().c_str(),
+ split->getDirectorySafeName().c_str(),
+ ext.c_str());
}
- return String8::format("%s_%s", original.string(),
- split->getDirectorySafeName().string());
+ return String8::format("%s_%s", original.c_str(),
+ split->getDirectorySafeName().c_str());
}
/*
@@ -2712,7 +2712,7 @@
for (size_t i = 0; i < numSplits; i++) {
std::set<ConfigDescription> configs;
if (!AaptConfig::parseCommaSeparatedList(splitStrs[i], &configs)) {
- fprintf(stderr, "ERROR: failed to parse split configuration '%s'\n", splitStrs[i].string());
+ fprintf(stderr, "ERROR: failed to parse split configuration '%s'\n", splitStrs[i].c_str());
goto bail;
}
@@ -2835,7 +2835,7 @@
String8 outputPath = buildApkName(String8(outputAPKFile), split);
err = writeAPK(bundle, outputPath, split);
if (err != NO_ERROR) {
- fprintf(stderr, "ERROR: packaging of '%s' failed\n", outputPath.string());
+ fprintf(stderr, "ERROR: packaging of '%s' failed\n", outputPath.c_str());
goto bail;
}
}
diff --git a/tools/aapt/CrunchCache.cpp b/tools/aapt/CrunchCache.cpp
index 7b8a576..1f2febe 100644
--- a/tools/aapt/CrunchCache.cpp
+++ b/tools/aapt/CrunchCache.cpp
@@ -44,7 +44,7 @@
// This efficiently strips the source directory prefix from our path.
// Also, String8 doesn't have a substring method so this is what we've
// got to work with.
- const char* rPathPtr = mSourceFiles.keyAt(0).string()+mSourcePath.length();
+ const char* rPathPtr = mSourceFiles.keyAt(0).c_str()+mSourcePath.length();
// Strip leading slash if present
int offset = 0;
if (rPathPtr[0] == OS_PATH_SEPARATOR)
diff --git a/tools/aapt/DirectoryWalker.h b/tools/aapt/DirectoryWalker.h
index 88031d0..cea3a6e 100644
--- a/tools/aapt/DirectoryWalker.h
+++ b/tools/aapt/DirectoryWalker.h
@@ -57,7 +57,7 @@
virtual bool openDir(String8 path) {
mBasePath = path;
dir = NULL;
- dir = opendir(mBasePath.string() );
+ dir = opendir(mBasePath.c_str() );
if (dir == NULL)
return false;
@@ -78,7 +78,7 @@
mEntry = *entryPtr;
// Get stats
String8 fullPath = mBasePath.appendPathCopy(mEntry.d_name);
- stat(fullPath.string(),&mStats);
+ stat(fullPath.c_str(),&mStats);
return &mEntry;
};
// Get the stats for the current entry
diff --git a/tools/aapt/FileFinder.cpp b/tools/aapt/FileFinder.cpp
index c9d0744..a5c19806 100644
--- a/tools/aapt/FileFinder.cpp
+++ b/tools/aapt/FileFinder.cpp
@@ -59,14 +59,14 @@
String8 fullPath = basePath.appendPathCopy(entryName);
// If this entry is a directory we'll recurse into it
- if (isDirectory(fullPath.string()) ) {
+ if (isDirectory(fullPath.c_str()) ) {
DirectoryWalker* copy = dw->clone();
findFiles(fullPath, extensions, fileStore,copy);
delete copy;
}
// If this entry is a file, we'll pass it over to checkAndAddFile
- if (isFile(fullPath.string()) ) {
+ if (isFile(fullPath.c_str()) ) {
checkAndAddFile(fullPath,dw->entryStats(),extensions,fileStore);
}
}
diff --git a/tools/aapt/Images.cpp b/tools/aapt/Images.cpp
index 627a231..c6c7e96 100644
--- a/tools/aapt/Images.cpp
+++ b/tools/aapt/Images.cpp
@@ -1328,13 +1328,13 @@
png_init_io(read_ptr, fp);
- read_png(printableName.string(), read_ptr, read_info, imageInfo);
+ read_png(printableName.c_str(), read_ptr, read_info, imageInfo);
const size_t nameLen = file->getPath().length();
if (nameLen > 6) {
- const char* name = file->getPath().string();
+ const char* name = file->getPath().c_str();
if (name[nameLen-5] == '9' && name[nameLen-6] == '.') {
- if (do_9patch(printableName.string(), imageInfo) != NO_ERROR) {
+ if (do_9patch(printableName.c_str(), imageInfo) != NO_ERROR) {
return false;
}
}
@@ -1349,7 +1349,7 @@
return false;
}
- write_png(printableName.string(), write_ptr, write_info, *imageInfo, bundle);
+ write_png(printableName.c_str(), write_ptr, write_info, *imageInfo, bundle);
return true;
}
@@ -1360,7 +1360,7 @@
String8 ext(file->getPath().getPathExtension());
// We currently only process PNG images.
- if (strcmp(ext.string(), ".png") != 0) {
+ if (strcmp(ext.c_str(), ".png") != 0) {
return NO_ERROR;
}
@@ -1371,7 +1371,7 @@
String8 printableName(file->getPrintableSource());
if (bundle->getVerbose()) {
- printf("Processing image: %s\n", printableName.string());
+ printf("Processing image: %s\n", printableName.c_str());
}
png_structp read_ptr = NULL;
@@ -1385,9 +1385,9 @@
status_t error = UNKNOWN_ERROR;
- fp = fopen(file->getSourceFile().string(), "rb");
+ fp = fopen(file->getSourceFile().c_str(), "rb");
if (fp == NULL) {
- fprintf(stderr, "%s: ERROR: Unable to open PNG file\n", printableName.string());
+ fprintf(stderr, "%s: ERROR: Unable to open PNG file\n", printableName.c_str());
goto bail;
}
@@ -1434,7 +1434,7 @@
size_t newSize = file->getSize();
float factor = ((float)newSize)/oldSize;
int percent = (int)(factor*100);
- printf(" (processed image %s: %d%% size of source)\n", printableName.string(), percent);
+ printf(" (processed image %s: %d%% size of source)\n", printableName.c_str(), percent);
}
bail:
@@ -1450,7 +1450,7 @@
if (error != NO_ERROR) {
fprintf(stderr, "ERROR: Failure processing PNG image %s\n",
- file->getPrintableSource().string());
+ file->getPrintableSource().c_str());
}
return error;
}
@@ -1470,13 +1470,13 @@
status_t error = UNKNOWN_ERROR;
if (bundle->getVerbose()) {
- printf("Processing image to cache: %s => %s\n", source.string(), dest.string());
+ printf("Processing image to cache: %s => %s\n", source.c_str(), dest.c_str());
}
// Get a file handler to read from
- fp = fopen(source.string(),"rb");
+ fp = fopen(source.c_str(),"rb");
if (fp == NULL) {
- fprintf(stderr, "%s ERROR: Unable to open PNG file\n", source.string());
+ fprintf(stderr, "%s ERROR: Unable to open PNG file\n", source.c_str());
return error;
}
@@ -1507,7 +1507,7 @@
png_init_io(read_ptr,fp);
// Actually read data from the file
- read_png(source.string(), read_ptr, read_info, &imageInfo);
+ read_png(source.c_str(), read_ptr, read_info, &imageInfo);
// We're done reading so we can clean up
// Find old file size before releasing handle
@@ -1519,7 +1519,7 @@
// Check to see if we're dealing with a 9-patch
// If we are, process appropriately
if (source.getBasePath().getPathExtension() == ".9") {
- if (do_9patch(source.string(), &imageInfo) != NO_ERROR) {
+ if (do_9patch(source.c_str(), &imageInfo) != NO_ERROR) {
return error;
}
}
@@ -1541,9 +1541,9 @@
}
// Open up our destination file for writing
- fp = fopen(dest.string(), "wb");
+ fp = fopen(dest.c_str(), "wb");
if (!fp) {
- fprintf(stderr, "%s ERROR: Unable to open PNG file\n", dest.string());
+ fprintf(stderr, "%s ERROR: Unable to open PNG file\n", dest.c_str());
png_destroy_write_struct(&write_ptr, &write_info);
return error;
}
@@ -1559,11 +1559,11 @@
}
// Actually write out to the new png
- write_png(dest.string(), write_ptr, write_info, imageInfo, bundle);
+ write_png(dest.c_str(), write_ptr, write_info, imageInfo, bundle);
if (bundle->getVerbose()) {
// Find the size of our new file
- FILE* reader = fopen(dest.string(), "rb");
+ FILE* reader = fopen(dest.c_str(), "rb");
fseek(reader, 0, SEEK_END);
size_t newSize = (size_t)ftell(reader);
fclose(reader);
@@ -1571,7 +1571,7 @@
float factor = ((float)newSize)/oldSize;
int percent = (int)(factor*100);
printf(" (processed image to cache entry %s: %d%% size of source)\n",
- dest.string(), percent);
+ dest.c_str(), percent);
}
//Clean up
@@ -1588,7 +1588,7 @@
// At this point, now that we have all the resource data, all we need to
// do is compile XML files.
- if (strcmp(ext.string(), ".xml") == 0) {
+ if (strcmp(ext.c_str(), ".xml") == 0) {
String16 resourceName(parseResourceName(file->getSourceFile().getPathLeaf()));
return compileXmlFile(bundle, assets, resourceName, file, table);
}
diff --git a/tools/aapt/Package.cpp b/tools/aapt/Package.cpp
index f06643dc..965655b 100644
--- a/tools/aapt/Package.cpp
+++ b/tools/aapt/Package.cpp
@@ -69,39 +69,39 @@
* If "update" is set, update the contents of the existing archive.
* Else, if "force" is set, remove the existing archive.
*/
- FileType fileType = getFileType(outputFile.string());
+ FileType fileType = getFileType(outputFile.c_str());
if (fileType == kFileTypeNonexistent) {
// okay, create it below
} else if (fileType == kFileTypeRegular) {
if (bundle->getUpdate()) {
// okay, open it below
} else if (bundle->getForce()) {
- if (unlink(outputFile.string()) != 0) {
- fprintf(stderr, "ERROR: unable to remove '%s': %s\n", outputFile.string(),
+ if (unlink(outputFile.c_str()) != 0) {
+ fprintf(stderr, "ERROR: unable to remove '%s': %s\n", outputFile.c_str(),
strerror(errno));
goto bail;
}
} else {
fprintf(stderr, "ERROR: '%s' exists (use '-f' to force overwrite)\n",
- outputFile.string());
+ outputFile.c_str());
goto bail;
}
} else {
- fprintf(stderr, "ERROR: '%s' exists and is not a regular file\n", outputFile.string());
+ fprintf(stderr, "ERROR: '%s' exists and is not a regular file\n", outputFile.c_str());
goto bail;
}
if (bundle->getVerbose()) {
printf("%s '%s'\n", (fileType == kFileTypeNonexistent) ? "Creating" : "Opening",
- outputFile.string());
+ outputFile.c_str());
}
status_t status;
zip = new ZipFile;
- status = zip->open(outputFile.string(), ZipFile::kOpenReadWrite | ZipFile::kOpenCreate);
+ status = zip->open(outputFile.c_str(), ZipFile::kOpenReadWrite | ZipFile::kOpenCreate);
if (status != NO_ERROR) {
fprintf(stderr, "ERROR: unable to open '%s' as Zip file for writing\n",
- outputFile.string());
+ outputFile.c_str());
goto bail;
}
@@ -112,7 +112,7 @@
count = processAssets(bundle, zip, outputSet);
if (count < 0) {
fprintf(stderr, "ERROR: unable to process assets while packaging '%s'\n",
- outputFile.string());
+ outputFile.c_str());
result = count;
goto bail;
}
@@ -124,7 +124,7 @@
count = processJarFiles(bundle, zip);
if (count < 0) {
fprintf(stderr, "ERROR: unable to process jar files while packaging '%s'\n",
- outputFile.string());
+ outputFile.c_str());
result = count;
goto bail;
}
@@ -169,12 +169,12 @@
/* anything here? */
if (zip->getNumEntries() == 0) {
if (bundle->getVerbose()) {
- printf("Archive is empty -- removing %s\n", outputFile.getPathLeaf().string());
+ printf("Archive is empty -- removing %s\n", outputFile.getPathLeaf().c_str());
}
delete zip; // close the file so we can remove it in Win32
zip = NULL;
- if (unlink(outputFile.string()) != 0) {
- fprintf(stderr, "warning: could not unlink '%s'\n", outputFile.string());
+ if (unlink(outputFile.c_str()) != 0) {
+ fprintf(stderr, "warning: could not unlink '%s'\n", outputFile.c_str());
}
}
@@ -187,9 +187,9 @@
String8 dependencyFile = outputFile;
dependencyFile.append(".d");
- FILE* fp = fopen(dependencyFile.string(), "a");
+ FILE* fp = fopen(dependencyFile.c_str(), "a");
// Add this file to the dependency file
- fprintf(fp, "%s \\\n", outputFile.string());
+ fprintf(fp, "%s \\\n", outputFile.c_str());
fclose(fp);
}
@@ -199,10 +199,10 @@
delete zip; // must close before remove in Win32
if (result != NO_ERROR) {
if (bundle->getVerbose()) {
- printf("Removing %s due to earlier failures\n", outputFile.string());
+ printf("Removing %s due to earlier failures\n", outputFile.c_str());
}
- if (unlink(outputFile.string()) != 0) {
- fprintf(stderr, "warning: could not unlink '%s'\n", outputFile.string());
+ if (unlink(outputFile.c_str()) != 0) {
+ fprintf(stderr, "warning: could not unlink '%s'\n", outputFile.c_str());
}
}
@@ -267,31 +267,31 @@
int fileNameLen = storageName.length();
int excludeExtensionLen = strlen(kExcludeExtension);
if (fileNameLen > excludeExtensionLen
- && (0 == strcmp(storageName.string() + (fileNameLen - excludeExtensionLen),
+ && (0 == strcmp(storageName.c_str() + (fileNameLen - excludeExtensionLen),
kExcludeExtension))) {
- fprintf(stderr, "warning: '%s' not added to Zip\n", storageName.string());
+ fprintf(stderr, "warning: '%s' not added to Zip\n", storageName.c_str());
return true;
}
- if (strcasecmp(storageName.getPathExtension().string(), ".gz") == 0) {
+ if (strcasecmp(storageName.getPathExtension().c_str(), ".gz") == 0) {
fromGzip = true;
storageName = storageName.getBasePath();
}
if (bundle->getUpdate()) {
- entry = zip->getEntryByName(storageName.string());
+ entry = zip->getEntryByName(storageName.c_str());
if (entry != NULL) {
/* file already exists in archive; there can be only one */
if (entry->getMarked()) {
fprintf(stderr,
"ERROR: '%s' exists twice (check for with & w/o '.gz'?)\n",
- file->getPrintableSource().string());
+ file->getPrintableSource().c_str());
return false;
}
if (!hasData) {
const String8& srcName = file->getSourceFile();
time_t fileModWhen;
- fileModWhen = getFileModDate(srcName.string());
+ fileModWhen = getFileModDate(srcName.c_str());
if (fileModWhen == (time_t) -1) { // file existence tested earlier,
return false; // not expecting an error here
}
@@ -299,14 +299,14 @@
if (fileModWhen > entry->getModWhen()) {
// mark as deleted so add() will succeed
if (bundle->getVerbose()) {
- printf(" (removing old '%s')\n", storageName.string());
+ printf(" (removing old '%s')\n", storageName.c_str());
}
zip->remove(entry);
} else {
// version in archive is newer
if (bundle->getVerbose()) {
- printf(" (not updating '%s')\n", storageName.string());
+ printf(" (not updating '%s')\n", storageName.c_str());
}
entry->setMarked(true);
return true;
@@ -321,22 +321,22 @@
//android_setMinPriority(NULL, ANDROID_LOG_VERBOSE);
if (fromGzip) {
- result = zip->addGzip(file->getSourceFile().string(), storageName.string(), &entry);
+ result = zip->addGzip(file->getSourceFile().c_str(), storageName.c_str(), &entry);
} else if (!hasData) {
/* don't compress certain files, e.g. PNGs */
int compressionMethod = bundle->getCompressionMethod();
if (!okayToCompress(bundle, storageName)) {
compressionMethod = ZipEntry::kCompressStored;
}
- result = zip->add(file->getSourceFile().string(), storageName.string(), compressionMethod,
+ result = zip->add(file->getSourceFile().c_str(), storageName.c_str(), compressionMethod,
&entry);
} else {
- result = zip->add(file->getData(), file->getSize(), storageName.string(),
+ result = zip->add(file->getData(), file->getSize(), storageName.c_str(),
file->getCompressionMethod(), &entry);
}
if (result == NO_ERROR) {
if (bundle->getVerbose()) {
- printf(" '%s'%s", storageName.string(), fromGzip ? " (from .gz)" : "");
+ printf(" '%s'%s", storageName.c_str(), fromGzip ? " (from .gz)" : "");
if (entry->getCompressionMethod() == ZipEntry::kCompressStored) {
printf(" (not compressed)\n");
} else {
@@ -348,10 +348,10 @@
} else {
if (result == ALREADY_EXISTS) {
fprintf(stderr, " Unable to add '%s': file already in archive (try '-u'?)\n",
- file->getPrintableSource().string());
+ file->getPrintableSource().c_str());
} else {
fprintf(stderr, " Unable to add '%s': Zip add failed (%d)\n",
- file->getPrintableSource().string(), result);
+ file->getPrintableSource().c_str(), result);
}
return false;
}
@@ -372,7 +372,7 @@
return true;
for (i = 0; i < NELEM(kNoCompressExt); i++) {
- if (strcasecmp(ext.string(), kNoCompressExt[i]) == 0)
+ if (strcasecmp(ext.c_str(), kNoCompressExt[i]) == 0)
return false;
}
@@ -383,7 +383,7 @@
if (pos < 0) {
continue;
}
- const char* path = pathName.string();
+ const char* path = pathName.c_str();
if (strcasecmp(path + pos, str) == 0) {
return false;
}
diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp
index dd3ebdb..4ca3a68 100644
--- a/tools/aapt/Resource.cpp
+++ b/tools/aapt/Resource.cpp
@@ -57,8 +57,8 @@
String8 parseResourceName(const String8& leaf)
{
- const char* firstDot = strchr(leaf.string(), '.');
- const char* str = leaf.string();
+ const char* firstDot = strchr(leaf.c_str(), '.');
+ const char* str = leaf.c_str();
if (firstDot) {
return String8(str, firstDot-str);
@@ -132,7 +132,7 @@
mParams = file->getGroupEntry().toParams();
if (kIsDebug) {
printf("Dir %s: mcc=%d mnc=%d lang=%c%c cnt=%c%c orient=%d ui=%d density=%d touch=%d key=%d inp=%d nav=%d\n",
- group->getPath().string(), mParams.mcc, mParams.mnc,
+ group->getPath().c_str(), mParams.mcc, mParams.mnc,
mParams.language[0] ? mParams.language[0] : '-',
mParams.language[1] ? mParams.language[1] : '-',
mParams.country[0] ? mParams.country[0] : '-',
@@ -147,12 +147,12 @@
mBaseName = parseResourceName(leaf);
if (mBaseName == "") {
fprintf(stderr, "Error: malformed resource filename %s\n",
- file->getPrintableSource().string());
+ file->getPrintableSource().c_str());
return UNKNOWN_ERROR;
}
if (kIsDebug) {
- printf("file name=%s\n", mBaseName.string());
+ printf("file name=%s\n", mBaseName.c_str());
}
return NO_ERROR;
@@ -222,7 +222,7 @@
{
if (grp->getFiles().size() != 1) {
fprintf(stderr, "warning: Multiple AndroidManifest.xml files found, using %s\n",
- grp->getFiles().valueAt(0)->getPrintableSource().string());
+ grp->getFiles().valueAt(0)->getPrintableSource().c_str());
}
sp<AaptFile> file = grp->getFiles().valueAt(0);
@@ -243,20 +243,20 @@
size_t len;
if (code != ResXMLTree::START_TAG) {
fprintf(stderr, "%s:%d: No start tag found\n",
- file->getPrintableSource().string(), block.getLineNumber());
+ file->getPrintableSource().c_str(), block.getLineNumber());
return UNKNOWN_ERROR;
}
- if (strcmp16(block.getElementName(&len), String16("manifest").string()) != 0) {
+ if (strcmp16(block.getElementName(&len), String16("manifest").c_str()) != 0) {
fprintf(stderr, "%s:%d: Invalid start tag %s, expected <manifest>\n",
- file->getPrintableSource().string(), block.getLineNumber(),
- String8(block.getElementName(&len)).string());
+ file->getPrintableSource().c_str(), block.getLineNumber(),
+ String8(block.getElementName(&len)).c_str());
return UNKNOWN_ERROR;
}
ssize_t nameIndex = block.indexOfAttribute(NULL, "package");
if (nameIndex < 0) {
fprintf(stderr, "%s:%d: <manifest> does not have package attribute.\n",
- file->getPrintableSource().string(), block.getLineNumber());
+ file->getPrintableSource().c_str(), block.getLineNumber());
return UNKNOWN_ERROR;
}
@@ -264,19 +264,19 @@
ssize_t revisionCodeIndex = block.indexOfAttribute(RESOURCES_ANDROID_NAMESPACE, "revisionCode");
if (revisionCodeIndex >= 0) {
- bundle->setRevisionCode(String8(block.getAttributeStringValue(revisionCodeIndex, &len)).string());
+ bundle->setRevisionCode(String8(block.getAttributeStringValue(revisionCodeIndex, &len)).c_str());
}
String16 uses_sdk16("uses-sdk");
while ((code=block.next()) != ResXMLTree::END_DOCUMENT
&& code != ResXMLTree::BAD_DOCUMENT) {
if (code == ResXMLTree::START_TAG) {
- if (strcmp16(block.getElementName(&len), uses_sdk16.string()) == 0) {
+ if (strcmp16(block.getElementName(&len), uses_sdk16.c_str()) == 0) {
ssize_t minSdkIndex = block.indexOfAttribute(RESOURCES_ANDROID_NAMESPACE,
"minSdkVersion");
if (minSdkIndex >= 0) {
const char16_t* minSdk16 = block.getAttributeStringValue(minSdkIndex, &len);
- const char* minSdk8 = strdup(String8(minSdk16).string());
+ const char* minSdk8 = strdup(String8(minSdk16).c_str());
bundle->setManifestMinSdkVersion(minSdk8);
}
}
@@ -305,17 +305,17 @@
while ((res=it.next()) == NO_ERROR) {
if (bundle->getVerbose()) {
printf(" (new resource id %s from %s)\n",
- it.getBaseName().string(), it.getFile()->getPrintableSource().string());
+ it.getBaseName().c_str(), it.getFile()->getPrintableSource().c_str());
}
String16 baseName(it.getBaseName());
- const char16_t* str = baseName.string();
+ const char16_t* str = baseName.c_str();
const char16_t* const end = str + baseName.size();
while (str < end) {
if (!((*str >= 'a' && *str <= 'z')
|| (*str >= '0' && *str <= '9')
|| *str == '_' || *str == '.')) {
fprintf(stderr, "%s: Invalid file name: must contain only [a-z0-9_.]\n",
- it.getPath().string());
+ it.getPath().c_str());
hasErrors = true;
}
str++;
@@ -413,7 +413,7 @@
sp<ResourceTypeSet> set = new ResourceTypeSet();
if (kIsDebug) {
printf("Creating new resource type set for leaf %s with group %s (%p)\n",
- leafName.string(), group->getPath().string(), group.get());
+ leafName.c_str(), group->getPath().c_str(), group.get());
}
set->add(leafName, group);
resources->add(resType, set);
@@ -423,21 +423,21 @@
if (index < 0) {
if (kIsDebug) {
printf("Adding to resource type set for leaf %s group %s (%p)\n",
- leafName.string(), group->getPath().string(), group.get());
+ leafName.c_str(), group->getPath().c_str(), group.get());
}
set->add(leafName, group);
} else {
sp<AaptGroup> existingGroup = set->valueAt(index);
if (kIsDebug) {
printf("Extending to resource type set for leaf %s group %s (%p)\n",
- leafName.string(), group->getPath().string(), group.get());
+ leafName.c_str(), group->getPath().c_str(), group.get());
}
for (size_t j=0; j<files.size(); j++) {
if (kIsDebug) {
printf("Adding file %s in group %s resType %s\n",
- files.valueAt(j)->getSourceFile().string(),
- files.keyAt(j).toDirName(String8()).string(),
- resType.string());
+ files.valueAt(j)->getSourceFile().c_str(),
+ files.keyAt(j).toDirName(String8()).c_str(),
+ resType.c_str());
}
existingGroup->addFile(files.valueAt(j));
}
@@ -455,14 +455,14 @@
for (int i=0; i<N; i++) {
const sp<AaptDir>& d = dirs.itemAt(i);
if (kIsDebug) {
- printf("Collecting dir #%d %p: %s, leaf %s\n", i, d.get(), d->getPath().string(),
- d->getLeaf().string());
+ printf("Collecting dir #%d %p: %s, leaf %s\n", i, d.get(), d->getPath().c_str(),
+ d->getLeaf().c_str());
}
collect_files(d, resources);
// don't try to include the res dir
if (kIsDebug) {
- printf("Removing dir leaf %s\n", d->getLeaf().string());
+ printf("Removing dir leaf %s\n", d->getLeaf().c_str());
}
ass->removeDir(d->getLeaf());
}
@@ -490,8 +490,8 @@
int strIdx;
if ((strIdx=table.resolveReference(&value, 0x10000000, NULL, &specFlags)) < 0) {
fprintf(stderr, "%s:%d: Tag <%s> attribute %s references unknown resid 0x%08x.\n",
- path.string(), parser.getLineNumber(),
- String8(parser.getElementName(&len)).string(), attr,
+ path.c_str(), parser.getLineNumber(),
+ String8(parser.getElementName(&len)).c_str(), attr,
value.data);
return ATTR_NOT_FOUND;
}
@@ -502,12 +502,12 @@
str = pool->stringAt(value.data, &len);
}
printf("***** RES ATTR: %s specFlags=0x%x strIdx=%d: %s\n", attr,
- specFlags, strIdx, str != NULL ? String8(str).string() : "???");
+ specFlags, strIdx, str != NULL ? String8(str).c_str() : "???");
#endif
if ((specFlags&~ResTable_typeSpec::SPEC_PUBLIC) != 0 && false) {
fprintf(stderr, "%s:%d: Tag <%s> attribute %s varies by configurations 0x%x.\n",
- path.string(), parser.getLineNumber(),
- String8(parser.getElementName(&len)).string(), attr,
+ path.c_str(), parser.getLineNumber(),
+ String8(parser.getElementName(&len)).c_str(), attr,
specFlags);
return ATTR_NOT_FOUND;
}
@@ -515,20 +515,20 @@
if (value.dataType == Res_value::TYPE_STRING) {
if (pool == NULL) {
fprintf(stderr, "%s:%d: Tag <%s> attribute %s has no string block.\n",
- path.string(), parser.getLineNumber(),
- String8(parser.getElementName(&len)).string(), attr);
+ path.c_str(), parser.getLineNumber(),
+ String8(parser.getElementName(&len)).c_str(), attr);
return ATTR_NOT_FOUND;
}
if ((str = UnpackOptionalString(pool->stringAt(value.data), &len)) == NULL) {
fprintf(stderr, "%s:%d: Tag <%s> attribute %s has corrupt string value.\n",
- path.string(), parser.getLineNumber(),
- String8(parser.getElementName(&len)).string(), attr);
+ path.c_str(), parser.getLineNumber(),
+ String8(parser.getElementName(&len)).c_str(), attr);
return ATTR_NOT_FOUND;
}
} else {
fprintf(stderr, "%s:%d: Tag <%s> attribute %s has invalid type %d.\n",
- path.string(), parser.getLineNumber(),
- String8(parser.getElementName(&len)).string(), attr,
+ path.c_str(), parser.getLineNumber(),
+ String8(parser.getElementName(&len)).c_str(), attr,
value.dataType);
return ATTR_NOT_FOUND;
}
@@ -546,30 +546,30 @@
}
if (!okay) {
fprintf(stderr, "%s:%d: Tag <%s> attribute %s has invalid character '%c'.\n",
- path.string(), parser.getLineNumber(),
- String8(parser.getElementName(&len)).string(), attr, (char)str[i]);
+ path.c_str(), parser.getLineNumber(),
+ String8(parser.getElementName(&len)).c_str(), attr, (char)str[i]);
return (int)i;
}
}
}
if (*str == ' ') {
fprintf(stderr, "%s:%d: Tag <%s> attribute %s can not start with a space.\n",
- path.string(), parser.getLineNumber(),
- String8(parser.getElementName(&len)).string(), attr);
+ path.c_str(), parser.getLineNumber(),
+ String8(parser.getElementName(&len)).c_str(), attr);
return ATTR_LEADING_SPACES;
}
if (len != 0 && str[len-1] == ' ') {
fprintf(stderr, "%s:%d: Tag <%s> attribute %s can not end with a space.\n",
- path.string(), parser.getLineNumber(),
- String8(parser.getElementName(&len)).string(), attr);
+ path.c_str(), parser.getLineNumber(),
+ String8(parser.getElementName(&len)).c_str(), attr);
return ATTR_TRAILING_SPACES;
}
return ATTR_OKAY;
}
if (required) {
fprintf(stderr, "%s:%d: Tag <%s> missing required attribute %s.\n",
- path.string(), parser.getLineNumber(),
- String8(parser.getElementName(&len)).string(), attr);
+ path.c_str(), parser.getLineNumber(),
+ String8(parser.getElementName(&len)).c_str(), attr);
return ATTR_NOT_FOUND;
}
return ATTR_OKAY;
@@ -584,7 +584,7 @@
ssize_t index = parser.indexOfAttribute(NULL, "id");
if (index >= 0) {
fprintf(stderr, "%s:%d: warning: found plain 'id' attribute; did you mean the new 'android:id' name?\n",
- path.string(), parser.getLineNumber());
+ path.c_str(), parser.getLineNumber());
}
}
}
@@ -618,7 +618,7 @@
size_t overlayCount = overlaySet->size();
for (size_t overlayIndex=0; overlayIndex<overlayCount; overlayIndex++) {
if (bundle->getVerbose()) {
- printf("trying overlaySet Key=%s\n",overlaySet->keyAt(overlayIndex).string());
+ printf("trying overlaySet Key=%s\n",overlaySet->keyAt(overlayIndex).c_str());
}
ssize_t baseIndex = -1;
if (baseSet->get() != NULL) {
@@ -638,11 +638,11 @@
baseGroup->getFiles();
for (size_t i=0; i < baseFiles.size(); i++) {
printf("baseFile " ZD " has flavor %s\n", (ZD_TYPE) i,
- baseFiles.keyAt(i).toString().string());
+ baseFiles.keyAt(i).toString().c_str());
}
for (size_t i=0; i < overlayFiles.size(); i++) {
printf("overlayFile " ZD " has flavor %s\n", (ZD_TYPE) i,
- overlayFiles.keyAt(i).toString().string());
+ overlayFiles.keyAt(i).toString().c_str());
}
}
@@ -657,16 +657,16 @@
if (bundle->getVerbose()) {
printf("found a match (" ZD ") for overlay file %s, for flavor %s\n",
(ZD_TYPE) baseFileIndex,
- overlayGroup->getLeaf().string(),
- overlayFiles.keyAt(overlayGroupIndex).toString().string());
+ overlayGroup->getLeaf().c_str(),
+ overlayFiles.keyAt(overlayGroupIndex).toString().c_str());
}
baseGroup->removeFile(baseFileIndex);
} else {
// didn't find a match fall through and add it..
if (true || bundle->getVerbose()) {
printf("nothing matches overlay file %s, for flavor %s\n",
- overlayGroup->getLeaf().string(),
- overlayFiles.keyAt(overlayGroupIndex).toString().string());
+ overlayGroup->getLeaf().c_str(),
+ overlayFiles.keyAt(overlayGroupIndex).toString().c_str());
}
}
baseGroup->addFile(overlayFiles.valueAt(overlayGroupIndex));
@@ -728,7 +728,7 @@
if (errorOnFailedInsert) {
fprintf(stderr, "Error: AndroidManifest.xml already defines %s (in %s);"
" cannot insert new value %s.\n",
- String8(attr).string(), String8(ns).string(), value);
+ String8(attr).c_str(), String8(ns).c_str(), value);
return false;
}
@@ -763,7 +763,7 @@
// .asdf .a.b --> package.asdf package.a.b
// asdf.adsf --> asdf.asdf
String8 className;
- const char* p = name.string();
+ const char* p = name.c_str();
const char* q = strchr(p, '.');
if (p == q) {
className += package;
@@ -776,7 +776,7 @@
className += name;
}
if (kIsDebug) {
- printf("Qualifying class '%s' to '%s'", name.string(), className.string());
+ printf("Qualifying class '%s' to '%s'", name.c_str(), className.c_str());
}
attr->string.setTo(String16(className));
}
@@ -810,7 +810,7 @@
const char* err;
String16 iconPackage, iconType, iconName;
- if (!ResTable::expandResourceRef(iconRef.string(), iconRef.size(), &iconPackage, &iconType,
+ if (!ResTable::expandResourceRef(iconRef.c_str(), iconRef.size(), &iconPackage, &iconType,
&iconName, NULL, &table->getAssetsPackage(), &err,
&publicOnly)) {
// Errors will be raised in later XML compilation.
@@ -824,7 +824,7 @@
}
String16 roundIconPackage, roundIconType, roundIconName;
- if (!ResTable::expandResourceRef(roundIconRef.string(), roundIconRef.size(), &roundIconPackage,
+ if (!ResTable::expandResourceRef(roundIconRef.c_str(), roundIconRef.size(), &roundIconPackage,
&roundIconType, &roundIconName, NULL, &table->getAssetsPackage(),
&err, &publicOnly)) {
// Errors will be raised in later XML compilation.
@@ -839,9 +839,9 @@
return;
}
- String16 aliasValue = String16(String8::format("@%s:%s/%s", String8(iconPackage).string(),
- String8(iconType).string(),
- String8(iconName).string()));
+ String16 aliasValue = String16(String8::format("@%s:%s/%s", String8(iconPackage).c_str(),
+ String8(iconType).c_str(),
+ String8(iconName).c_str()));
// Add an equivalent v26 entry to the roundIcon for each v26 variant of the regular icon.
const DefaultKeyedVector<ConfigDescription, sp<ResourceTable::Entry>>& configList =
@@ -872,7 +872,7 @@
const XMLNode::attribute_entry* attr = root->getAttribute(
String16(RESOURCES_ANDROID_NAMESPACE), String16("versionCode"));
if (attr != NULL) {
- bundle->setVersionCode(strdup(String8(attr->string).string()));
+ bundle->setVersionCode(strdup(String8(attr->string).c_str()));
}
}
@@ -883,7 +883,7 @@
const XMLNode::attribute_entry* attr = root->getAttribute(
String16(RESOURCES_ANDROID_NAMESPACE), String16("versionName"));
if (attr != NULL) {
- bundle->setVersionName(strdup(String8(attr->string).string()));
+ bundle->setVersionName(strdup(String8(attr->string).c_str()));
}
}
@@ -914,7 +914,7 @@
const XMLNode::attribute_entry* attr = vers->getAttribute(
String16(RESOURCES_ANDROID_NAMESPACE), String16("minSdkVersion"));
if (attr != NULL) {
- bundle->setMinSdkVersion(strdup(String8(attr->string).string()));
+ bundle->setMinSdkVersion(strdup(String8(attr->string).c_str()));
}
}
@@ -970,7 +970,7 @@
String8 origPackage(attr->string);
attr->string.setTo(String16(manifestPackageNameOverride));
if (kIsDebug) {
- printf("Overriding package '%s' to be '%s'\n", origPackage.string(),
+ printf("Overriding package '%s' to be '%s'\n", origPackage.c_str(),
manifestPackageNameOverride);
}
@@ -1071,7 +1071,7 @@
static ssize_t extractPlatformBuildVersion(const ResTable& table, ResXMLTree& tree, Bundle* bundle) {
// First check if we should be recording the compileSdkVersion* attributes.
static const String16 compileSdkVersionName("android:attr/compileSdkVersion");
- const bool useCompileSdkVersion = table.identifierForName(compileSdkVersionName.string(),
+ const bool useCompileSdkVersion = table.identifierForName(compileSdkVersionName.c_str(),
compileSdkVersionName.size()) != 0u;
size_t len;
@@ -1223,7 +1223,7 @@
// Add the 'revisionCode' attribute, which is set to the original revisionCode.
if (bundle->getRevisionCode().size() > 0) {
if (!addTagAttribute(manifest, RESOURCES_ANDROID_NAMESPACE, "revisionCode",
- bundle->getRevisionCode().string(), true, true)) {
+ bundle->getRevisionCode().c_str(), true, true)) {
return UNKNOWN_ERROR;
}
}
@@ -1270,7 +1270,7 @@
}
if (kIsDebug) {
- printf("Creating resources for package %s\n", assets->getPackage().string());
+ printf("Creating resources for package %s\n", assets->getPackage().c_str());
}
// Set the private symbols package if it was declared.
@@ -1804,7 +1804,7 @@
flattenedTable, split->isBase());
if (err != NO_ERROR) {
fprintf(stderr, "Failed to generate resource table for split '%s'\n",
- split->getPrintableName().string());
+ split->getPrintableName().c_str());
return err;
}
split->addEntry(String8("resources.arsc"), flattenedTable);
@@ -1821,7 +1821,7 @@
err = resTable.add(flattenedTable->getData(), flattenedTable->getSize());
if (err != NO_ERROR) {
fprintf(stderr, "Generated resource table for split '%s' is corrupt.\n",
- split->getPrintableName().string());
+ split->getPrintableName().c_str());
return err;
}
@@ -1849,7 +1849,7 @@
if (block < 0) {
hasError = true;
SourcePos().error("%s has no definition for density split '%s'",
- symbol.toString().string(), config.toString().string());
+ symbol.toString().c_str(), config.toString().c_str());
if (bundle->getVerbose()) {
const Vector<SymbolDefinition>& defs = densityVaryingResources[k];
@@ -1857,7 +1857,7 @@
for (size_t d = 0; d < defCount; d++) {
const SymbolDefinition& def = defs[d];
def.source.error("%s has definition for %s",
- symbol.toString().string(), def.config.toString().string());
+ symbol.toString().c_str(), def.config.toString().c_str());
}
if (defCount < defs.size()) {
@@ -1880,7 +1880,7 @@
generatedManifest, &table);
if (err != NO_ERROR) {
fprintf(stderr, "Failed to generate AndroidManifest.xml for split '%s'\n",
- split->getPrintableName().string());
+ split->getPrintableName().c_str());
return err;
}
split->addEntry(String8("AndroidManifest.xml"), generatedManifest);
@@ -1960,7 +1960,7 @@
if (block.getElementNamespace(&len) != NULL) {
continue;
}
- if (strcmp16(block.getElementName(&len), manifest16.string()) == 0) {
+ if (strcmp16(block.getElementName(&len), manifest16.c_str()) == 0) {
if (validateAttr(manifestPath, finalResTable, block, NULL, "package",
packageIdentChars, true) != ATTR_OKAY) {
hasErrors = true;
@@ -1969,10 +1969,10 @@
"sharedUserId", packageIdentChars, false) != ATTR_OKAY) {
hasErrors = true;
}
- } else if (strcmp16(block.getElementName(&len), permission16.string()) == 0
- || strcmp16(block.getElementName(&len), permission_group16.string()) == 0) {
+ } else if (strcmp16(block.getElementName(&len), permission16.c_str()) == 0
+ || strcmp16(block.getElementName(&len), permission_group16.c_str()) == 0) {
const bool isGroup = strcmp16(block.getElementName(&len),
- permission_group16.string()) == 0;
+ permission_group16.c_str()) == 0;
if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE,
"name", isGroup ? packageIdentCharsWithTheStupid
: packageIdentChars, true) != ATTR_OKAY) {
@@ -2002,8 +2002,8 @@
const char16_t* id = block.getAttributeStringValue(index, &len);
if (id == NULL) {
fprintf(stderr, "%s:%d: missing name attribute in element <%s>.\n",
- manifestPath.string(), block.getLineNumber(),
- String8(block.getElementName(&len)).string());
+ manifestPath.c_str(), block.getLineNumber(),
+ String8(block.getElementName(&len)).c_str());
hasErrors = true;
break;
}
@@ -2038,23 +2038,23 @@
if (begins_with_digit || (e != p && *(e-1) != '.')) {
fprintf(stderr,
"%s:%d: Permission name <%s> is not a valid Java symbol\n",
- manifestPath.string(), block.getLineNumber(), idStr.string());
+ manifestPath.c_str(), block.getLineNumber(), idStr.c_str());
hasErrors = true;
}
syms->addStringSymbol(String8(e), idStr, srcPos);
const char16_t* cmt = block.getComment(&len);
if (cmt != NULL && *cmt != 0) {
- //printf("Comment of %s: %s\n", String8(e).string(),
- // String8(cmt).string());
+ //printf("Comment of %s: %s\n", String8(e).c_str(),
+ // String8(cmt).c_str());
syms->appendComment(String8(e), String16(cmt), srcPos);
}
syms->makeSymbolPublic(String8(e), srcPos);
- } else if (strcmp16(block.getElementName(&len), uses_permission16.string()) == 0) {
+ } else if (strcmp16(block.getElementName(&len), uses_permission16.c_str()) == 0) {
if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE,
"name", packageIdentChars, true) != ATTR_OKAY) {
hasErrors = true;
}
- } else if (strcmp16(block.getElementName(&len), instrumentation16.string()) == 0) {
+ } else if (strcmp16(block.getElementName(&len), instrumentation16.c_str()) == 0) {
if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE,
"name", classIdentChars, true) != ATTR_OKAY) {
hasErrors = true;
@@ -2064,7 +2064,7 @@
packageIdentChars, true) != ATTR_OKAY) {
hasErrors = true;
}
- } else if (strcmp16(block.getElementName(&len), application16.string()) == 0) {
+ } else if (strcmp16(block.getElementName(&len), application16.c_str()) == 0) {
if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE,
"name", classIdentChars, false) != ATTR_OKAY) {
hasErrors = true;
@@ -2084,7 +2084,7 @@
processIdentChars, false) != ATTR_OKAY) {
hasErrors = true;
}
- } else if (strcmp16(block.getElementName(&len), provider16.string()) == 0) {
+ } else if (strcmp16(block.getElementName(&len), provider16.c_str()) == 0) {
if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE,
"name", classIdentChars, true) != ATTR_OKAY) {
hasErrors = true;
@@ -2104,9 +2104,9 @@
processIdentChars, false) != ATTR_OKAY) {
hasErrors = true;
}
- } else if (strcmp16(block.getElementName(&len), service16.string()) == 0
- || strcmp16(block.getElementName(&len), receiver16.string()) == 0
- || strcmp16(block.getElementName(&len), activity16.string()) == 0) {
+ } else if (strcmp16(block.getElementName(&len), service16.c_str()) == 0
+ || strcmp16(block.getElementName(&len), receiver16.c_str()) == 0
+ || strcmp16(block.getElementName(&len), activity16.c_str()) == 0) {
if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE,
"name", classIdentChars, true) != ATTR_OKAY) {
hasErrors = true;
@@ -2126,14 +2126,14 @@
processIdentChars, false) != ATTR_OKAY) {
hasErrors = true;
}
- } else if (strcmp16(block.getElementName(&len), action16.string()) == 0
- || strcmp16(block.getElementName(&len), category16.string()) == 0) {
+ } else if (strcmp16(block.getElementName(&len), action16.c_str()) == 0
+ || strcmp16(block.getElementName(&len), category16.c_str()) == 0) {
if (validateAttr(manifestPath, finalResTable, block,
RESOURCES_ANDROID_NAMESPACE, "name",
packageIdentChars, true) != ATTR_OKAY) {
hasErrors = true;
}
- } else if (strcmp16(block.getElementName(&len), data16.string()) == 0) {
+ } else if (strcmp16(block.getElementName(&len), data16.c_str()) == 0) {
if (validateAttr(manifestPath, finalResTable, block,
RESOURCES_ANDROID_NAMESPACE, "mimeType",
typeIdentChars, true) != ATTR_OKAY) {
@@ -2144,13 +2144,13 @@
schemeIdentChars, true) != ATTR_OKAY) {
hasErrors = true;
}
- } else if (strcmp16(block.getElementName(&len), feature_group16.string()) == 0) {
+ } else if (strcmp16(block.getElementName(&len), feature_group16.c_str()) == 0) {
int depth = 1;
while ((code=block.next()) != ResXMLTree::END_DOCUMENT
&& code > ResXMLTree::BAD_DOCUMENT) {
if (code == ResXMLTree::START_TAG) {
depth++;
- if (strcmp16(block.getElementName(&len), uses_feature16.string()) == 0) {
+ if (strcmp16(block.getElementName(&len), uses_feature16.c_str()) == 0) {
ssize_t idx = block.indexOfAttribute(
RESOURCES_ANDROID_NAMESPACE, "required");
if (idx < 0) {
@@ -2162,7 +2162,7 @@
fprintf(stderr, "%s:%d: Tag <uses-feature> can not have "
"android:required=\"false\" when inside a "
"<feature-group> tag.\n",
- manifestPath.string(), block.getLineNumber());
+ manifestPath.c_str(), block.getLineNumber());
hasErrors = true;
}
}
@@ -2222,7 +2222,7 @@
static String8 getSymbolPackage(const String8& symbol, const sp<AaptAssets>& assets, bool pub) {
ssize_t colon = symbol.find(":", 0);
if (colon >= 0) {
- return String8(symbol.string(), colon);
+ return String8(symbol.c_str(), colon);
}
return pub ? assets->getPackage() : assets->getSymbolsPrivatePackage();
}
@@ -2230,7 +2230,7 @@
static String8 getSymbolName(const String8& symbol) {
ssize_t colon = symbol.find(":", 0);
if (colon >= 0) {
- return String8(symbol.string() + colon + 1);
+ return String8(symbol.c_str() + colon + 1);
}
return symbol;
}
@@ -2245,7 +2245,7 @@
asym = asym->getNestedSymbols().valueFor(String8("attr"));
if (asym != NULL) {
//printf("Got attrs symbols! comment %s=%s\n",
- // name.string(), String8(asym->getComment(name)).string());
+ // name.c_str(), String8(asym->getComment(name)).c_str());
if (outTypeComment != NULL) {
*outTypeComment = asym->getTypeComment(name);
}
@@ -2276,8 +2276,8 @@
"%sfor(int i = 0; i < styleable.%s.length; ++i) {\n"
"%sstyleable.%s[i] = (styleable.%s[i] & 0x00ffffff) | (packageId << 24);\n"
"%s}\n",
- indentStr, nclassName.string(),
- getIndentSpace(indent+1), nclassName.string(), nclassName.string(),
+ indentStr, nclassName.c_str(),
+ getIndentSpace(indent+1), nclassName.c_str(), nclassName.c_str(),
indentStr);
}
@@ -2303,8 +2303,8 @@
String8 flat_name(flattenSymbol(sym.name));
fprintf(fp,
"%s%s.%s = (%s.%s & 0x00ffffff) | (packageId << 24);\n",
- getIndentSpace(indent), className.string(), flat_name.string(),
- className.string(), flat_name.string());
+ getIndentSpace(indent), className.c_str(), flat_name.c_str(),
+ className.c_str(), flat_name.c_str());
}
N = symbols->getNestedSymbols().size();
@@ -2365,12 +2365,12 @@
String16 name16(sym.name);
uint32_t typeSpecFlags;
code = assets->getIncludedResources().identifierForName(
- name16.string(), name16.size(),
- attr16.string(), attr16.size(),
- package16.string(), package16.size(), &typeSpecFlags);
+ name16.c_str(), name16.size(),
+ attr16.c_str(), attr16.size(),
+ package16.c_str(), package16.size(), &typeSpecFlags);
if (code == 0) {
fprintf(stderr, "ERROR: In <declare-styleable> %s, unable to find attribute %s\n",
- nclassName.string(), sym.name.string());
+ nclassName.c_str(), sym.name.c_str());
hasErrors = true;
}
isPublic = (typeSpecFlags&ResTable_typeSpec::SPEC_PUBLIC) != 0;
@@ -2388,9 +2388,9 @@
if (comment.size() > 0) {
String8 cmt(comment);
ann.preprocessComment(cmt);
- fprintf(fp, "%s\n", cmt.string());
+ fprintf(fp, "%s\n", cmt.c_str());
} else {
- fprintf(fp, "Attributes that can be used with a %s.\n", nclassName.string());
+ fprintf(fp, "Attributes that can be used with a %s.\n", nclassName.c_str());
}
bool hasTable = false;
for (a=0; a<NA; a++) {
@@ -2423,7 +2423,7 @@
continue;
}
if (comment.size() > 0) {
- const char16_t* p = comment.string();
+ const char16_t* p = comment.c_str();
while (*p != 0 && *p != '.') {
if (*p == '{') {
while (*p != 0 && *p != '}') {
@@ -2436,14 +2436,14 @@
if (*p == '.') {
p++;
}
- comment = String16(comment.string(), p-comment.string());
+ comment = String16(comment.c_str(), p-comment.c_str());
}
fprintf(fp, "%s <tr><td><code>{@link #%s_%s %s:%s}</code></td><td>%s</td></tr>\n",
- indentStr, nclassName.string(),
- flattenSymbol(name8).string(),
- getSymbolPackage(name8, assets, true).string(),
- getSymbolName(name8).string(),
- String8(comment).string());
+ indentStr, nclassName.c_str(),
+ flattenSymbol(name8).c_str(),
+ getSymbolPackage(name8, assets, true).c_str(),
+ getSymbolName(name8).c_str(),
+ String8(comment).c_str());
}
}
if (hasTable) {
@@ -2457,8 +2457,8 @@
continue;
}
fprintf(fp, "%s @see #%s_%s\n",
- indentStr, nclassName.string(),
- flattenSymbol(sym.name).string());
+ indentStr, nclassName.c_str(),
+ flattenSymbol(sym.name).c_str());
}
}
fprintf(fp, "%s */\n", getIndentSpace(indent));
@@ -2468,7 +2468,7 @@
fprintf(fp,
"%spublic static final int[] %s = {\n"
"%s",
- indentStr, nclassName.string(),
+ indentStr, nclassName.c_str(),
getIndentSpace(indent+1));
for (a=0; a<NA; a++) {
@@ -2503,11 +2503,11 @@
uint32_t typeSpecFlags = 0;
String16 name16(sym.name);
assets->getIncludedResources().identifierForName(
- name16.string(), name16.size(),
- attr16.string(), attr16.size(),
- package16.string(), package16.size(), &typeSpecFlags);
- //printf("%s:%s/%s: 0x%08x\n", String8(package16).string(),
- // String8(attr16).string(), String8(name16).string(), typeSpecFlags);
+ name16.c_str(), name16.size(),
+ attr16.c_str(), attr16.size(),
+ package16.c_str(), package16.size(), &typeSpecFlags);
+ //printf("%s:%s/%s: 0x%08x\n", String8(package16).c_str(),
+ // String8(attr16).c_str(), String8(name16).c_str(), typeSpecFlags);
const bool pub = (typeSpecFlags&ResTable_typeSpec::SPEC_PUBLIC) != 0;
AnnotationProcessor ann;
@@ -2516,20 +2516,20 @@
String8 cmt(comment);
ann.preprocessComment(cmt);
fprintf(fp, "%s <p>\n%s @attr description\n", indentStr, indentStr);
- fprintf(fp, "%s %s\n", indentStr, cmt.string());
+ fprintf(fp, "%s %s\n", indentStr, cmt.c_str());
} else {
fprintf(fp,
"%s <p>This symbol is the offset where the {@link %s.R.attr#%s}\n"
"%s attribute's value can be found in the {@link #%s} array.\n",
indentStr,
- getSymbolPackage(name8, assets, pub).string(),
- getSymbolName(name8).string(),
- indentStr, nclassName.string());
+ getSymbolPackage(name8, assets, pub).c_str(),
+ getSymbolName(name8).c_str(),
+ indentStr, nclassName.c_str());
}
if (typeComment.size() > 0) {
String8 cmt(typeComment);
ann.preprocessComment(cmt);
- fprintf(fp, "\n\n%s %s\n", indentStr, cmt.string());
+ fprintf(fp, "\n\n%s %s\n", indentStr, cmt.c_str());
}
if (comment.size() > 0) {
if (pub) {
@@ -2537,16 +2537,16 @@
"%s <p>This corresponds to the global attribute\n"
"%s resource symbol {@link %s.R.attr#%s}.\n",
indentStr, indentStr,
- getSymbolPackage(name8, assets, true).string(),
- getSymbolName(name8).string());
+ getSymbolPackage(name8, assets, true).c_str(),
+ getSymbolName(name8).c_str());
} else {
fprintf(fp,
"%s <p>This is a private symbol.\n", indentStr);
}
}
fprintf(fp, "%s @attr name %s:%s\n", indentStr,
- getSymbolPackage(name8, assets, pub).string(),
- getSymbolName(name8).string());
+ getSymbolPackage(name8, assets, pub).c_str(),
+ getSymbolName(name8).c_str());
fprintf(fp, "%s*/\n", indentStr);
ann.printAnnotations(fp, indentStr);
@@ -2556,8 +2556,8 @@
fprintf(fp,
id_format,
- indentStr, nclassName.string(),
- flattenSymbol(name8).string(), (int)pos);
+ indentStr, nclassName.c_str(),
+ flattenSymbol(name8).c_str(), (int)pos);
}
}
}
@@ -2598,12 +2598,12 @@
String16 name16(sym.name);
uint32_t typeSpecFlags;
code = assets->getIncludedResources().identifierForName(
- name16.string(), name16.size(),
- attr16.string(), attr16.size(),
- package16.string(), package16.size(), &typeSpecFlags);
+ name16.c_str(), name16.size(),
+ attr16.c_str(), attr16.size(),
+ package16.c_str(), package16.size(), &typeSpecFlags);
if (code == 0) {
fprintf(stderr, "ERROR: In <declare-styleable> %s, unable to find attribute %s\n",
- nclassName.string(), sym.name.string());
+ nclassName.c_str(), sym.name.c_str());
hasErrors = true;
}
isPublic = (typeSpecFlags&ResTable_typeSpec::SPEC_PUBLIC) != 0;
@@ -2615,7 +2615,7 @@
NA = idents.size();
- fprintf(fp, "int[] styleable %s {", nclassName.string());
+ fprintf(fp, "int[] styleable %s {", nclassName.c_str());
for (a=0; a<NA; a++) {
if (a != 0) {
@@ -2645,17 +2645,17 @@
uint32_t typeSpecFlags = 0;
String16 name16(sym.name);
assets->getIncludedResources().identifierForName(
- name16.string(), name16.size(),
- attr16.string(), attr16.size(),
- package16.string(), package16.size(), &typeSpecFlags);
- //printf("%s:%s/%s: 0x%08x\n", String8(package16).string(),
- // String8(attr16).string(), String8(name16).string(), typeSpecFlags);
+ name16.c_str(), name16.size(),
+ attr16.c_str(), attr16.size(),
+ package16.c_str(), package16.size(), &typeSpecFlags);
+ //printf("%s:%s/%s: 0x%08x\n", String8(package16).c_str(),
+ // String8(attr16).c_str(), String8(name16).c_str(), typeSpecFlags);
//const bool pub = (typeSpecFlags&ResTable_typeSpec::SPEC_PUBLIC) != 0;
fprintf(fp,
"int styleable %s_%s %d\n",
- nclassName.string(),
- flattenSymbol(name8).string(), (int)pos);
+ nclassName.c_str(),
+ flattenSymbol(name8).c_str(), (int)pos);
}
}
}
@@ -2670,7 +2670,7 @@
{
fprintf(fp, "%spublic %sfinal class %s {\n",
getIndentSpace(indent),
- indent != 0 ? "static " : "", className.string());
+ indent != 0 ? "static " : "", className.c_str());
indent++;
size_t i;
@@ -2699,7 +2699,7 @@
ann.preprocessComment(cmt);
fprintf(fp,
"%s/** %s\n",
- getIndentSpace(indent), cmt.string());
+ getIndentSpace(indent), cmt.c_str());
}
String16 typeComment(sym.typeComment);
if (typeComment.size() > 0) {
@@ -2708,10 +2708,10 @@
if (!haveComment) {
haveComment = true;
fprintf(fp,
- "%s/** %s\n", getIndentSpace(indent), cmt.string());
+ "%s/** %s\n", getIndentSpace(indent), cmt.c_str());
} else {
fprintf(fp,
- "%s %s\n", getIndentSpace(indent), cmt.string());
+ "%s %s\n", getIndentSpace(indent), cmt.c_str());
}
}
if (haveComment) {
@@ -2720,7 +2720,7 @@
ann.printAnnotations(fp, getIndentSpace(indent));
fprintf(fp, id_format,
getIndentSpace(indent),
- flattenSymbol(name8).string(), (int)sym.int32Val);
+ flattenSymbol(name8).c_str(), (int)sym.int32Val);
}
for (i=0; i<N; i++) {
@@ -2740,13 +2740,13 @@
fprintf(fp,
"%s/** %s\n"
"%s */\n",
- getIndentSpace(indent), cmt.string(),
+ getIndentSpace(indent), cmt.c_str(),
getIndentSpace(indent));
}
ann.printAnnotations(fp, getIndentSpace(indent));
fprintf(fp, "%spublic static final String %s=\"%s\";\n",
getIndentSpace(indent),
- flattenSymbol(name8).string(), sym.stringVal.string());
+ flattenSymbol(name8).c_str(), sym.stringVal.c_str());
}
sp<AaptSymbols> styleableSymbols;
@@ -2805,8 +2805,8 @@
String8 name8(sym.name);
fprintf(fp, "int %s %s 0x%08x\n",
- className.string(),
- flattenSymbol(name8).string(), (int)sym.int32Val);
+ className.c_str(),
+ flattenSymbol(name8).c_str(), (int)sym.int32Val);
}
N = symbols->getNestedSymbols().size();
@@ -2844,7 +2844,7 @@
if (bundle->getMakePackageDirs()) {
const String8& pkg(package);
- const char* last = pkg.string();
+ const char* last = pkg.c_str();
const char* s = last-1;
do {
s++;
@@ -2852,9 +2852,9 @@
String8 part(last, s-last);
dest.appendPath(part);
#ifdef _WIN32
- _mkdir(dest.string());
+ _mkdir(dest.c_str());
#else
- mkdir(dest.string(), S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP);
+ mkdir(dest.c_str(), S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP);
#endif
last = s+1;
}
@@ -2862,14 +2862,14 @@
}
dest.appendPath(className);
dest.append(".java");
- FILE* fp = fopen(dest.string(), "w+");
+ FILE* fp = fopen(dest.c_str(), "w+");
if (fp == NULL) {
fprintf(stderr, "ERROR: Unable to open class file %s: %s\n",
- dest.string(), strerror(errno));
+ dest.c_str(), strerror(errno));
return UNKNOWN_ERROR;
}
if (bundle->getVerbose()) {
- printf(" Writing symbols for class %s.\n", className.string());
+ printf(" Writing symbols for class %s.\n", className.c_str());
}
fprintf(fp,
@@ -2880,7 +2880,7 @@
" * should not be modified by hand.\n"
" */\n"
"\n"
- "package %s;\n\n", package.string());
+ "package %s;\n\n", package.c_str());
status_t err = writeSymbolClass(fp, assets, includePrivate, symbols,
className, 0, bundle->getNonConstantId(), emitCallback);
@@ -2894,14 +2894,14 @@
textDest.appendPath(className);
textDest.append(".txt");
- FILE* fp = fopen(textDest.string(), "w+");
+ FILE* fp = fopen(textDest.c_str(), "w+");
if (fp == NULL) {
fprintf(stderr, "ERROR: Unable to open text symbol file %s: %s\n",
- textDest.string(), strerror(errno));
+ textDest.c_str(), strerror(errno));
return UNKNOWN_ERROR;
}
if (bundle->getVerbose()) {
- printf(" Writing text symbols for class %s.\n", className.string());
+ printf(" Writing text symbols for class %s.\n", className.c_str());
}
status_t err = writeTextSymbolClass(fp, assets, includePrivate, symbols,
@@ -2919,8 +2919,8 @@
String8 dependencyFile(bundle->getRClassDir());
dependencyFile.appendPath("R.java.d");
- FILE *fp = fopen(dependencyFile.string(), "a");
- fprintf(fp,"%s \\\n", dest.string());
+ FILE *fp = fopen(dependencyFile.c_str(), "a");
+ fprintf(fp,"%s \\\n", dest.c_str());
fclose(fp);
}
}
@@ -2956,7 +2956,7 @@
// asdf --> package.asdf
// .asdf .a.b --> package.asdf package.a.b
// asdf.adsf --> asdf.asdf
- const char* p = className.string();
+ const char* p = className.c_str();
const char* q = strchr(p, '.');
if (p == q) {
className = pkg;
@@ -3023,7 +3023,7 @@
if (assGroup->getFiles().size() != 1) {
fprintf(stderr, "warning: Multiple AndroidManifest.xml files found, using %s\n",
- assGroup->getFiles().valueAt(0)->getPrintableSource().string());
+ assGroup->getFiles().valueAt(0)->getPrintableSource().c_str());
}
assFile = assGroup->getFiles().valueAt(0);
@@ -3048,7 +3048,7 @@
}
depth++;
String8 tag(tree.getElementName(&len));
- // printf("Depth %d tag %s\n", depth, tag.string());
+ // printf("Depth %d tag %s\n", depth, tag.c_str());
bool keepTag = false;
if (depth == 1) {
if (tag != "manifest") {
@@ -3065,7 +3065,7 @@
"http://schemas.android.com/apk/res/android",
"backupAgent", &error);
if (agent.length() > 0) {
- addProguardKeepRule(keep, agent, pkg.string(),
+ addProguardKeepRule(keep, agent, pkg.c_str(),
assFile->getPrintableSource(), tree.getLineNumber());
}
@@ -3073,7 +3073,7 @@
defaultProcess = AaptXml::getAttribute(tree,
"http://schemas.android.com/apk/res/android", "process", &error);
if (error != "") {
- fprintf(stderr, "ERROR: %s\n", error.string());
+ fprintf(stderr, "ERROR: %s\n", error.c_str());
return -1;
}
}
@@ -3089,7 +3089,7 @@
String8 componentProcess = AaptXml::getAttribute(tree,
"http://schemas.android.com/apk/res/android", "process", &error);
if (error != "") {
- fprintf(stderr, "ERROR: %s\n", error.string());
+ fprintf(stderr, "ERROR: %s\n", error.c_str());
return -1;
}
@@ -3103,14 +3103,14 @@
String8 name = AaptXml::getAttribute(tree,
"http://schemas.android.com/apk/res/android", "name", &error);
if (error != "") {
- fprintf(stderr, "ERROR: %s\n", error.string());
+ fprintf(stderr, "ERROR: %s\n", error.c_str());
return -1;
}
keepTag = name.length() > 0;
if (keepTag) {
- addProguardKeepRule(keep, name, pkg.string(),
+ addProguardKeepRule(keep, name, pkg.c_str(),
assFile->getPrintableSource(), tree.getLineNumber());
}
}
@@ -3170,7 +3170,7 @@
String8 tag(tree.getElementName(&len));
// If there is no '.', we'll assume that it's one of the built in names.
- if (strchr(tag.string(), '.')) {
+ if (strchr(tag.c_str(), '.')) {
addProguardKeepRule(keep, tag, NULL,
layoutFile->getPrintableSource(), tree.getLineNumber());
} else if (tagAttrPairs != NULL) {
@@ -3183,8 +3183,8 @@
ssize_t attrIndex = tree.indexOfAttribute(nsAttr.ns, nsAttr.attr);
if (attrIndex < 0) {
// fprintf(stderr, "%s:%d: <%s> does not have attribute %s:%s.\n",
- // layoutFile->getPrintableSource().string(), tree.getLineNumber(),
- // tag.string(), nsAttr.ns, nsAttr.attr);
+ // layoutFile->getPrintableSource().c_str(), tree.getLineNumber(),
+ // tag.c_str(), nsAttr.ns, nsAttr.attr);
} else {
size_t len;
addProguardKeepRule(keep,
@@ -3242,7 +3242,7 @@
// tag:attribute pairs that should be checked in transition files.
KeyedVector<String8, Vector<NamespaceAttributePair> > kTransitionTagAttrPairs;
- addTagAttrPair(&kTransitionTagAttrPairs, kTransition.string(), NULL, kClass);
+ addTagAttrPair(&kTransitionTagAttrPairs, kTransition.c_str(), NULL, kClass);
addTagAttrPair(&kTransitionTagAttrPairs, "pathMotion", NULL, kClass);
const Vector<sp<AaptDir> >& dirs = assets->resDirs();
@@ -3252,16 +3252,16 @@
const String8& dirName = d->getLeaf();
Vector<String8> startTags;
const KeyedVector<String8, Vector<NamespaceAttributePair> >* tagAttrPairs = NULL;
- if ((dirName == String8("layout")) || (strncmp(dirName.string(), "layout-", 7) == 0)) {
+ if ((dirName == String8("layout")) || (strncmp(dirName.c_str(), "layout-", 7) == 0)) {
tagAttrPairs = &kLayoutTagAttrPairs;
- } else if ((dirName == String8("xml")) || (strncmp(dirName.string(), "xml-", 4) == 0)) {
+ } else if ((dirName == String8("xml")) || (strncmp(dirName.c_str(), "xml-", 4) == 0)) {
startTags.add(String8("PreferenceScreen"));
startTags.add(String8("preference-headers"));
tagAttrPairs = &kXmlTagAttrPairs;
- } else if ((dirName == String8("menu")) || (strncmp(dirName.string(), "menu-", 5) == 0)) {
+ } else if ((dirName == String8("menu")) || (strncmp(dirName.c_str(), "menu-", 5) == 0)) {
startTags.add(String8("menu"));
tagAttrPairs = NULL;
- } else if (dirName == kTransition || (strncmp(dirName.string(), kTransitionPrefix.string(),
+ } else if (dirName == kTransition || (strncmp(dirName.c_str(), kTransitionPrefix.c_str(),
kTransitionPrefix.size()) == 0)) {
tagAttrPairs = &kTransitionTagAttrPairs;
} else {
@@ -3307,9 +3307,9 @@
const SortedVector<String8>& locations = rules.valueAt(i);
const size_t M = locations.size();
for (size_t j=0; j<M; j++) {
- fprintf(fp, "# %s\n", locations.itemAt(j).string());
+ fprintf(fp, "# %s\n", locations.itemAt(j).c_str());
}
- fprintf(fp, "%s\n\n", rules.keyAt(i).string());
+ fprintf(fp, "%s\n\n", rules.keyAt(i).c_str());
}
fclose(fp);
@@ -3366,7 +3366,7 @@
status_t deps = -1;
for (size_t file_i = 0; file_i < files->size(); ++file_i) {
// Add the full file path to the dependency file
- fprintf(fp, "%s \\\n", files->itemAt(file_i).string());
+ fprintf(fp, "%s \\\n", files->itemAt(file_i).c_str());
deps++;
}
return deps;
diff --git a/tools/aapt/ResourceFilter.cpp b/tools/aapt/ResourceFilter.cpp
index ed06f60..cc8dce7e 100644
--- a/tools/aapt/ResourceFilter.cpp
+++ b/tools/aapt/ResourceFilter.cpp
@@ -32,7 +32,7 @@
// only specify locale in the standard 'en_US' format.
val.writeTo(&entry.first);
} else if (!AaptConfig::parse(part, &entry.first)) {
- fprintf(stderr, "Invalid configuration: %s\n", part.string());
+ fprintf(stderr, "Invalid configuration: %s\n", part.c_str());
return UNKNOWN_ERROR;
}
@@ -43,7 +43,7 @@
// Ignore any densities. Those are best handled in --preferred-density
if ((entry.second & ResTable_config::CONFIG_DENSITY) != 0) {
- fprintf(stderr, "warning: ignoring flag -c %s. Use --preferred-density instead.\n", entry.first.toString().string());
+ fprintf(stderr, "warning: ignoring flag -c %s. Use --preferred-density instead.\n", entry.first.toString().c_str());
entry.first.density = 0;
entry.second &= ~ResTable_config::CONFIG_DENSITY;
}
@@ -148,7 +148,7 @@
mConfigs.clear();
for (size_t i = 0; i < configStrs.size(); i++) {
if (!AaptConfig::parse(configStrs[i], &config)) {
- fprintf(stderr, "Invalid configuration: %s\n", configStrs[i].string());
+ fprintf(stderr, "Invalid configuration: %s\n", configStrs[i].c_str());
return UNKNOWN_ERROR;
}
mConfigs.insert(config);
diff --git a/tools/aapt/ResourceIdCache.cpp b/tools/aapt/ResourceIdCache.cpp
index 8835fb0..1c7788d 100644
--- a/tools/aapt/ResourceIdCache.cpp
+++ b/tools/aapt/ResourceIdCache.cpp
@@ -37,7 +37,7 @@
static uint32_t hash(const android::String16& hashableString) {
uint32_t hash = 5381;
- const char16_t* str = hashableString.string();
+ const char16_t* str = hashableString.c_str();
while (int c = *str++) hash = hashround(hash, c);
return hash;
}
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
index 4e597fb..2344007 100644
--- a/tools/aapt/ResourceTable.cpp
+++ b/tools/aapt/ResourceTable.cpp
@@ -361,10 +361,10 @@
ssize_t typeIdx = block.indexOfAttribute(NULL, "format");
if (typeIdx >= 0) {
String16 typeStr = String16(block.getAttributeStringValue(typeIdx, &len));
- attr.type = parse_flags(typeStr.string(), typeStr.size(), gFormatFlags);
+ attr.type = parse_flags(typeStr.c_str(), typeStr.size(), gFormatFlags);
if (attr.type == 0) {
attr.sourcePos.error("Tag <attr> 'format' attribute value \"%s\" not valid\n",
- String8(typeStr).string());
+ String8(typeStr).c_str());
attr.hasErrors = true;
}
attr.createIfNeeded(outTable);
@@ -374,14 +374,14 @@
attr.createIfNeeded(outTable);
}
- //printf("Attribute %s: type=0x%08x\n", String8(attr.ident).string(), attr.type);
+ //printf("Attribute %s: type=0x%08x\n", String8(attr.ident).c_str(), attr.type);
ssize_t minIdx = block.indexOfAttribute(NULL, "min");
if (minIdx >= 0) {
String16 val = String16(block.getAttributeStringValue(minIdx, &len));
- if (!ResTable::stringToInt(val.string(), val.size(), NULL)) {
+ if (!ResTable::stringToInt(val.c_str(), val.size(), NULL)) {
attr.sourcePos.error("Tag <attr> 'min' attribute must be a number, not \"%s\"\n",
- String8(val).string());
+ String8(val).c_str());
attr.hasErrors = true;
}
attr.createIfNeeded(outTable);
@@ -397,9 +397,9 @@
ssize_t maxIdx = block.indexOfAttribute(NULL, "max");
if (maxIdx >= 0) {
String16 val = String16(block.getAttributeStringValue(maxIdx, &len));
- if (!ResTable::stringToInt(val.string(), val.size(), NULL)) {
+ if (!ResTable::stringToInt(val.c_str(), val.size(), NULL)) {
attr.sourcePos.error("Tag <attr> 'max' attribute must be a number, not \"%s\"\n",
- String8(val).string());
+ String8(val).c_str());
attr.hasErrors = true;
}
attr.createIfNeeded(outTable);
@@ -422,7 +422,7 @@
uint32_t l10n_required = parse_flags(str, len, l10nRequiredFlags, &error);
if (error) {
attr.sourcePos.error("Tag <attr> 'localization' attribute value \"%s\" not valid\n",
- String8(str).string());
+ String8(str).c_str());
attr.hasErrors = true;
}
attr.createIfNeeded(outTable);
@@ -442,14 +442,14 @@
while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
if (code == ResXMLTree::START_TAG) {
uint32_t localType = 0;
- if (strcmp16(block.getElementName(&len), enum16.string()) == 0) {
+ if (strcmp16(block.getElementName(&len), enum16.c_str()) == 0) {
localType = ResTable_map::TYPE_ENUM;
- } else if (strcmp16(block.getElementName(&len), flag16.string()) == 0) {
+ } else if (strcmp16(block.getElementName(&len), flag16.c_str()) == 0) {
localType = ResTable_map::TYPE_FLAGS;
} else {
SourcePos(in->getPrintableSource(), block.getLineNumber())
.error("Tag <%s> can not appear inside <attr>, only <enum> or <flag>\n",
- String8(block.getElementName(&len)).string());
+ String8(block.getElementName(&len)).c_str());
return UNKNOWN_ERROR;
}
@@ -505,11 +505,11 @@
.error("A 'value' attribute is required for <enum> or <flag>\n");
attr.hasErrors = true;
}
- if (!attr.hasErrors && !ResTable::stringToInt(value.string(), value.size(), NULL)) {
+ if (!attr.hasErrors && !ResTable::stringToInt(value.c_str(), value.size(), NULL)) {
SourcePos(in->getPrintableSource(), block.getLineNumber())
.error("Tag <enum> or <flag> 'value' attribute must be a number,"
" not \"%s\"\n",
- String8(value).string());
+ String8(value).c_str());
attr.hasErrors = true;
}
@@ -546,21 +546,21 @@
}
}
} else if (code == ResXMLTree::END_TAG) {
- if (strcmp16(block.getElementName(&len), attr16.string()) == 0) {
+ if (strcmp16(block.getElementName(&len), attr16.c_str()) == 0) {
break;
}
if ((attr.type&ResTable_map::TYPE_ENUM) != 0) {
- if (strcmp16(block.getElementName(&len), enum16.string()) != 0) {
+ if (strcmp16(block.getElementName(&len), enum16.c_str()) != 0) {
SourcePos(in->getPrintableSource(), block.getLineNumber())
.error("Found tag </%s> where </enum> is expected\n",
- String8(block.getElementName(&len)).string());
+ String8(block.getElementName(&len)).c_str());
return UNKNOWN_ERROR;
}
} else {
- if (strcmp16(block.getElementName(&len), flag16.string()) != 0) {
+ if (strcmp16(block.getElementName(&len), flag16.c_str()) != 0) {
SourcePos(in->getPrintableSource(), block.getLineNumber())
.error("Found tag </%s> where </flag> is expected\n",
- String8(block.getElementName(&len)).string());
+ String8(block.getElementName(&len)).c_str());
return UNKNOWN_ERROR;
}
}
@@ -606,7 +606,7 @@
String16 str;
Vector<StringPool::entry_style_span> spans;
- err = parseStyledString(bundle, in->getPrintableSource().string(),
+ err = parseStyledString(bundle, in->getPrintableSource().c_str(),
block, item16, &str, &spans, isFormatted,
pseudolocalize);
if (err != NO_ERROR) {
@@ -619,10 +619,10 @@
config.language[0], config.language[1],
config.country[0], config.country[1],
config.orientation, config.density,
- String8(parentIdent).string(),
- String8(ident).string(),
- String8(itemIdent).string(),
- String8(str).string());
+ String8(parentIdent).c_str(),
+ String8(ident).c_str(),
+ String8(itemIdent).c_str(),
+ String8(str).c_str());
}
err = outTable->addBag(SourcePos(in->getPrintableSource(), block->getLineNumber()),
@@ -636,8 +636,8 @@
* haystack, false otherwise.
*/
bool isInProductList(const String16& needle, const String16& haystack) {
- const char16_t *needle2 = needle.string();
- const char16_t *haystack2 = haystack.string();
+ const char16_t *needle2 = needle.c_str();
+ const char16_t *haystack2 = haystack.c_str();
size_t needlesize = needle.size();
while (*haystack2 != '\0') {
@@ -703,7 +703,7 @@
String16 str;
Vector<StringPool::entry_style_span> spans;
- err = parseStyledString(bundle, in->getPrintableSource().string(), block,
+ err = parseStyledString(bundle, in->getPrintableSource().c_str(), block,
curTag, &str, curIsStyled ? &spans : NULL,
isFormatted, pseudolocalize);
@@ -730,7 +730,7 @@
*/
if (bundleProduct[0] == '\0') {
- if (strcmp16(String16("default").string(), product.string()) != 0) {
+ if (strcmp16(String16("default").c_str(), product.c_str()) != 0) {
/*
* This string has a product other than 'default'. Do not add it,
* but record it so that if we do not see the same string with
@@ -750,7 +750,7 @@
if (isInProductList(product, String16(bundleProduct))) {
;
- } else if (strcmp16(String16("default").string(), product.string()) == 0 &&
+ } else if (strcmp16(String16("default").c_str(), product.c_str()) == 0 &&
!outTable->hasBagOrEntry(myPackage, curType, ident, config)) {
;
} else {
@@ -764,7 +764,7 @@
config.language[0], config.language[1],
config.country[0], config.country[1],
config.orientation, config.density,
- String8(ident).string(), String8(str).string());
+ String8(ident).c_str(), String8(str).c_str());
}
err = outTable->addEntry(SourcePos(in->getPrintableSource(), block->getLineNumber()),
@@ -847,7 +847,7 @@
bool hasErrors = false;
bool fileIsTranslatable = true;
- if (strstr(in->getPrintableSource().string(), "donottranslate") != NULL) {
+ if (strstr(in->getPrintableSource().c_str(), "donottranslate") != NULL) {
fileIsTranslatable = false;
}
@@ -869,9 +869,9 @@
"No start tag found\n");
return UNKNOWN_ERROR;
}
- if (strcmp16(block.getElementName(&len), resources16.string()) != 0) {
+ if (strcmp16(block.getElementName(&len), resources16.c_str()) != 0) {
SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
- "Invalid start tag %s\n", String8(block.getElementName(&len)).string());
+ "Invalid start tag %s\n", String8(block.getElementName(&len)).c_str());
return UNKNOWN_ERROR;
}
@@ -900,7 +900,7 @@
SourcePos(in->getPrintableSource(), 0).warning(
"Resource file %s is skipped as pseudolocalization"
" was done automatically.",
- in->getPrintableSource().string());
+ in->getPrintableSource().c_str());
return NO_ERROR;
}
@@ -917,29 +917,29 @@
bool curIsFormatted = fileIsTranslatable;
bool localHasErrors = false;
- if (strcmp16(block.getElementName(&len), skip16.string()) == 0) {
+ if (strcmp16(block.getElementName(&len), skip16.c_str()) == 0) {
while ((code=block.next()) != ResXMLTree::END_DOCUMENT
&& code != ResXMLTree::BAD_DOCUMENT) {
if (code == ResXMLTree::END_TAG) {
- if (strcmp16(block.getElementName(&len), skip16.string()) == 0) {
+ if (strcmp16(block.getElementName(&len), skip16.c_str()) == 0) {
break;
}
}
}
continue;
- } else if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) {
+ } else if (strcmp16(block.getElementName(&len), eat_comment16.c_str()) == 0) {
while ((code=block.next()) != ResXMLTree::END_DOCUMENT
&& code != ResXMLTree::BAD_DOCUMENT) {
if (code == ResXMLTree::END_TAG) {
- if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) {
+ if (strcmp16(block.getElementName(&len), eat_comment16.c_str()) == 0) {
break;
}
}
}
continue;
- } else if (strcmp16(block.getElementName(&len), public16.string()) == 0) {
+ } else if (strcmp16(block.getElementName(&len), public16.c_str()) == 0) {
SourcePos srcPos(in->getPrintableSource(), block.getLineNumber());
String16 type;
@@ -965,7 +965,7 @@
Res_value identValue;
if (!ResTable::stringToInt(identStr, len, &identValue)) {
srcPos.error("Given 'id' attribute is not an integer: %s\n",
- String8(block.getAttributeStringValue(identIdx, &len)).string());
+ String8(block.getAttributeStringValue(identIdx, &len)).c_str());
hasErrors = localHasErrors = true;
} else {
ident = identValue.data;
@@ -1004,14 +1004,14 @@
while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
if (code == ResXMLTree::END_TAG) {
- if (strcmp16(block.getElementName(&len), public16.string()) == 0) {
+ if (strcmp16(block.getElementName(&len), public16.c_str()) == 0) {
break;
}
}
}
continue;
- } else if (strcmp16(block.getElementName(&len), public_padding16.string()) == 0) {
+ } else if (strcmp16(block.getElementName(&len), public_padding16.c_str()) == 0) {
SourcePos srcPos(in->getPrintableSource(), block.getLineNumber());
String16 type;
@@ -1037,7 +1037,7 @@
Res_value startValue;
if (!ResTable::stringToInt(startStr, len, &startValue)) {
srcPos.error("Given 'start' attribute is not an integer: %s\n",
- String8(block.getAttributeStringValue(startIdx, &len)).string());
+ String8(block.getAttributeStringValue(startIdx, &len)).c_str());
hasErrors = localHasErrors = true;
} else {
start = startValue.data;
@@ -1057,7 +1057,7 @@
Res_value endValue;
if (!ResTable::stringToInt(endStr, len, &endValue)) {
srcPos.error("Given 'end' attribute is not an integer: %s\n",
- String8(block.getAttributeStringValue(endIdx, &len)).string());
+ String8(block.getAttributeStringValue(endIdx, &len)).c_str());
hasErrors = localHasErrors = true;
} else {
end = endValue.data;
@@ -1114,14 +1114,14 @@
while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
if (code == ResXMLTree::END_TAG) {
- if (strcmp16(block.getElementName(&len), public_padding16.string()) == 0) {
+ if (strcmp16(block.getElementName(&len), public_padding16.c_str()) == 0) {
break;
}
}
}
continue;
- } else if (strcmp16(block.getElementName(&len), private_symbols16.string()) == 0) {
+ } else if (strcmp16(block.getElementName(&len), private_symbols16.c_str()) == 0) {
String16 pkg;
ssize_t pkgIdx = block.indexOfAttribute(NULL, "package");
if (pkgIdx < 0) {
@@ -1144,14 +1144,14 @@
while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
if (code == ResXMLTree::END_TAG) {
- if (strcmp16(block.getElementName(&len), private_symbols16.string()) == 0) {
+ if (strcmp16(block.getElementName(&len), private_symbols16.c_str()) == 0) {
break;
}
}
}
continue;
- } else if (strcmp16(block.getElementName(&len), java_symbol16.string()) == 0) {
+ } else if (strcmp16(block.getElementName(&len), java_symbol16.c_str()) == 0) {
SourcePos srcPos(in->getPrintableSource(), block.getLineNumber());
String16 type;
@@ -1186,7 +1186,7 @@
while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
if (code == ResXMLTree::END_TAG) {
- if (strcmp16(block.getElementName(&len), java_symbol16.string()) == 0) {
+ if (strcmp16(block.getElementName(&len), java_symbol16.c_str()) == 0) {
break;
}
}
@@ -1194,7 +1194,7 @@
continue;
- } else if (strcmp16(block.getElementName(&len), add_resource16.string()) == 0) {
+ } else if (strcmp16(block.getElementName(&len), add_resource16.c_str()) == 0) {
SourcePos srcPos(in->getPrintableSource(), block.getLineNumber());
String16 typeName;
@@ -1217,14 +1217,14 @@
while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
if (code == ResXMLTree::END_TAG) {
- if (strcmp16(block.getElementName(&len), add_resource16.string()) == 0) {
+ if (strcmp16(block.getElementName(&len), add_resource16.c_str()) == 0) {
break;
}
}
}
continue;
- } else if (strcmp16(block.getElementName(&len), declare_styleable16.string()) == 0) {
+ } else if (strcmp16(block.getElementName(&len), declare_styleable16.c_str()) == 0) {
SourcePos srcPos(in->getPrintableSource(), block.getLineNumber());
String16 ident;
@@ -1258,30 +1258,30 @@
while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
if (code == ResXMLTree::START_TAG) {
- if (strcmp16(block.getElementName(&len), skip16.string()) == 0) {
+ if (strcmp16(block.getElementName(&len), skip16.c_str()) == 0) {
while ((code=block.next()) != ResXMLTree::END_DOCUMENT
&& code != ResXMLTree::BAD_DOCUMENT) {
if (code == ResXMLTree::END_TAG) {
- if (strcmp16(block.getElementName(&len), skip16.string()) == 0) {
+ if (strcmp16(block.getElementName(&len), skip16.c_str()) == 0) {
break;
}
}
}
continue;
- } else if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) {
+ } else if (strcmp16(block.getElementName(&len), eat_comment16.c_str()) == 0) {
while ((code=block.next()) != ResXMLTree::END_DOCUMENT
&& code != ResXMLTree::BAD_DOCUMENT) {
if (code == ResXMLTree::END_TAG) {
- if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) {
+ if (strcmp16(block.getElementName(&len), eat_comment16.c_str()) == 0) {
break;
}
}
}
continue;
- } else if (strcmp16(block.getElementName(&len), attr16.string()) != 0) {
+ } else if (strcmp16(block.getElementName(&len), attr16.c_str()) != 0) {
SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
"Tag <%s> can not appear inside <declare-styleable>, only <attr>\n",
- String8(block.getElementName(&len)).string());
+ String8(block.getElementName(&len)).c_str());
return UNKNOWN_ERROR;
}
@@ -1297,30 +1297,30 @@
SourcePos srcPos(String8(in->getPrintableSource()), block.getLineNumber());
symbols->addSymbol(String8(itemIdent), 0, srcPos);
symbols->appendComment(String8(itemIdent), comment, srcPos);
- //printf("Attribute %s comment: %s\n", String8(itemIdent).string(),
- // String8(comment).string());
+ //printf("Attribute %s comment: %s\n", String8(itemIdent).c_str(),
+ // String8(comment).c_str());
}
} else if (code == ResXMLTree::END_TAG) {
- if (strcmp16(block.getElementName(&len), declare_styleable16.string()) == 0) {
+ if (strcmp16(block.getElementName(&len), declare_styleable16.c_str()) == 0) {
break;
}
SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
"Found tag </%s> where </attr> is expected\n",
- String8(block.getElementName(&len)).string());
+ String8(block.getElementName(&len)).c_str());
return UNKNOWN_ERROR;
}
}
continue;
- } else if (strcmp16(block.getElementName(&len), attr16.string()) == 0) {
+ } else if (strcmp16(block.getElementName(&len), attr16.c_str()) == 0) {
err = compileAttribute(in, block, myPackage, outTable, NULL);
if (err != NO_ERROR) {
hasErrors = true;
}
continue;
- } else if (strcmp16(block.getElementName(&len), item16.string()) == 0) {
+ } else if (strcmp16(block.getElementName(&len), item16.c_str()) == 0) {
curTag = &item16;
ssize_t attri = block.indexOfAttribute(NULL, "type");
if (attri >= 0) {
@@ -1333,12 +1333,12 @@
if (formatIdx >= 0) {
String16 formatStr = String16(block.getAttributeStringValue(
formatIdx, &len));
- curFormat = parse_flags(formatStr.string(), formatStr.size(),
+ curFormat = parse_flags(formatStr.c_str(), formatStr.size(),
gFormatFlags);
if (curFormat == 0) {
SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
"Tag <item> 'format' attribute value \"%s\" not valid\n",
- String8(formatStr).string());
+ String8(formatStr).c_str());
hasErrors = localHasErrors = true;
}
}
@@ -1348,7 +1348,7 @@
hasErrors = localHasErrors = true;
}
curIsStyled = true;
- } else if (strcmp16(block.getElementName(&len), string16.string()) == 0) {
+ } else if (strcmp16(block.getElementName(&len), string16.c_str()) == 0) {
// Note the existence and locale of every string we process
char rawLocale[RESTABLE_MAX_LOCALE_LEN];
curParams.getBcp47Locale(rawLocale);
@@ -1361,11 +1361,11 @@
for (size_t i = 0; i < n; i++) {
size_t length;
const char16_t* attr = block.getAttributeName(i, &length);
- if (strcmp16(attr, name16.string()) == 0) {
+ if (strcmp16(attr, name16.c_str()) == 0) {
name.setTo(block.getAttributeStringValue(i, &length));
- } else if (strcmp16(attr, translatable16.string()) == 0) {
+ } else if (strcmp16(attr, translatable16.c_str()) == 0) {
translatable.setTo(block.getAttributeStringValue(i, &length));
- } else if (strcmp16(attr, formatted16.string()) == 0) {
+ } else if (strcmp16(attr, formatted16.c_str()) == 0) {
formatted.setTo(block.getAttributeStringValue(i, &length));
}
}
@@ -1380,8 +1380,8 @@
if (locale.size() > 0) {
SourcePos(in->getPrintableSource(), block.getLineNumber()).warning(
"string '%s' marked untranslatable but exists in locale '%s'\n",
- String8(name).string(),
- locale.string());
+ String8(name).c_str(),
+ locale.c_str());
// hasErrors = localHasErrors = true;
} else {
// Intentionally empty block:
@@ -1407,31 +1407,31 @@
curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_STRING;
curIsStyled = true;
curIsPseudolocalizable = fileIsTranslatable && (translatable != false16);
- } else if (strcmp16(block.getElementName(&len), drawable16.string()) == 0) {
+ } else if (strcmp16(block.getElementName(&len), drawable16.c_str()) == 0) {
curTag = &drawable16;
curType = drawable16;
curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_COLOR;
- } else if (strcmp16(block.getElementName(&len), color16.string()) == 0) {
+ } else if (strcmp16(block.getElementName(&len), color16.c_str()) == 0) {
curTag = &color16;
curType = color16;
curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_COLOR;
- } else if (strcmp16(block.getElementName(&len), bool16.string()) == 0) {
+ } else if (strcmp16(block.getElementName(&len), bool16.c_str()) == 0) {
curTag = &bool16;
curType = bool16;
curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_BOOLEAN;
- } else if (strcmp16(block.getElementName(&len), integer16.string()) == 0) {
+ } else if (strcmp16(block.getElementName(&len), integer16.c_str()) == 0) {
curTag = &integer16;
curType = integer16;
curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_INTEGER;
- } else if (strcmp16(block.getElementName(&len), dimen16.string()) == 0) {
+ } else if (strcmp16(block.getElementName(&len), dimen16.c_str()) == 0) {
curTag = &dimen16;
curType = dimen16;
curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_DIMENSION;
- } else if (strcmp16(block.getElementName(&len), fraction16.string()) == 0) {
+ } else if (strcmp16(block.getElementName(&len), fraction16.c_str()) == 0) {
curTag = &fraction16;
curType = fraction16;
curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_FRACTION;
- } else if (strcmp16(block.getElementName(&len), bag16.string()) == 0) {
+ } else if (strcmp16(block.getElementName(&len), bag16.c_str()) == 0) {
curTag = &bag16;
curIsBag = true;
ssize_t attri = block.indexOfAttribute(NULL, "type");
@@ -1442,16 +1442,16 @@
"A 'type' attribute is required for <bag>\n");
hasErrors = localHasErrors = true;
}
- } else if (strcmp16(block.getElementName(&len), style16.string()) == 0) {
+ } else if (strcmp16(block.getElementName(&len), style16.c_str()) == 0) {
curTag = &style16;
curType = style16;
curIsBag = true;
- } else if (strcmp16(block.getElementName(&len), plurals16.string()) == 0) {
+ } else if (strcmp16(block.getElementName(&len), plurals16.c_str()) == 0) {
curTag = &plurals16;
curType = plurals16;
curIsBag = true;
curIsPseudolocalizable = fileIsTranslatable;
- } else if (strcmp16(block.getElementName(&len), array16.string()) == 0) {
+ } else if (strcmp16(block.getElementName(&len), array16.c_str()) == 0) {
curTag = &array16;
curType = array16;
curIsBag = true;
@@ -1460,16 +1460,16 @@
if (formatIdx >= 0) {
String16 formatStr = String16(block.getAttributeStringValue(
formatIdx, &len));
- curFormat = parse_flags(formatStr.string(), formatStr.size(),
+ curFormat = parse_flags(formatStr.c_str(), formatStr.size(),
gFormatFlags);
if (curFormat == 0) {
SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
"Tag <array> 'format' attribute value \"%s\" not valid\n",
- String8(formatStr).string());
+ String8(formatStr).c_str());
hasErrors = localHasErrors = true;
}
}
- } else if (strcmp16(block.getElementName(&len), string_array16.string()) == 0) {
+ } else if (strcmp16(block.getElementName(&len), string_array16.c_str()) == 0) {
// Check whether these strings need valid formats.
// (simplified form of what string16 does above)
bool isTranslatable = false;
@@ -1480,14 +1480,14 @@
for (size_t i = 0; i < n; i++) {
size_t length;
const char16_t* attr = block.getAttributeName(i, &length);
- if (strcmp16(attr, formatted16.string()) == 0) {
+ if (strcmp16(attr, formatted16.c_str()) == 0) {
const char16_t* value = block.getAttributeStringValue(i, &length);
- if (strcmp16(value, false16.string()) == 0) {
+ if (strcmp16(value, false16.c_str()) == 0) {
curIsFormatted = false;
}
- } else if (strcmp16(attr, translatable16.string()) == 0) {
+ } else if (strcmp16(attr, translatable16.c_str()) == 0) {
const char16_t* value = block.getAttributeStringValue(i, &length);
- if (strcmp16(value, false16.string()) == 0) {
+ if (strcmp16(value, false16.c_str()) == 0) {
isTranslatable = false;
}
}
@@ -1499,7 +1499,7 @@
curIsBag = true;
curIsBagReplaceOnOverwrite = true;
curIsPseudolocalizable = isTranslatable && fileIsTranslatable;
- } else if (strcmp16(block.getElementName(&len), integer_array16.string()) == 0) {
+ } else if (strcmp16(block.getElementName(&len), integer_array16.c_str()) == 0) {
curTag = &integer_array16;
curType = array16;
curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_INTEGER;
@@ -1508,7 +1508,7 @@
} else {
SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
"Found tag %s where item is expected\n",
- String8(block.getElementName(&len)).string());
+ String8(block.getElementName(&len)).c_str());
return UNKNOWN_ERROR;
}
@@ -1519,7 +1519,7 @@
} else {
SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
"A 'name' attribute is required for <%s>\n",
- String8(*curTag).string());
+ String8(*curTag).c_str());
hasErrors = localHasErrors = true;
}
@@ -1560,11 +1560,11 @@
&& code != ResXMLTree::BAD_DOCUMENT) {
if (code == ResXMLTree::START_TAG) {
- if (strcmp16(block.getElementName(&len), item16.string()) != 0) {
+ if (strcmp16(block.getElementName(&len), item16.c_str()) != 0) {
SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
"Tag <%s> can not appear inside <%s>, only <item>\n",
- String8(block.getElementName(&len)).string(),
- String8(*curTag).string());
+ String8(block.getElementName(&len)).c_str(),
+ String8(*curTag).c_str());
return UNKNOWN_ERROR;
}
@@ -1647,11 +1647,11 @@
hasErrors = localHasErrors = true;
}
} else if (code == ResXMLTree::END_TAG) {
- if (strcmp16(block.getElementName(&len), curTag->string()) != 0) {
+ if (strcmp16(block.getElementName(&len), curTag->c_str()) != 0) {
SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
"Found tag </%s> where </%s> is expected\n",
- String8(block.getElementName(&len)).string(),
- String8(*curTag).string());
+ String8(block.getElementName(&len)).c_str(),
+ String8(*curTag).c_str());
return UNKNOWN_ERROR;
}
break;
@@ -1700,9 +1700,9 @@
#if 0
if (comment.size() > 0) {
- printf("Comment for @%s:%s/%s: %s\n", String8(myPackage).string(),
- String8(curType).string(), String8(ident).string(),
- String8(comment).string());
+ printf("Comment for @%s:%s/%s: %s\n", String8(myPackage).c_str(),
+ String8(curType).c_str(), String8(ident).c_str(),
+ String8(comment).c_str());
}
#endif
if (!localHasErrors) {
@@ -1710,9 +1710,9 @@
}
}
else if (code == ResXMLTree::END_TAG) {
- if (strcmp16(block.getElementName(&len), resources16.string()) != 0) {
+ if (strcmp16(block.getElementName(&len), resources16.c_str()) != 0) {
SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
- "Unexpected end tag %s\n", String8(block.getElementName(&len)).string());
+ "Unexpected end tag %s\n", String8(block.getElementName(&len)).c_str());
return UNKNOWN_ERROR;
}
}
@@ -1724,7 +1724,7 @@
}
SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
"Found text \"%s\" where item tag is expected\n",
- String8(block.getText(&len)).string());
+ String8(block.getText(&len)).c_str());
return UNKNOWN_ERROR;
}
}
@@ -1740,13 +1740,13 @@
const char* bundleProduct =
(bundle->getProduct() == NULL) ? "" : bundle->getProduct();
fprintf(stderr, "In resource file %s: %s\n",
- in->getPrintableSource().string(),
- curParams.toString().string());
+ in->getPrintableSource().c_str(),
+ curParams.toString().c_str());
fprintf(stderr, "\t%s '%s' does not match product %s.\n"
"\tYou may have forgotten to include a 'default' product variant"
" of the resource.\n",
- String8(p.type).string(), String8(p.ident).string(),
+ String8(p.type).c_str(), String8(p.ident).c_str(),
bundleProduct[0] == 0 ? "default" : bundleProduct);
return UNKNOWN_ERROR;
}
@@ -1816,7 +1816,7 @@
AssetManager featureAssetManager;
if (!featureAssetManager.addAssetPath(featureAfter, NULL)) {
fprintf(stderr, "ERROR: Feature package '%s' not found.\n",
- featureAfter.string());
+ featureAfter.c_str());
return UNKNOWN_ERROR;
}
@@ -1835,13 +1835,13 @@
const uint32_t ident)
{
uint32_t rid = mAssets->getIncludedResources()
- .identifierForName(name.string(), name.size(),
- type.string(), type.size(),
- package.string(), package.size());
+ .identifierForName(name.c_str(), name.size(),
+ type.c_str(), type.size(),
+ package.c_str(), package.size());
if (rid != 0) {
sourcePos.error("Error declaring public resource %s/%s for included package %s\n",
- String8(type).string(), String8(name).string(),
- String8(package).string());
+ String8(type).c_str(), String8(name).c_str(),
+ String8(package).c_str());
return UNKNOWN_ERROR;
}
@@ -1864,12 +1864,12 @@
const bool overwrite)
{
uint32_t rid = mAssets->getIncludedResources()
- .identifierForName(name.string(), name.size(),
- type.string(), type.size(),
- package.string(), package.size());
+ .identifierForName(name.c_str(), name.size(),
+ type.c_str(), type.size(),
+ package.c_str(), package.size());
if (rid != 0) {
sourcePos.error("Resource entry %s/%s is already defined in package %s.",
- String8(type).string(), String8(name).string(), String8(package).string());
+ String8(type).c_str(), String8(name).c_str(), String8(package).c_str());
return UNKNOWN_ERROR;
}
@@ -1899,12 +1899,12 @@
// Check for adding entries in other packages... for now we do
// nothing. We need to do the right thing here to support skinning.
uint32_t rid = mAssets->getIncludedResources()
- .identifierForName(name.string(), name.size(),
- type.string(), type.size(),
- package.string(), package.size());
+ .identifierForName(name.c_str(), name.size(),
+ type.c_str(), type.size(),
+ package.c_str(), package.size());
if (rid != 0) {
sourcePos.error("Resource entry %s/%s is already defined in package %s.",
- String8(type).string(), String8(name).string(), String8(package).string());
+ String8(type).c_str(), String8(name).c_str(), String8(package).c_str());
return UNKNOWN_ERROR;
}
@@ -1921,7 +1921,7 @@
}
if (!canAdd) {
sourcePos.error("Resource does not already exist in overlay at '%s'; use <add-resource> to add.\n",
- String8(name).string());
+ String8(name).c_str());
return UNKNOWN_ERROR;
}
}
@@ -1959,9 +1959,9 @@
// Check for adding entries in other packages... for now we do
// nothing. We need to do the right thing here to support skinning.
uint32_t rid = mAssets->getIncludedResources()
- .identifierForName(name.string(), name.size(),
- type.string(), type.size(),
- package.string(), package.size());
+ .identifierForName(name.c_str(), name.size(),
+ type.c_str(), type.size(),
+ package.c_str(), package.size());
if (rid != 0) {
return NO_ERROR;
}
@@ -1969,7 +1969,7 @@
#if 0
if (name == String16("left")) {
printf("Adding bag left: file=%s, line=%d, type=%s\n",
- sourcePos.file.striing(), sourcePos.line, String8(type).string());
+ sourcePos.file.striing(), sourcePos.line, String8(type).c_str());
}
#endif
sp<Entry> e = getEntry(package, type, name, sourcePos, replace, params);
@@ -1996,9 +1996,9 @@
{
// First look for this in the included resources...
uint32_t rid = mAssets->getIncludedResources()
- .identifierForName(name.string(), name.size(),
- type.string(), type.size(),
- package.string(), package.size());
+ .identifierForName(name.c_str(), name.size(),
+ type.c_str(), type.size(),
+ package.c_str(), package.size());
if (rid != 0) {
return true;
}
@@ -2022,9 +2022,9 @@
{
// First look for this in the included resources...
uint32_t rid = mAssets->getIncludedResources()
- .identifierForName(name.string(), name.size(),
- type.string(), type.size(),
- package.string(), package.size());
+ .identifierForName(name.c_str(), name.size(),
+ type.c_str(), type.size(),
+ package.c_str(), package.size());
if (rid != 0) {
return true;
}
@@ -2051,7 +2051,7 @@
const String16* defPackage)
{
String16 package, type, name;
- if (!ResTable::expandResourceRef(ref.string(), ref.size(), &package, &type, &name,
+ if (!ResTable::expandResourceRef(ref.c_str(), ref.size(), &package, &type, &name,
defType, defPackage ? defPackage:&mAssetsPackage, NULL)) {
return false;
}
@@ -2115,17 +2115,17 @@
// First look for this in the included resources...
uint32_t rid = mAssets->getIncludedResources()
- .identifierForName(name.string(), name.size(),
- attr16.string(), attr16.size(),
- package.string(), package.size());
+ .identifierForName(name.c_str(), name.size(),
+ attr16.c_str(), attr16.size(),
+ package.c_str(), package.size());
if (rid != 0) {
- source.error("Attribute \"%s\" has already been defined", String8(name).string());
+ source.error("Attribute \"%s\" has already been defined", String8(name).c_str());
return false;
}
sp<ResourceTable::Entry> entry = getEntry(package, attr16, name, source, false);
if (entry == NULL) {
- source.error("Failed to create entry attr/%s", String8(name).string());
+ source.error("Failed to create entry attr/%s", String8(name).c_str());
return false;
}
@@ -2146,7 +2146,7 @@
formatItem.value != formatValue16) {
source.error("Attribute \"%s\" already defined with incompatible format.\n"
"%s:%d: Original attribute defined here.",
- String8(name).string(), formatItem.sourcePos.file.string(),
+ String8(name).c_str(), formatItem.sourcePos.file.c_str(),
formatItem.sourcePos.line);
return false;
}
@@ -2207,9 +2207,9 @@
// First look for this in the included resources...
uint32_t specFlags = 0;
uint32_t rid = mAssets->getIncludedResources()
- .identifierForName(name.string(), name.size(),
- type.string(), type.size(),
- package.string(), package.size(),
+ .identifierForName(name.c_str(), name.size(),
+ type.c_str(), type.size(),
+ package.c_str(), package.size(),
&specFlags);
if (rid != 0) {
if (onlyPublic && (specFlags & ResTable_typeSpec::SPEC_PUBLIC) == 0) {
@@ -2253,27 +2253,27 @@
String16 package, type, name;
bool refOnlyPublic = true;
if (!ResTable::expandResourceRef(
- ref.string(), ref.size(), &package, &type, &name,
+ ref.c_str(), ref.size(), &package, &type, &name,
defType, defPackage ? defPackage:&mAssetsPackage,
outErrorMsg, &refOnlyPublic)) {
if (kIsDebug) {
- printf("Expanding resource: ref=%s\n", String8(ref).string());
+ printf("Expanding resource: ref=%s\n", String8(ref).c_str());
printf("Expanding resource: defType=%s\n",
- defType ? String8(*defType).string() : "NULL");
+ defType ? String8(*defType).c_str() : "NULL");
printf("Expanding resource: defPackage=%s\n",
- defPackage ? String8(*defPackage).string() : "NULL");
- printf("Expanding resource: ref=%s\n", String8(ref).string());
+ defPackage ? String8(*defPackage).c_str() : "NULL");
+ printf("Expanding resource: ref=%s\n", String8(ref).c_str());
printf("Expanded resource: p=%s, t=%s, n=%s, res=0\n",
- String8(package).string(), String8(type).string(),
- String8(name).string());
+ String8(package).c_str(), String8(type).c_str(),
+ String8(name).c_str());
}
return 0;
}
uint32_t res = getResId(package, type, name, onlyPublic && refOnlyPublic);
if (kIsDebug) {
printf("Expanded resource: p=%s, t=%s, n=%s, res=%d\n",
- String8(package).string(), String8(type).string(),
- String8(name).string(), res);
+ String8(package).c_str(), String8(type).c_str(),
+ String8(name).c_str(), res);
}
if (res == 0) {
if (outErrorMsg)
@@ -2284,7 +2284,7 @@
bool ResourceTable::isValidResourceName(const String16& s)
{
- const char16_t* p = s.string();
+ const char16_t* p = s.c_str();
bool first = true;
while (*p) {
if ((*p >= 'a' && *p <= 'z')
@@ -2315,7 +2315,7 @@
if (style == NULL || style->size() == 0) {
// Text is not styled so it can be any type... let's figure it out.
res = mAssets->getIncludedResources()
- .stringToValue(outValue, &finalStr, str.string(), str.size(), preserveSpaces,
+ .stringToValue(outValue, &finalStr, str.c_str(), str.size(), preserveSpaces,
coerceType, attrID, NULL, &mAssetsPackage, this,
accessorCookie, attrType);
} else {
@@ -2344,7 +2344,7 @@
if (kIsDebug) {
printf("Adding to pool string style #%zu config %s: %s\n",
style != NULL ? style->size() : 0U,
- configStr.string(), String8(finalStr).string());
+ configStr.c_str(), String8(finalStr).c_str());
}
if (style != NULL && style->size() > 0) {
outValue->data = pool->add(finalStr, *style, configTypeName, config);
@@ -2368,8 +2368,8 @@
uint32_t ResourceTable::getCustomResource(
const String16& package, const String16& type, const String16& name) const
{
- //printf("getCustomResource: %s %s %s\n", String8(package).string(),
- // String8(type).string(), String8(name).string());
+ //printf("getCustomResource: %s %s %s\n", String8(package).c_str(),
+ // String8(type).c_str(), String8(name).c_str());
sp<Package> p = mPackages.valueFor(package);
if (p == NULL) return 0;
sp<Type> t = p->getTypes().valueFor(type);
@@ -2400,7 +2400,7 @@
if (mAssetsPackage != package) {
mCurrentXmlPos.error("creating resource for external package %s: %s/%s.",
- String8(package).string(), String8(type).string(), String8(name).string());
+ String8(package).c_str(), String8(type).c_str(), String8(name).c_str());
if (package == String16("android")) {
mCurrentXmlPos.printf("did you mean to use @+id instead of @+android:id?");
}
@@ -2427,7 +2427,7 @@
Res_value value;
if (getItemValue(attrID, ResTable_map::ATTR_TYPE, &value)) {
//printf("getAttributeType #%08x (%s): #%08x\n", attrID,
- // String8(getEntry(attrID)->getName()).string(), value.data);
+ // String8(getEntry(attrID)->getName()).c_str(), value.data);
*outType = value.data;
return true;
}
@@ -2481,7 +2481,7 @@
vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
ac->sourcePos.error("Error: %s (at '%s' with value '%s').\n",
- buf, ac->attr.string(), ac->value.string());
+ buf, ac->attr.c_str(), ac->value.c_str());
}
}
@@ -2493,7 +2493,7 @@
const size_t N = e->getBag().size();
for (size_t i=0; i<N; i++) {
const String16& key = e->getBag().keyAt(i);
- if (key.size() > 0 && key.string()[0] != '^') {
+ if (key.size() > 0 && key.c_str()[0] != '^') {
outKeys->add(key);
}
}
@@ -2506,14 +2506,14 @@
uint32_t attrID, const char16_t* name, size_t nameLen,
Res_value* outValue)
{
- //printf("getAttributeEnum #%08x %s\n", attrID, String8(name, nameLen).string());
+ //printf("getAttributeEnum #%08x %s\n", attrID, String8(name, nameLen).c_str());
String16 nameStr(name, nameLen);
sp<const Entry> e = getEntry(attrID);
if (e != NULL) {
const size_t N = e->getBag().size();
for (size_t i=0; i<N; i++) {
- //printf("Comparing %s to %s\n", String8(name, nameLen).string(),
- // String8(e->getBag().keyAt(i)).string());
+ //printf("Comparing %s to %s\n", String8(name, nameLen).c_str(),
+ // String8(e->getBag().keyAt(i)).c_str());
if (e->getBag().keyAt(i) == nameStr) {
return getItemValue(attrID, e->getBag().valueAt(i).bagKeyId, outValue);
}
@@ -2529,7 +2529,7 @@
outValue->dataType = Res_value::TYPE_INT_HEX;
outValue->data = 0;
- //printf("getAttributeFlags #%08x %s\n", attrID, String8(name, nameLen).string());
+ //printf("getAttributeFlags #%08x %s\n", attrID, String8(name, nameLen).c_str());
String16 nameStr(name, nameLen);
sp<const Entry> e = getEntry(attrID);
if (e != NULL) {
@@ -2546,8 +2546,8 @@
String16 nameStr(start, pos-start);
size_t i;
for (i=0; i<N; i++) {
- //printf("Comparing \"%s\" to \"%s\"\n", String8(nameStr).string(),
- // String8(e->getBag().keyAt(i)).string());
+ //printf("Comparing \"%s\" to \"%s\"\n", String8(nameStr).c_str(),
+ // String8(e->getBag().keyAt(i)).c_str());
if (e->getBag().keyAt(i) == nameStr) {
Res_value val;
bool got = getItemValue(attrID, e->getBag().valueAt(i).bagKeyId, &val);
@@ -2753,7 +2753,7 @@
if (mHasDefaultLocalization.find(c->getName())
== mHasDefaultLocalization.end()) {
// printf("Skip symbol [%08x] %s\n", rid,
- // String8(c->getName()).string());
+ // String8(c->getName()).c_str());
continue;
}
}
@@ -2763,7 +2763,7 @@
String16 comment(c->getComment());
typeSymbols->appendComment(String8(c->getName()), comment, c->getPos());
//printf("Type symbol [%08x] %s comment: %s\n", rid,
- // String8(c->getName()).string(), String8(comment).string());
+ // String8(c->getName()).c_str(), String8(comment).c_str());
comment = c->getTypeComment();
typeSymbols->appendTypeComment(String8(c->getName()), comment);
}
@@ -2809,10 +2809,10 @@
// Look for strings with no default localization
if (configSrcMap.count(defaultLocale) == 0) {
SourcePos().warning("string '%s' has no default translation.",
- String8(nameIter.first).string());
+ String8(nameIter.first).c_str());
if (mBundle->getVerbose()) {
for (const auto& locale : configSrcMap) {
- locale.second.printf("locale %s found", locale.first.string());
+ locale.second.printf("locale %s found", locale.first.c_str());
}
}
// !!! TODO: throw an error here in some circumstances
@@ -2820,7 +2820,7 @@
// Check that all requested localizations are present for this string
if (mBundle->getConfigurations().size() > 0 && mBundle->getRequireLocalization()) {
- const char* allConfigs = mBundle->getConfigurations().string();
+ const char* allConfigs = mBundle->getConfigurations().c_str();
const char* start = allConfigs;
const char* comma;
@@ -2847,7 +2847,7 @@
// requiring a specific regional localization [e.g. de_DE] but there is an
// available string in the generic language localization [e.g. de];
// consider that string to have fulfilled the localization requirement.
- String8 region(config.string(), 2);
+ String8 region(config.c_str(), 2);
if (configSrcMap.find(region) == configSrcMap.end() &&
configSrcMap.count(defaultLocale) == 0) {
missingConfigs.insert(config);
@@ -2859,12 +2859,12 @@
if (!missingConfigs.empty()) {
String8 configStr;
for (const auto& iter : missingConfigs) {
- configStr.appendFormat(" %s", iter.string());
+ configStr.appendFormat(" %s", iter.c_str());
}
SourcePos().warning("string '%s' is missing %u required localizations:%s",
- String8(nameIter.first).string(),
+ String8(nameIter.first).c_str(),
(unsigned int)missingConfigs.size(),
- configStr.string());
+ configStr.c_str());
}
}
}
@@ -3021,7 +3021,7 @@
header->header.type = htods(RES_TABLE_PACKAGE_TYPE);
header->header.headerSize = htods(sizeof(*header));
header->id = htodl(static_cast<uint32_t>(p->getAssignedId()));
- strcpy16_htod(header->name, p->getName().string());
+ strcpy16_htod(header->name, p->getName().c_str());
// Write the string blocks.
const size_t typeStringsStart = data->getSize();
@@ -3061,7 +3061,7 @@
sp<Type> t = p->getTypes().valueFor(typeName);
LOG_ALWAYS_FATAL_IF(t == NULL && typeName != String16("<empty>"),
"Type name %s not found",
- String8(typeName).string());
+ String8(typeName).c_str());
if (t == NULL) {
continue;
}
@@ -3260,7 +3260,7 @@
sp<ConfigList> c = t->getOrderedConfigs().itemAt(i);
if (c != NULL) {
fprintf(stderr, "%s: no entries written for %s/%s (0x%08zx)\n", log_prefix,
- String8(typeName).string(), String8(c->getName()).string(),
+ String8(typeName).c_str(), String8(c->getName()).c_str(),
Res_MAKEID(p->getAssignedId() - 1, ti, i));
}
missing_entry = true;
@@ -3359,7 +3359,7 @@
sp<Package> libPackage = libs[i];
if (kIsDebug) {
fprintf(stderr, " Entry %s -> 0x%02x\n",
- String8(libPackage->getName()).string(),
+ String8(libPackage->getName()).c_str(),
(uint8_t)libPackage->getAssignedId());
}
@@ -3367,7 +3367,7 @@
entryStart, sizeof(ResTable_lib_entry));
memset(entry, 0, sizeof(*entry));
entry->packageId = htodl(libPackage->getAssignedId());
- strcpy16_htod(entry->packageName, libPackage->getName().string());
+ strcpy16_htod(entry->packageName, libPackage->getName().c_str());
}
}
return NO_ERROR;
@@ -3435,13 +3435,13 @@
const SourcePos& pos = c->getEntries().valueAt(k)->getPos();
if (pos.file != "") {
fprintf(fp," <!-- Declared at %s:%d -->\n",
- pos.file.string(), pos.line);
+ pos.file.c_str(), pos.line);
}
}
}
fprintf(fp, " <public type=\"%s\" name=\"%s\" id=\"0x%08x\" />\n",
- String8(t->getName()).string(),
- String8(c->getName()).string(),
+ String8(t->getName()).c_str(),
+ String8(c->getName()).c_str(),
getResId(pkg, t, c->getEntryIndex()));
}
}
@@ -3501,8 +3501,8 @@
}
sourcePos.error("Resource entry %s is already defined as a single item.\n"
"%s:%d: Originally defined here.\n",
- String8(mName).string(),
- mItem.sourcePos.file.string(), mItem.sourcePos.line);
+ String8(mName).c_str(),
+ mItem.sourcePos.file.c_str(), mItem.sourcePos.line);
return UNKNOWN_ERROR;
}
@@ -3517,21 +3517,21 @@
if (mType == TYPE_BAG) {
if (mBag.size() == 0) {
sourcePos.error("Resource entry %s is already defined as a bag.",
- String8(mName).string());
+ String8(mName).c_str());
} else {
const Item& item(mBag.valueAt(0));
sourcePos.error("Resource entry %s is already defined as a bag.\n"
"%s:%d: Originally defined here.\n",
- String8(mName).string(),
- item.sourcePos.file.string(), item.sourcePos.line);
+ String8(mName).c_str(),
+ item.sourcePos.file.c_str(), item.sourcePos.line);
}
return UNKNOWN_ERROR;
}
if ( (mType != TYPE_UNKNOWN) && (overwrite == false) ) {
sourcePos.error("Resource entry %s is already defined.\n"
"%s:%d: Originally defined here.\n",
- String8(mName).string(),
- mItem.sourcePos.file.string(), mItem.sourcePos.line);
+ String8(mName).c_str(),
+ mItem.sourcePos.file.c_str(), mItem.sourcePos.line);
return UNKNOWN_ERROR;
}
@@ -3562,12 +3562,12 @@
const Item& item(mBag.valueAt(origKey));
sourcePos.error("Resource entry %s already has bag item %s.\n"
"%s:%d: Originally defined here.\n",
- String8(mName).string(), String8(key).string(),
- item.sourcePos.file.string(), item.sourcePos.line);
+ String8(mName).c_str(), String8(key).c_str(),
+ item.sourcePos.file.c_str(), item.sourcePos.line);
return UNKNOWN_ERROR;
}
//printf("Replacing %s with %s\n",
- // String8(mBag.valueFor(key).value).string(), String8(value).string());
+ // String8(mBag.valueFor(key).value).c_str(), String8(value).c_str());
mBag.replaceValueFor(key, item);
}
@@ -3611,8 +3611,8 @@
String16 value("false");
if (kIsDebug) {
fprintf(stderr, "Generating %s:id/%s\n",
- String8(package).string(),
- String8(key).string());
+ String8(package).c_str(),
+ String8(key).c_str());
}
status_t err = table->addEntry(SourcePos(String8("<generated>"), 0), package,
id16, key, value);
@@ -3624,10 +3624,10 @@
#if 1
// fprintf(stderr, "ERROR: Bag attribute '%s' has not been defined.\n",
-// String8(key).string());
+// String8(key).c_str());
// const Item& item(mBag.valueAt(i));
// fprintf(stderr, "Referenced from file %s line %d\n",
-// item.sourcePos.file.string(), item.sourcePos.line);
+// item.sourcePos.file.c_str(), item.sourcePos.line);
// return UNKNOWN_ERROR;
#else
char numberStr[16];
@@ -3660,7 +3660,7 @@
mParentId = table->getResId(mParent, &style16, NULL, &errorMsg);
if (mParentId == 0) {
mPos.error("Error retrieving parent for item: %s '%s'.\n",
- errorMsg, String8(mParent).string());
+ errorMsg, String8(mParent).c_str());
hasErrors = true;
}
}
@@ -3670,11 +3670,11 @@
Item& it = mBag.editValueAt(i);
it.bagKeyId = table->getResId(key,
it.isId ? &id16 : &attr16, NULL, &errorMsg);
- //printf("Bag key of %s: #%08x\n", String8(key).string(), it.bagKeyId);
+ //printf("Bag key of %s: #%08x\n", String8(key).c_str(), it.bagKeyId);
if (it.bagKeyId == 0) {
it.sourcePos.error("Error: %s: %s '%s'.\n", errorMsg,
- String8(it.isId ? id16 : attr16).string(),
- String8(key).string());
+ String8(it.isId ? id16 : attr16).c_str(),
+ String8(key).c_str());
hasErrors = true;
}
}
@@ -3709,7 +3709,7 @@
}
} else {
mPos.error("Error: entry %s is not a single item or a bag.\n",
- String8(mName).string());
+ String8(mName).c_str());
return UNKNOWN_ERROR;
}
return NO_ERROR;
@@ -3732,7 +3732,7 @@
}
} else {
mPos.error("Error: entry %s is not a single item or a bag.\n",
- String8(mName).string());
+ String8(mName).c_str());
return UNKNOWN_ERROR;
}
return NO_ERROR;
@@ -3768,7 +3768,7 @@
par.data = htodl(it.parsedValue.data);
#if 0
printf("Writing item (%s): type=%d, data=0x%x, res0=0x%x\n",
- String8(mName).string(), it.parsedValue.dataType,
+ String8(mName).c_str(), it.parsedValue.dataType,
it.parsedValue.data, par.res0);
#endif
err = data->writeData(&par, it.parsedValue.size);
@@ -3852,7 +3852,7 @@
int32_t entryIdx = Res_GETENTRY(ident);
if (entryIdx < 0) {
sourcePos.error("Public resource %s/%s has an invalid 0 identifier (0x%08x).\n",
- String8(mName).string(), String8(name).string(), ident);
+ String8(mName).c_str(), String8(name).c_str(), ident);
return UNKNOWN_ERROR;
}
#endif
@@ -3863,7 +3863,7 @@
if (mPublicIndex > 0 && mPublicIndex != typeIdx) {
sourcePos.error("Public resource %s/%s has conflicting type codes for its"
" public identifiers (0x%x vs 0x%x).\n",
- String8(mName).string(), String8(name).string(),
+ String8(mName).c_str(), String8(name).c_str(),
mPublicIndex, typeIdx);
return UNKNOWN_ERROR;
}
@@ -3882,8 +3882,8 @@
sourcePos.error("Public resource %s/%s has conflicting public identifiers"
" (0x%08x vs 0x%08x).\n"
"%s:%d: Originally defined here.\n",
- String8(mName).string(), String8(name).string(), p.ident, ident,
- p.sourcePos.file.string(), p.sourcePos.line);
+ String8(mName).c_str(), String8(name).c_str(), p.ident, ident,
+ p.sourcePos.file.c_str(), p.sourcePos.line);
return UNKNOWN_ERROR;
}
}
@@ -3909,7 +3909,7 @@
if (overlay && !autoAddOverlay && mCanAddEntries.indexOf(entry) < 0) {
sourcePos.error("Resource at %s appears in overlay but not"
" in the base package; use <add-resource> to add.\n",
- String8(entry).string());
+ String8(entry).c_str());
return NULL;
}
c = new ConfigList(entry, sourcePos);
@@ -3931,7 +3931,7 @@
printf("New entry at %s:%d: imsi:%d/%d lang:%c%c cnt:%c%c "
"orien:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d "
"sw%ddp w%ddp h%ddp layout:%d\n",
- sourcePos.file.string(), sourcePos.line,
+ sourcePos.file.c_str(), sourcePos.line,
config->mcc, config->mnc,
config->language[0] ? config->language[0] : '-',
config->language[1] ? config->language[1] : '-',
@@ -3951,7 +3951,7 @@
config->screenLayout);
} else {
printf("New entry at %s:%d: NULL config\n",
- sourcePos.file.string(), sourcePos.line);
+ sourcePos.file.c_str(), sourcePos.line);
}
}
e = new Entry(entry, sourcePos);
@@ -4032,11 +4032,11 @@
const Public& p = mPublic.valueAt(j);
int32_t idx = Res_GETENTRY(p.ident);
//printf("Looking for entry \"%s\"/\"%s\" (0x%08x) in %d...\n",
- // String8(mName).string(), String8(name).string(), p.ident, N);
+ // String8(mName).c_str(), String8(name).c_str(), p.ident, N);
bool found = false;
for (i=0; i<N; i++) {
sp<ConfigList> e = origOrder.itemAt(i);
- //printf("#%d: \"%s\"\n", i, String8(e->getName()).string());
+ //printf("#%d: \"%s\"\n", i, String8(e->getName()).c_str());
if (e->getName() == name) {
if (idx >= (int32_t)mOrderedConfigs.size()) {
mOrderedConfigs.resize(idx + 1);
@@ -4056,10 +4056,10 @@
p.sourcePos.error("Multiple entry names declared for public entry"
" identifier 0x%x in type %s (%s vs %s).\n"
"%s:%d: Originally defined here.",
- idx+1, String8(mName).string(),
- String8(oe->getName()).string(),
- String8(name).string(),
- oe->getPublicSourcePos().file.string(),
+ idx+1, String8(mName).c_str(),
+ String8(oe->getName()).c_str(),
+ String8(name).c_str(),
+ oe->getPublicSourcePos().file.c_str(),
oe->getPublicSourcePos().line);
hasError = true;
}
@@ -4068,7 +4068,7 @@
if (!found) {
p.sourcePos.error("Public symbol %s/%s declared here is not defined.",
- String8(mName).string(), String8(name).string());
+ String8(mName).c_str(), String8(name).c_str());
hasError = true;
}
}
@@ -4189,9 +4189,9 @@
t->getFirstPublicSourcePos().error("Multiple type names declared for public type"
" identifier 0x%x (%s vs %s).\n"
"%s:%d: Originally defined here.",
- idx, String8(ot->getName()).string(),
- String8(t->getName()).string(),
- ot->getFirstPublicSourcePos().file.string(),
+ idx, String8(ot->getName()).c_str(),
+ String8(t->getName()).c_str(),
+ ot->getFirstPublicSourcePos().file.c_str(),
ot->getFirstPublicSourcePos().line);
return UNKNOWN_ERROR;
}
@@ -4399,8 +4399,8 @@
const Item& it = e->getBag().valueAt(i);
if (it.bagKeyId == 0) {
fprintf(stderr, "warning: ID not yet assigned to '%s' in bag '%s'\n",
- String8(e->getName()).string(),
- String8(e->getBag().keyAt(i)).string());
+ String8(e->getName()).c_str(),
+ String8(e->getBag().keyAt(i)).c_str());
}
if (it.bagKeyId == attrID) {
return ⁢
@@ -4427,8 +4427,8 @@
}
}
fprintf(stderr, "warning: Circular reference detected in key '%s' of bag '%s'\n",
- String8(e->getName()).string(),
- String8(e->getBag().keyAt(i)).string());
+ String8(e->getName()).c_str(),
+ String8(e->getBag().keyAt(i)).c_str());
return false;
}
item->evaluating = true;
@@ -4436,7 +4436,7 @@
if (kIsDebug) {
if (res) {
printf("getItemValue of #%08x[#%08x] (%s): type=#%08x, data=#%08x\n",
- resID, attrID, String8(getEntry(resID)->getName()).string(),
+ resID, attrID, String8(getEntry(resID)->getName()).c_str(),
outValue->dataType, outValue->data);
} else {
printf("getItemValue of #%08x[#%08x]: failed\n",
@@ -4713,10 +4713,10 @@
entriesToAdd[i].value->getPos()
.printf("using v%d attributes; synthesizing resource %s:%s/%s for configuration %s.",
entriesToAdd[i].key.sdkVersion,
- String8(p->getName()).string(),
- String8(t->getName()).string(),
- String8(entriesToAdd[i].value->getName()).string(),
- entriesToAdd[i].key.toString().string());
+ String8(p->getName()).c_str(),
+ String8(t->getName()).c_str(),
+ String8(entriesToAdd[i].value->getName()).c_str(),
+ entriesToAdd[i].key.toString().c_str());
}
sp<Entry> newEntry = t->getEntry(c->getName(),
@@ -4801,8 +4801,8 @@
sp<AaptFile> newFile = new AaptFile(target->getSourceFile(),
AaptGroupEntry(newConfig), target->getResourceType());
String8 resPath = String8::format("res/%s/%s.xml",
- newFile->getGroupEntry().toDirName(target->getResourceType()).string(),
- String8(resourceName).string());
+ newFile->getGroupEntry().toDirName(target->getResourceType()).c_str(),
+ String8(resourceName).c_str());
resPath.convertToResPath();
// Add a resource table entry.
@@ -4893,10 +4893,10 @@
if (bundle->getVerbose()) {
SourcePos(node->getFilename(), node->getStartLineNumber()).printf(
"removing attribute %s%s%s from <%s>",
- String8(attr.ns).string(),
+ String8(attr.ns).c_str(),
(attr.ns.size() == 0 ? "" : ":"),
- String8(attr.name).string(),
- String8(node->getElementName()).string());
+ String8(attr.name).c_str(),
+ String8(node->getElementName()).c_str());
}
node->removeAttribute(i);
i--;
@@ -4925,8 +4925,8 @@
sp<AaptFile> newFile = new AaptFile(target->getSourceFile(),
AaptGroupEntry(newConfig), target->getResourceType());
String8 resPath = String8::format("res/%s/%s.xml",
- newFile->getGroupEntry().toDirName(target->getResourceType()).string(),
- String8(resourceName).string());
+ newFile->getGroupEntry().toDirName(target->getResourceType()).c_str(),
+ String8(resourceName).c_str());
resPath.convertToResPath();
// Add a resource table entry.
@@ -4934,10 +4934,10 @@
SourcePos(target->getSourceFile(), -1).printf(
"using v%d attributes; synthesizing resource %s:%s/%s for configuration %s.",
newConfig.sdkVersion,
- mAssets->getPackage().string(),
- newFile->getResourceType().string(),
- String8(resourceName).string(),
- newConfig.toString().string());
+ mAssets->getPackage().c_str(),
+ newFile->getResourceType().c_str(),
+ String8(resourceName).c_str(),
+ newConfig.toString().c_str());
}
addEntry(SourcePos(),
@@ -5114,8 +5114,8 @@
sp<XMLNode> nestedRoot = findOnlyChildElement(child);
if (nestedRoot == NULL) {
source.error("<%s:%s> must have exactly one child element",
- String8(child->getElementNamespace()).string(),
- String8(child->getElementName()).string());
+ String8(child->getElementNamespace()).c_str(),
+ String8(child->getElementName()).c_str());
return UNKNOWN_ERROR;
}
@@ -5130,7 +5130,7 @@
// Parse the attribute name.
const char* errorMsg = NULL;
String16 attrPackage, attrType, attrName;
- bool result = ResTable::expandResourceRef(attr->string.string(),
+ bool result = ResTable::expandResourceRef(attr->string.c_str(),
attr->string.size(),
&attrPackage, &attrType, &attrName,
&kAttr16, &kAssetPackage16,
@@ -5156,11 +5156,11 @@
// This child element will be extracted into its own resource file.
// Generate a name and path for it from its parent.
nestedResourceName = String8::format("%s_%d",
- String8(resourceName).string(), suffix++);
+ String8(resourceName).c_str(), suffix++);
nestedResourcePath = String8::format("res/%s/%s.xml",
target->getGroupEntry().toDirName(target->getResourceType())
- .string(),
- nestedResourceName.string());
+ .c_str(),
+ nestedResourceName.c_str());
// Lookup or create the entry for this name.
sp<Entry> entry = getEntry(kAssetPackage16,
@@ -5187,20 +5187,20 @@
if (bundle->getVerbose()) {
source.printf("generating nested resource %s:%s/%s",
- mAssets->getPackage().string(), target->getResourceType().string(),
- nestedResourceName.string());
+ mAssets->getPackage().c_str(), target->getResourceType().c_str(),
+ nestedResourceName.c_str());
}
// Build the attribute reference and assign it to the parent.
String16 nestedResourceRef = String16(String8::format("@%s:%s/%s",
- mAssets->getPackage().string(), target->getResourceType().string(),
- nestedResourceName.string()));
+ mAssets->getPackage().c_str(), target->getResourceType().c_str(),
+ nestedResourceName.c_str()));
String16 attrNs = buildNamespace(attrPackage);
if (parent->getAttribute(attrNs, attrName) != NULL) {
SourcePos(parent->getFilename(), parent->getStartLineNumber())
.error("parent of nested resource already defines attribute '%s:%s'",
- String8(attrPackage).string(), String8(attrName).string());
+ String8(attrPackage).c_str(), String8(attrName).c_str());
return UNKNOWN_ERROR;
}
diff --git a/tools/aapt/SourcePos.cpp b/tools/aapt/SourcePos.cpp
index 3864320..e130286 100644
--- a/tools/aapt/SourcePos.cpp
+++ b/tools/aapt/SourcePos.cpp
@@ -80,12 +80,12 @@
if (!this->file.isEmpty()) {
if (this->line >= 0) {
- fprintf(to, "%s:%d: %s%s\n", this->file.string(), this->line, type, this->error.string());
+ fprintf(to, "%s:%d: %s%s\n", this->file.c_str(), this->line, type, this->error.c_str());
} else {
- fprintf(to, "%s: %s%s\n", this->file.string(), type, this->error.string());
+ fprintf(to, "%s: %s%s\n", this->file.c_str(), type, this->error.c_str());
}
} else {
- fprintf(to, "%s%s\n", type, this->error.string());
+ fprintf(to, "%s%s\n", type, this->error.c_str());
}
}
diff --git a/tools/aapt/StringPool.cpp b/tools/aapt/StringPool.cpp
index 6cacd32..8d02683 100644
--- a/tools/aapt/StringPool.cpp
+++ b/tools/aapt/StringPool.cpp
@@ -67,7 +67,7 @@
const size_t NS = pool->size();
for (size_t s=0; s<NS; s++) {
auto str = pool->string8ObjectAt(s);
- printf("String #" ZD ": %s\n", (ZD_TYPE) s, (str.has_value() ? str->string() : ""));
+ printf("String #" ZD ": %s\n", (ZD_TYPE) s, (str.has_value() ? str->c_str() : ""));
}
}
@@ -139,7 +139,7 @@
if (eidx < 0) {
eidx = mEntries.add(entry(value));
if (eidx < 0) {
- fprintf(stderr, "Failure adding string %s\n", String8(value).string());
+ fprintf(stderr, "Failure adding string %s\n", String8(value).c_str());
return eidx;
}
}
@@ -148,7 +148,7 @@
entry& ent = mEntries.editItemAt(eidx);
if (kIsDebug) {
printf("*** adding config type name %s, was %s\n",
- configTypeName->string(), ent.configTypeName.string());
+ configTypeName->c_str(), ent.configTypeName.c_str());
}
if (ent.configTypeName.size() <= 0) {
ent.configTypeName = *configTypeName;
@@ -166,7 +166,7 @@
if (cmp >= 0) {
if (cmp > 0) {
if (kIsDebug) {
- printf("*** inserting config: %s\n", config->toString().string());
+ printf("*** inserting config: %s\n", config->toString().c_str());
}
ent.configs.insertAt(*config, addPos);
}
@@ -175,7 +175,7 @@
}
if (addPos >= ent.configs.size()) {
if (kIsDebug) {
- printf("*** adding config: %s\n", config->toString().string());
+ printf("*** adding config: %s\n", config->toString().c_str());
}
ent.configs.add(*config);
}
@@ -195,7 +195,7 @@
if (kIsDebug) {
printf("Adding string %s to pool: pos=%zd eidx=%zd vidx=%zd\n",
- String8(value).string(), pos, eidx, vidx);
+ String8(value).c_str(), pos, eidx, vidx);
}
return pos;
@@ -286,13 +286,13 @@
for (size_t i=0; i<N; i++) {
printf("#%d was %d: %s\n", i, newPosToOriginalPos[i],
- mEntries[mEntryArray[newPosToOriginalPos[i]]].makeConfigsString().string());
+ mEntries[mEntryArray[newPosToOriginalPos[i]]].makeConfigsString().c_str());
entries.add(mEntries[mEntryArray[i]]);
}
for (size_t i=0; i<entries.size(); i++) {
printf("Sorted config #%d: %s\n", i,
- entries[i].makeConfigsString().string());
+ entries[i].makeConfigsString().c_str());
}
#endif
@@ -363,8 +363,8 @@
printf("FINAL SORTED STRING CONFIGS:\n");
for (size_t i=0; i<mEntries.size(); i++) {
const entry& ent = mEntries[i];
- printf("#" ZD " %s: %s\n", (ZD_TYPE)i, ent.makeConfigsString().string(),
- String8(ent.value).string());
+ printf("#" ZD " %s: %s\n", (ZD_TYPE)i, ent.makeConfigsString().c_str(),
+ String8(ent.value).c_str());
}
#endif
}
@@ -415,7 +415,7 @@
ssize_t idx = add(span.name, true);
if (idx < 0) {
fprintf(stderr, "Error adding span for style tag '%s'\n",
- String8(span.name).string());
+ String8(span.name).c_str());
return idx;
}
span.span.name.index = (uint32_t)idx;
@@ -571,7 +571,7 @@
if (kIsDebug) {
printf("Writing entry #%zu: \"%s\" ent=%zu off=%zu\n",
i,
- String8(ent.value).string(),
+ String8(ent.value).c_str(),
mEntryArray[i],
ent.offset);
}
@@ -591,8 +591,8 @@
const Vector<size_t>* indices = offsetsForString(val);
ssize_t res = indices != NULL && indices->size() > 0 ? indices->itemAt(0) : -1;
if (kIsDebug) {
- printf("Offset for string %s: %zd (%s)\n", String8(val).string(), res,
- res >= 0 ? String8(mEntries[mEntryArray[res]].value).string() : String8());
+ printf("Offset for string %s: %zd (%s)\n", String8(val).c_str(), res,
+ res >= 0 ? String8(mEntries[mEntryArray[res]].value).c_str() : String8());
}
return res;
}
diff --git a/tools/aapt/Symbol.h b/tools/aapt/Symbol.h
index e157541..de1d60c 100644
--- a/tools/aapt/Symbol.h
+++ b/tools/aapt/Symbol.h
@@ -68,9 +68,9 @@
android::String8 Symbol::toString() const {
return android::String8::format("%s:%s/%s (0x%08x)",
- android::String8(package).string(),
- android::String8(type).string(),
- android::String8(name).string(),
+ android::String8(package).c_str(),
+ android::String8(type).c_str(),
+ android::String8(name).c_str(),
(int) id);
}
diff --git a/tools/aapt/XMLNode.cpp b/tools/aapt/XMLNode.cpp
index 69392d6..e270a73 100644
--- a/tools/aapt/XMLNode.cpp
+++ b/tools/aapt/XMLNode.cpp
@@ -66,14 +66,14 @@
String16 getNamespaceResourcePackage(const String16& appPackage, const String16& namespaceUri, bool* outIsPublic)
{
- //printf("%s starts with %s?\n", String8(namespaceUri).string(),
- // String8(RESOURCES_PREFIX).string());
+ //printf("%s starts with %s?\n", String8(namespaceUri).c_str(),
+ // String8(RESOURCES_PREFIX).c_str());
size_t prefixSize;
bool isPublic = true;
if(namespaceUri.startsWith(RESOURCES_PREFIX_AUTO_PACKAGE)) {
if (kIsDebug) {
- printf("Using default application package: %s -> %s\n", String8(namespaceUri).string(),
- String8(appPackage).string());
+ printf("Using default application package: %s -> %s\n", String8(namespaceUri).c_str(),
+ String8(appPackage).c_str());
}
isPublic = true;
return appPackage;
@@ -88,7 +88,7 @@
}
//printf("YES!\n");
- //printf("namespace: %s\n", String8(String16(namespaceUri, namespaceUri.size()-prefixSize, prefixSize)).string());
+ //printf("namespace: %s\n", String8(String16(namespaceUri, namespaceUri.size()-prefixSize, prefixSize)).c_str());
if (outIsPublic) *outIsPublic = isPublic;
return String16(namespaceUri, namespaceUri.size()-prefixSize, prefixSize);
}
@@ -97,7 +97,7 @@
ResXMLTree* inXml,
const String16& str16)
{
- const char16_t* str = str16.string();
+ const char16_t* str = str16.c_str();
const char16_t* p = str;
const char16_t* end = str + str16.size();
@@ -223,7 +223,7 @@
String16 text(inXml->getText(&len));
if (firstTime && text.size() > 0) {
firstTime = false;
- if (text.string()[0] == '@') {
+ if (text.c_str()[0] == '@') {
// If this is a resource reference, don't do the pseudoloc.
pseudolocalize = NO_PSEUDOLOCALIZATION;
pseudo.setMethod(pseudolocalize);
@@ -263,7 +263,7 @@
{
SourcePos(String8(fileName), inXml->getLineNumber()).error(
"Found unsupported XLIFF tag <%s>\n",
- element8.string());
+ element8.c_str());
return UNKNOWN_ERROR;
}
moveon:
@@ -272,14 +272,14 @@
if (outSpans == NULL) {
SourcePos(String8(fileName), inXml->getLineNumber()).error(
- "Found style tag <%s> where styles are not allowed\n", element8.string());
+ "Found style tag <%s> where styles are not allowed\n", element8.c_str());
return UNKNOWN_ERROR;
}
- if (!ResTable::collectString(outString, curString.string(),
+ if (!ResTable::collectString(outString, curString.c_str(),
curString.size(), false, &errorMsg, true)) {
SourcePos(String8(fileName), inXml->getLineNumber()).error("%s (in %s)\n",
- errorMsg, String8(curString).string());
+ errorMsg, String8(curString).c_str());
return UNKNOWN_ERROR;
}
rawString.append(curString);
@@ -295,7 +295,7 @@
str = inXml->getAttributeStringValue(ai, &len);
span.name.append(str, len);
}
- //printf("Span: %s\n", String8(span.name).string());
+ //printf("Span: %s\n", String8(span.name).c_str());
span.span.firstChar = span.span.lastChar = outString->size();
spanStack.push(span);
@@ -311,21 +311,21 @@
xliffDepth--;
continue;
}
- if (!ResTable::collectString(outString, curString.string(),
+ if (!ResTable::collectString(outString, curString.c_str(),
curString.size(), false, &errorMsg, true)) {
SourcePos(String8(fileName), inXml->getLineNumber()).error("%s (in %s)\n",
- errorMsg, String8(curString).string());
+ errorMsg, String8(curString).c_str());
return UNKNOWN_ERROR;
}
rawString.append(curString);
curString = String16();
if (spanStack.size() == 0) {
- if (strcmp16(inXml->getElementName(&len), endTag.string()) != 0) {
+ if (strcmp16(inXml->getElementName(&len), endTag.c_str()) != 0) {
SourcePos(String8(fileName), inXml->getLineNumber()).error(
"Found tag %s where <%s> close is expected\n",
- String8(inXml->getElementName(&len)).string(),
- String8(endTag).string());
+ String8(inXml->getElementName(&len)).c_str(),
+ String8(endTag).c_str());
return UNKNOWN_ERROR;
}
break;
@@ -334,15 +334,15 @@
String16 spanTag;
ssize_t semi = span.name.findFirst(';');
if (semi >= 0) {
- spanTag.setTo(span.name.string(), semi);
+ spanTag.setTo(span.name.c_str(), semi);
} else {
spanTag.setTo(span.name);
}
- if (strcmp16(inXml->getElementName(&len), spanTag.string()) != 0) {
+ if (strcmp16(inXml->getElementName(&len), spanTag.c_str()) != 0) {
SourcePos(String8(fileName), inXml->getLineNumber()).error(
"Found close tag %s where close tag %s is expected\n",
- String8(inXml->getElementName(&len)).string(),
- String8(spanTag).string());
+ String8(inXml->getElementName(&len)).c_str(),
+ String8(spanTag).c_str());
return UNKNOWN_ERROR;
}
bool empty = true;
@@ -363,7 +363,7 @@
if (0 && empty) {
fprintf(stderr, "%s:%d: warning: empty '%s' span found in text '%s'\n",
fileName, inXml->getLineNumber(),
- String8(spanTag).string(), String8(*outString).string());
+ String8(spanTag).c_str(), String8(*outString).c_str());
}
} else if (code == ResXMLTree::START_NAMESPACE) {
@@ -380,11 +380,11 @@
if (outSpans != NULL && outSpans->size() > 0) {
if (curString.size() > 0) {
- if (!ResTable::collectString(outString, curString.string(),
+ if (!ResTable::collectString(outString, curString.c_str(),
curString.size(), false, &errorMsg, true)) {
SourcePos(String8(fileName), inXml->getLineNumber()).error(
"%s (in %s)\n",
- errorMsg, String8(curString).string());
+ errorMsg, String8(curString).c_str());
return UNKNOWN_ERROR;
}
}
@@ -450,10 +450,10 @@
String8 elemNs = build_namespace(namespaces, ns16);
const char16_t* com16 = block->getComment(&len);
if (com16) {
- printf("%s <!-- %s -->\n", prefix.string(), String8(com16).string());
+ printf("%s <!-- %s -->\n", prefix.c_str(), String8(com16).c_str());
}
- printf("%sE: %s%s (line=%d)\n", prefix.string(), elemNs.string(),
- String8(block->getElementName(&len)).string(),
+ printf("%sE: %s%s (line=%d)\n", prefix.c_str(), elemNs.c_str(),
+ String8(block->getElementName(&len)).c_str(),
block->getLineNumber());
int N = block->getAttributeCount();
depth++;
@@ -463,11 +463,11 @@
ns16 = block->getAttributeNamespace(i, &len);
String8 ns = build_namespace(namespaces, ns16);
String8 name(block->getAttributeName(i, &len));
- printf("%sA: ", prefix.string());
+ printf("%sA: ", prefix.c_str());
if (res) {
- printf("%s%s(0x%08x)", ns.string(), name.string(), res);
+ printf("%s%s(0x%08x)", ns.c_str(), name.c_str(), res);
} else {
- printf("%s%s", ns.string(), name.string());
+ printf("%s%s", ns.c_str(), name.c_str());
}
Res_value value;
block->getAttributeValue(i, &value);
@@ -480,14 +480,14 @@
} else if (value.dataType == Res_value::TYPE_STRING) {
printf("=\"%s\"",
ResTable::normalizeForOutput(String8(block->getAttributeStringValue(i,
- &len)).string()).string());
+ &len)).c_str()).c_str());
} else {
printf("=(type 0x%x)0x%x", (int)value.dataType, (int)value.data);
}
const char16_t* val = block->getAttributeStringValue(i, &len);
if (val != NULL) {
- printf(" (Raw: \"%s\")", ResTable::normalizeForOutput(String8(val).string()).
- string());
+ printf(" (Raw: \"%s\")", ResTable::normalizeForOutput(String8(val).c_str()).
+ c_str());
}
printf("\n");
}
@@ -509,8 +509,8 @@
}
ns.uri = String8(block->getNamespaceUri(&len));
namespaces.push(ns);
- printf("%sN: %s=%s\n", prefix.string(), ns.prefix.string(),
- ns.uri.string());
+ printf("%sN: %s=%s\n", prefix.c_str(), ns.prefix.c_str(),
+ ns.uri.c_str());
depth++;
} else if (code == ResXMLTree::END_NAMESPACE) {
if (--depth < 0) {
@@ -529,19 +529,19 @@
if (ns.prefix != pr) {
prefix = make_prefix(depth);
printf("%s*** BAD END NS PREFIX: found=%s, expected=%s\n",
- prefix.string(), pr.string(), ns.prefix.string());
+ prefix.c_str(), pr.c_str(), ns.prefix.c_str());
}
String8 uri = String8(block->getNamespaceUri(&len));
if (ns.uri != uri) {
prefix = make_prefix(depth);
printf("%s *** BAD END NS URI: found=%s, expected=%s\n",
- prefix.string(), uri.string(), ns.uri.string());
+ prefix.c_str(), uri.c_str(), ns.uri.c_str());
}
namespaces.pop();
} else if (code == ResXMLTree::TEXT) {
size_t len;
- printf("%sC: \"%s\"\n", prefix.string(),
- ResTable::normalizeForOutput(String8(block->getText(&len)).string()).string());
+ printf("%sC: \"%s\"\n", prefix.c_str(),
+ ResTable::normalizeForOutput(String8(block->getText(&len)).c_str()).c_str());
}
}
@@ -583,7 +583,7 @@
sp<XMLNode> XMLNode::parse(const sp<AaptFile>& file)
{
char buf[16384];
- int fd = open(file->getSourceFile().string(), O_RDONLY | O_BINARY);
+ int fd = open(file->getSourceFile().c_str(), O_RDONLY | O_BINARY);
if (fd < 0) {
SourcePos(file->getSourceFile(), -1).error("Unable to open file for read: %s",
strerror(errno));
@@ -875,9 +875,9 @@
}
if (kIsDebug) {
printf("Elem %s %s=\"%s\": set res id = 0x%08x\n",
- String8(getElementName()).string(),
- String8(mAttributes.itemAt(attrIdx).name).string(),
- String8(mAttributes.itemAt(attrIdx).string).string(),
+ String8(getElementName()).c_str(),
+ String8(mAttributes.itemAt(attrIdx).name).c_str(),
+ String8(mAttributes.itemAt(attrIdx).string).c_str(),
resId);
}
mAttributes.editItemAt(attrIdx).nameResId = resId;
@@ -915,7 +915,7 @@
void XMLNode::removeWhitespace(bool stripAll, const char** cDataTags)
{
- //printf("Removing whitespace in %s\n", String8(mElementName).string());
+ //printf("Removing whitespace in %s\n", String8(mElementName).c_str());
size_t N = mChildren.size();
if (cDataTags) {
String8 tag(mElementName);
@@ -931,13 +931,13 @@
sp<XMLNode> node = mChildren.itemAt(i);
if (node->getType() == TYPE_CDATA) {
// This is a CDATA node...
- const char16_t* p = node->mChars.string();
+ const char16_t* p = node->mChars.c_str();
while (*p != 0 && *p < 128 && isspace(*p)) {
p++;
}
//printf("Space ends at %d in \"%s\"\n",
- // (int)(p-node->mChars.string()),
- // String8(node->mChars).string());
+ // (int)(p-node->mChars.c_str()),
+ // String8(node->mChars).c_str());
if (*p == 0) {
if (stripAll) {
// Remove this node!
@@ -949,18 +949,18 @@
}
} else {
// Compact leading/trailing whitespace.
- const char16_t* e = node->mChars.string()+node->mChars.size()-1;
+ const char16_t* e = node->mChars.c_str()+node->mChars.size()-1;
while (e > p && *e < 128 && isspace(*e)) {
e--;
}
- if (p > node->mChars.string()) {
+ if (p > node->mChars.c_str()) {
p--;
}
- if (e < (node->mChars.string()+node->mChars.size()-1)) {
+ if (e < (node->mChars.c_str()+node->mChars.size()-1)) {
e++;
}
- if (p > node->mChars.string() ||
- e < (node->mChars.string()+node->mChars.size()-1)) {
+ if (p > node->mChars.c_str() ||
+ e < (node->mChars.c_str()+node->mChars.size()-1)) {
String16 tmp(p, e-p+1);
node->mChars = tmp;
}
@@ -986,14 +986,14 @@
table->setCurrentXmlPos(SourcePos(mFilename, getStartLineNumber()));
if (!assets->getIncludedResources()
.stringToValue(&e.value, &e.string,
- e.string.string(), e.string.size(), true, true,
+ e.string.c_str(), e.string.size(), true, true,
e.nameResId, NULL, &defPackage, table, &ac)) {
hasErrors = true;
}
if (kIsDebug) {
printf("Attr %s: type=0x%x, str=%s\n",
- String8(e.name).string(), e.value.dataType,
- String8(e.string).string());
+ String8(e.name).c_str(), e.value.dataType,
+ String8(e.string).c_str());
}
}
}
@@ -1023,30 +1023,30 @@
String16 pkg(getNamespaceResourcePackage(String16(assets->getPackage()), e.ns, &nsIsPublic));
if (kIsDebug) {
printf("Elem %s %s=\"%s\": namespace(%s) %s ===> %s\n",
- String8(getElementName()).string(),
- String8(e.name).string(),
- String8(e.string).string(),
- String8(e.ns).string(),
+ String8(getElementName()).c_str(),
+ String8(e.name).c_str(),
+ String8(e.string).c_str(),
+ String8(e.ns).c_str(),
(nsIsPublic) ? "public" : "private",
- String8(pkg).string());
+ String8(pkg).c_str());
}
if (pkg.size() <= 0) continue;
uint32_t res = table != NULL
? table->getResId(e.name, &attr, &pkg, &errorMsg, nsIsPublic)
: assets->getIncludedResources().
- identifierForName(e.name.string(), e.name.size(),
- attr.string(), attr.size(),
- pkg.string(), pkg.size());
+ identifierForName(e.name.c_str(), e.name.size(),
+ attr.c_str(), attr.size(),
+ pkg.c_str(), pkg.size());
if (res != 0) {
if (kIsDebug) {
printf("XML attribute name %s: resid=0x%08x\n",
- String8(e.name).string(), res);
+ String8(e.name).c_str(), res);
}
setAttributeResID(i, res);
} else {
SourcePos(mFilename, getStartLineNumber()).error(
"No resource identifier found for attribute '%s' in package '%s'\n",
- String8(e.name).string(), String8(pkg).string());
+ String8(e.name).c_str(), String8(pkg).c_str());
hasErrors = true;
}
}
@@ -1137,7 +1137,7 @@
if (kPrintStringMetrics) {
fprintf(stderr, "**** total xml size: %zu / %zu%% strings (in %s)\n",
dest->getSize(), (stringPool->getSize()*100)/dest->getSize(),
- dest->getPath().string());
+ dest->getPath().c_str());
}
return NO_ERROR;
@@ -1155,8 +1155,8 @@
if (elemNs.size() > 0) {
elemNs.append(":");
}
- printf("%s E: %s%s", prefix.string(),
- elemNs.string(), String8(getElementName()).string());
+ printf("%s E: %s%s", prefix.c_str(),
+ elemNs.c_str(), String8(getElementName()).c_str());
int N = mAttributes.size();
for (i=0; i<N; i++) {
ssize_t idx = mAttributeOrder.valueAt(i);
@@ -1171,21 +1171,21 @@
attrNs.append(":");
}
if (attr.nameResId) {
- printf("%s%s(0x%08x)", attrNs.string(),
- String8(attr.name).string(), attr.nameResId);
+ printf("%s%s(0x%08x)", attrNs.c_str(),
+ String8(attr.name).c_str(), attr.nameResId);
} else {
- printf("%s%s", attrNs.string(), String8(attr.name).string());
+ printf("%s%s", attrNs.c_str(), String8(attr.name).c_str());
}
- printf("=%s", String8(attr.string).string());
+ printf("=%s", String8(attr.string).c_str());
}
printf("\n");
} else if (getType() == TYPE_NAMESPACE) {
- printf("%s N: %s=%s\n", prefix.string(),
+ printf("%s N: %s=%s\n", prefix.c_str(),
getNamespacePrefix().size() > 0
- ? String8(getNamespacePrefix()).string() : "<DEF>",
- String8(getNamespaceUri()).string());
+ ? String8(getNamespacePrefix()).c_str() : "<DEF>",
+ String8(getNamespaceUri()).c_str());
} else {
- printf("%s C: \"%s\"\n", prefix.string(), String8(getCData()).string());
+ printf("%s C: \"%s\"\n", prefix.c_str(), String8(getCData()).c_str());
}
int N = mChildren.size();
for (i=0; i<N; i++) {
@@ -1258,7 +1258,7 @@
XMLNode::characterData(void *userData, const XML_Char *s, int len)
{
if (kIsDebugParse) {
- printf("CDATA: \"%s\"\n", String8(s, len).string());
+ printf("CDATA: \"%s\"\n", String8(s, len).c_str());
}
ParseState* st = (ParseState*)userData;
sp<XMLNode> node = NULL;
@@ -1423,7 +1423,7 @@
idx = outPool->add(attr.name);
if (kIsDebug) {
printf("Adding attr %s (resid 0x%08x) to pool: idx=%zd\n",
- String8(attr.name).string(), id, idx);
+ String8(attr.name).c_str(), id, idx);
}
if (id != 0) {
while ((ssize_t)outResIds->size() <= idx) {
@@ -1434,7 +1434,7 @@
}
attr.namePoolIdx = idx;
if (kIsDebug) {
- printf("String %s offset=0x%08zd\n", String8(attr.name).string(), idx);
+ printf("String %s offset=0x%08zd\n", String8(attr.name).c_str(), idx);
}
}
}
@@ -1488,7 +1488,7 @@
node.comment.index = htodl(
mComment.size() > 0 ? strings.offsetForString(mComment) : -1);
//if (mComment.size() > 0) {
- // printf("Flattening comment: %s\n", String8(mComment).string());
+ // printf("Flattening comment: %s\n", String8(mComment).c_str());
//}
} else {
node.comment.index = htodl((uint32_t)-1);
diff --git a/tools/aapt/pseudolocalize.cpp b/tools/aapt/pseudolocalize.cpp
index 4e8dcb1..fc2ed98 100644
--- a/tools/aapt/pseudolocalize.cpp
+++ b/tools/aapt/pseudolocalize.cpp
@@ -42,7 +42,7 @@
size_t depth = mLastDepth;
size_t lastpos, pos;
const size_t length= text.size();
- const char16_t* str = text.string();
+ const char16_t* str = text.c_str();
bool escaped = false;
for (lastpos = pos = 0; pos < length; pos++) {
char16_t c = str[pos];
@@ -181,7 +181,7 @@
static String16 pseudo_generate_expansion(const unsigned int length) {
String16 result = k_expansion_string;
- const char16_t* s = result.string();
+ const char16_t* s = result.c_str();
if (result.size() < length) {
result += String16(" ");
result += pseudo_generate_expansion(length - result.size());
@@ -237,7 +237,7 @@
*/
String16 PseudoMethodAccent::text(const String16& source)
{
- const char16_t* s = source.string();
+ const char16_t* s = source.c_str();
String16 result;
const size_t I = source.size();
bool lastspace = true;
@@ -357,7 +357,7 @@
String16 PseudoMethodBidi::text(const String16& source)
{
- const char16_t* s = source.string();
+ const char16_t* s = source.c_str();
String16 result;
bool lastspace = true;
bool space = true;
diff --git a/tools/aapt2/Debug.cpp b/tools/aapt2/Debug.cpp
index df87889..9cfb85d 100644
--- a/tools/aapt2/Debug.cpp
+++ b/tools/aapt2/Debug.cpp
@@ -447,7 +447,7 @@
const size_t NS = pool->size();
for (size_t s=0; s<NS; s++) {
auto str = pool->string8ObjectAt(s);
- printer->Print(StringPrintf("String #%zd : %s\n", s, str.has_value() ? str->string() : ""));
+ printer->Print(StringPrintf("String #%zd : %s\n", s, str.has_value() ? str->c_str() : ""));
}
}
diff --git a/tools/aapt2/cmd/Util.cpp b/tools/aapt2/cmd/Util.cpp
index 1671e1e..a92f24b 100644
--- a/tools/aapt2/cmd/Util.cpp
+++ b/tools/aapt2/cmd/Util.cpp
@@ -215,7 +215,7 @@
}
std::vector<std::string> sanitized_config_names;
for (const auto &config : constraints.configs) {
- sanitized_config_names.push_back(MakePackageSafeName(config.toString().string()));
+ sanitized_config_names.push_back(MakePackageSafeName(config.toString().c_str()));
}
split_name << "config." << util::Joiner(sanitized_config_names, "_");
diff --git a/tools/aapt2/format/binary/BinaryResourceParser.cpp b/tools/aapt2/format/binary/BinaryResourceParser.cpp
index 75dcba5..2e20e81 100644
--- a/tools/aapt2/format/binary/BinaryResourceParser.cpp
+++ b/tools/aapt2/format/binary/BinaryResourceParser.cpp
@@ -453,7 +453,7 @@
const size_t count = entries.size();
for (size_t i = 0; i < count; i++) {
table_->included_packages_[entries.valueAt(i)] =
- android::util::Utf16ToUtf8(StringPiece16(entries.keyAt(i).string()));
+ android::util::Utf16ToUtf8(StringPiece16(entries.keyAt(i).c_str()));
}
return true;
}
diff --git a/tools/split-select/Grouper_test.cpp b/tools/split-select/Grouper_test.cpp
index 7294a86..a8b78cd 100644
--- a/tools/split-select/Grouper_test.cpp
+++ b/tools/split-select/Grouper_test.cpp
@@ -179,7 +179,7 @@
errorMessage.append("\n");
}
}
- ADD_FAILURE() << errorMessage.string();
+ ADD_FAILURE() << errorMessage.c_str();
}
void GrouperTest::addSplit(Vector<SplitDescription>& splits, const char* str) {
diff --git a/tools/split-select/Main.cpp b/tools/split-select/Main.cpp
index e6966db..1e75117 100644
--- a/tools/split-select/Main.cpp
+++ b/tools/split-select/Main.cpp
@@ -99,8 +99,7 @@
}
masterRule = Rule::simplify(masterRule);
fprintf(stdout, " {\n \"path\": \"%s\",\n \"rules\": %s\n }",
- splits.keyAt(i).string(),
- masterRule->toJson(2).string());
+ splits.keyAt(i).c_str(), masterRule->toJson(2).c_str());
}
fprintf(stdout, "\n]\n");
}
@@ -158,25 +157,23 @@
const char16_t* name = xml.getElementName(&len);
String16 name16(name, len);
if (name16 == kManifestTag) {
- ssize_t idx = xml.indexOfAttribute(
- kAndroidNamespace.string(), kAndroidNamespace.size(),
- kVersionCodeAttr.string(), kVersionCodeAttr.size());
+ ssize_t idx = xml.indexOfAttribute(kAndroidNamespace.c_str(), kAndroidNamespace.size(),
+ kVersionCodeAttr.c_str(), kVersionCodeAttr.size());
if (idx >= 0) {
outInfo.versionCode = xml.getAttributeData(idx);
}
} else if (name16 == kApplicationTag) {
- ssize_t idx = xml.indexOfAttribute(
- kAndroidNamespace.string(), kAndroidNamespace.size(),
- kMultiArchAttr.string(), kMultiArchAttr.size());
+ ssize_t idx = xml.indexOfAttribute(kAndroidNamespace.c_str(), kAndroidNamespace.size(),
+ kMultiArchAttr.c_str(), kMultiArchAttr.size());
if (idx >= 0) {
outInfo.multiArch = xml.getAttributeData(idx) != 0;
}
} else if (name16 == kUsesSdkTag) {
- ssize_t idx = xml.indexOfAttribute(
- kAndroidNamespace.string(), kAndroidNamespace.size(),
- kMinSdkVersionAttr.string(), kMinSdkVersionAttr.size());
+ ssize_t idx =
+ xml.indexOfAttribute(kAndroidNamespace.c_str(), kAndroidNamespace.size(),
+ kMinSdkVersionAttr.c_str(), kMinSdkVersionAttr.size());
if (idx >= 0) {
uint16_t type = xml.getAttributeDataType(idx);
if (type >= Res_value::TYPE_FIRST_INT && type <= Res_value::TYPE_LAST_INT) {
@@ -187,10 +184,10 @@
fprintf(stderr, "warning: failed to retrieve android:minSdkVersion.\n");
} else {
char *endPtr;
- int minSdk = strtol(minSdk8->string(), &endPtr, 10);
- if (endPtr != minSdk8->string() + minSdk8->size()) {
+ int minSdk = strtol(minSdk8->c_str(), &endPtr, 10);
+ if (endPtr != minSdk8->c_str() + minSdk8->size()) {
fprintf(stderr, "warning: failed to parse android:minSdkVersion '%s'\n",
- minSdk8->string());
+ minSdk8->c_str());
} else {
outInfo.minSdkVersion = minSdk;
}
@@ -232,7 +229,7 @@
splits.add();
Vector<String8> parts = AaptUtil::splitAndLowerCase(dir->getFileName(i), '-');
if (parseAbi(parts, 0, &splits.editTop()) < 0) {
- fprintf(stderr, "Malformed library %s\n", dir->getFileName(i).string());
+ fprintf(stderr, "Malformed library %s\n", dir->getFileName(i).c_str());
splits.pop();
}
}
@@ -291,7 +288,7 @@
help();
return 0;
} else {
- fprintf(stderr, "error: unknown argument '%s'.\n", arg.string());
+ fprintf(stderr, "error: unknown argument '%s'.\n", arg.c_str());
usage();
return 1;
}
@@ -313,15 +310,14 @@
// Find out some details about the base APK.
AppInfo baseAppInfo;
if (!getAppInfo(baseApkPath, baseAppInfo)) {
- fprintf(stderr, "error: unable to read base APK: '%s'.\n", baseApkPath.string());
+ fprintf(stderr, "error: unable to read base APK: '%s'.\n", baseApkPath.c_str());
return 1;
}
SplitDescription targetSplit;
if (!generateFlag) {
if (!SplitDescription::parse(targetConfigStr, &targetSplit)) {
- fprintf(stderr, "error: invalid --target config: '%s'.\n",
- targetConfigStr.string());
+ fprintf(stderr, "error: invalid --target config: '%s'.\n", targetConfigStr.c_str());
usage();
return 1;
}
@@ -341,7 +337,7 @@
Vector<SplitDescription> splits = extractSplitDescriptionsFromApk(splitApkPaths[i]);
if (splits.isEmpty()) {
fprintf(stderr, "error: invalid --split path: '%s'. No splits found.\n",
- splitApkPaths[i].string());
+ splitApkPaths[i].c_str());
usage();
return 1;
}
@@ -364,7 +360,7 @@
const size_t matchingSplitApkPathCount = matchingSplitPaths.size();
for (size_t i = 0; i < matchingSplitApkPathCount; i++) {
if (matchingSplitPaths[i] != baseApkPath) {
- fprintf(stdout, "%s\n", matchingSplitPaths[i].string());
+ fprintf(stdout, "%s\n", matchingSplitPaths[i].c_str());
}
}
} else {
diff --git a/tools/split-select/Rule_test.cpp b/tools/split-select/Rule_test.cpp
index c6cff0d..c78533f 100644
--- a/tools/split-select/Rule_test.cpp
+++ b/tools/split-select/Rule_test.cpp
@@ -68,7 +68,7 @@
expected.erase(std::remove_if(expected.begin(), expected.end(), ::isspace), expected.end());
// Result
- std::string result(rule.toJson().string());
+ std::string result(rule.toJson().c_str());
result.erase(std::remove_if(result.begin(), result.end(), ::isspace), result.end());
ASSERT_EQ(expected, result);
diff --git a/tools/split-select/SplitDescription.cpp b/tools/split-select/SplitDescription.cpp
index 99bc23d..4e2b48e 100644
--- a/tools/split-select/SplitDescription.cpp
+++ b/tools/split-select/SplitDescription.cpp
@@ -134,8 +134,8 @@
String8 configStr;
String8 extensionStr;
if (index >= 0) {
- configStr.setTo(str.string(), index);
- extensionStr.setTo(str.string() + index + 1);
+ configStr.setTo(str.c_str(), index);
+ extensionStr.setTo(str.c_str() + index + 1);
} else {
configStr.setTo(str);
}
diff --git a/tools/split-select/TestRules.cpp b/tools/split-select/TestRules.cpp
index 86ccd6a..ca3c56f 100644
--- a/tools/split-select/TestRules.cpp
+++ b/tools/split-select/TestRules.cpp
@@ -78,9 +78,8 @@
const String8 actualStr(actual != NULL ? actual->toJson() : String8());
if (expectedStr != actualStr) {
- return ::testing::AssertionFailure()
- << "Expected: " << expectedStr.string() << "\n"
- << " Actual: " << actualStr.string();
+ return ::testing::AssertionFailure() << "Expected: " << expectedStr.c_str() << "\n"
+ << " Actual: " << actualStr.c_str();
}
return ::testing::AssertionSuccess();
}