Merge "Use String.equals when comparing conflicting providers"
diff --git a/Android.bp b/Android.bp
index 1c59e2b..415eff3 100644
--- a/Android.bp
+++ b/Android.bp
@@ -368,6 +368,7 @@
"core/java/com/android/internal/app/IAppOpsService.aidl",
"core/java/com/android/internal/app/IBatteryStats.aidl",
"core/java/com/android/internal/app/ISoundTriggerService.aidl",
+ "core/java/com/android/internal/app/IVoiceActionCheckCallback.aidl",
"core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl",
"core/java/com/android/internal/app/IVoiceInteractionSessionListener.aidl",
"core/java/com/android/internal/app/IVoiceInteractionSessionShowCallback.aidl",
diff --git a/api/current.txt b/api/current.txt
index 75787a7..6042b2f 100755
--- a/api/current.txt
+++ b/api/current.txt
@@ -14015,12 +14015,15 @@
method public android.graphics.Paint.Style getStyle();
method public android.graphics.Paint.Align getTextAlign();
method public void getTextBounds(java.lang.String, int, int, android.graphics.Rect);
+ method public void getTextBounds(java.lang.CharSequence, int, int, android.graphics.Rect);
method public void getTextBounds(char[], int, int, android.graphics.Rect);
method public java.util.Locale getTextLocale();
method public android.os.LocaleList getTextLocales();
method public void getTextPath(char[], int, int, float, float, android.graphics.Path);
method public void getTextPath(java.lang.String, int, int, float, float, android.graphics.Path);
method public float getTextRunAdvances(char[], int, int, int, int, boolean, float[], int);
+ method public int getTextRunCursor(char[], int, int, boolean, int, int);
+ method public int getTextRunCursor(java.lang.CharSequence, int, int, boolean, int, int);
method public float getTextScaleX();
method public float getTextSize();
method public float getTextSkewX();
@@ -14087,6 +14090,11 @@
method public void setWordSpacing(float);
method public android.graphics.Xfermode setXfermode(android.graphics.Xfermode);
field public static final int ANTI_ALIAS_FLAG = 1; // 0x1
+ field public static final int CURSOR_AFTER = 0; // 0x0
+ field public static final int CURSOR_AT = 4; // 0x4
+ field public static final int CURSOR_AT_OR_AFTER = 1; // 0x1
+ field public static final int CURSOR_AT_OR_BEFORE = 3; // 0x3
+ field public static final int CURSOR_BEFORE = 2; // 0x2
field public static final int DEV_KERN_TEXT_FLAG = 256; // 0x100
field public static final int DITHER_FLAG = 4; // 0x4
field public static final int EMBEDDED_BITMAP_TEXT_FLAG = 1024; // 0x400
@@ -39920,6 +39928,7 @@
method public int getDisabledShowContext();
method public static boolean isActiveService(android.content.Context, android.content.ComponentName);
method public android.os.IBinder onBind(android.content.Intent);
+ method public java.util.Set<java.lang.String> onGetSupportedVoiceActions(java.util.Set<java.lang.String>);
method public void onLaunchVoiceAssistFromKeyguard();
method public void onReady();
method public void onShutdown();
diff --git a/api/system-current.txt b/api/system-current.txt
index 47b4cfc..8f7606a 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -5405,7 +5405,6 @@
}
public class TelephonyManager {
- method public deprecated void answerRingingCall();
method public deprecated void call(java.lang.String, java.lang.String);
method public int checkCarrierPrivilegesForPackage(java.lang.String);
method public int checkCarrierPrivilegesForPackageAnyPhone(java.lang.String);
@@ -5413,7 +5412,6 @@
method public boolean disableDataConnectivity();
method public boolean enableDataConnectivity();
method public void enableVideoCalling(boolean);
- method public deprecated boolean endCall();
method public java.util.List<android.service.carrier.CarrierIdentifier> getAllowedCarriers(int);
method public java.util.List<java.lang.String> getCarrierPackageNamesForIntent(android.content.Intent);
method public java.util.List<java.lang.String> getCarrierPackageNamesForIntentAndPhone(android.content.Intent, int);
diff --git a/api/system-removed.txt b/api/system-removed.txt
index b88c760..9012c33 100644
--- a/api/system-removed.txt
+++ b/api/system-removed.txt
@@ -143,3 +143,12 @@
}
+package android.telephony {
+
+ public class TelephonyManager {
+ method public deprecated void answerRingingCall();
+ method public deprecated boolean endCall();
+ }
+
+}
+
diff --git a/cmds/content/src/com/android/commands/content/Content.java b/cmds/content/src/com/android/commands/content/Content.java
index 36e51b9..12fb4a3 100644
--- a/cmds/content/src/com/android/commands/content/Content.java
+++ b/cmds/content/src/com/android/commands/content/Content.java
@@ -470,7 +470,8 @@
onExecute(provider);
} finally {
if (provider != null) {
- activityManager.removeContentProviderExternal(providerName, token);
+ activityManager.removeContentProviderExternalAsUser(
+ providerName, token, mUserId);
}
}
} catch (Exception e) {
diff --git a/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/ShellUiAutomatorBridge.java b/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/ShellUiAutomatorBridge.java
index 950a258..455e4bb 100644
--- a/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/ShellUiAutomatorBridge.java
+++ b/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/ShellUiAutomatorBridge.java
@@ -84,7 +84,8 @@
cursor.close();
}
if (provider != null) {
- activityManager.removeContentProviderExternal(providerName, token);
+ activityManager.removeContentProviderExternalAsUser(providerName, token,
+ UserHandle.USER_SYSTEM);
}
}
} catch (RemoteException e) {
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 16360b3..2490cae 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -263,7 +263,9 @@
void killAllBackgroundProcesses();
ContentProviderHolder getContentProviderExternal(in String name, int userId,
in IBinder token, String tag);
+ /** @deprecated - Use {@link #removeContentProviderExternalAsUser} which takes a user ID. */
void removeContentProviderExternal(in String name, in IBinder token);
+ void removeContentProviderExternalAsUser(in String name, in IBinder token, int userId);
// Get memory information about the calling process.
void getMyMemoryState(out ActivityManager.RunningAppProcessInfo outInfo);
boolean killProcessesBelowForeground(in String reason);
diff --git a/core/java/android/content/ClipboardManager.java b/core/java/android/content/ClipboardManager.java
index 3fe17840..8760efe 100644
--- a/core/java/android/content/ClipboardManager.java
+++ b/core/java/android/content/ClipboardManager.java
@@ -95,9 +95,6 @@
* Sets the current primary clip on the clipboard. This is the clip that
* is involved in normal cut and paste operations.
*
- * <em>If the application is not the default IME or does not have input focus this will have
- * no effect.</em>
- *
* @param clip The clipped data item to set.
* @see #getPrimaryClip()
* @see #clearPrimaryClip()
@@ -115,9 +112,6 @@
/**
* Clears any current primary clip on the clipboard.
*
- * <em>If the application is not the default IME or does not have input focus this will have
- * no effect.</em>
- *
* @see #setPrimaryClip(ClipData)
*/
public void clearPrimaryClip() {
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 2ae3ae6..d88f6e3 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3167,11 +3167,11 @@
*
* <p>Note: Instant apps, for which {@link PackageManager#isInstantApp()} returns true,
* don't have access to the following system services: {@link #DEVICE_POLICY_SERVICE},
- * {@link #FINGERPRINT_SERVICE}, {@link #SHORTCUT_SERVICE}, {@link #USB_SERVICE},
- * {@link #WALLPAPER_SERVICE}, {@link #WIFI_P2P_SERVICE}, {@link #WIFI_SERVICE},
- * {@link #WIFI_AWARE_SERVICE}. For these services this method will return <code>null</code>.
- * Generally, if you are running as an instant app you should always check whether the result
- * of this method is null.
+ * {@link #FINGERPRINT_SERVICE}, {@link #KEYGUARD_SERVICE}, {@link #SHORTCUT_SERVICE},
+ * {@link #USB_SERVICE}, {@link #WALLPAPER_SERVICE}, {@link #WIFI_P2P_SERVICE},
+ * {@link #WIFI_SERVICE}, {@link #WIFI_AWARE_SERVICE}. For these services this method will
+ * return <code>null</code>. Generally, if you are running as an instant app you should always
+ * check whether the result of this method is null.
*
* @param name The name of the desired service.
*
@@ -3258,11 +3258,11 @@
*
* <p>Note: Instant apps, for which {@link PackageManager#isInstantApp()} returns true,
* don't have access to the following system services: {@link #DEVICE_POLICY_SERVICE},
- * {@link #FINGERPRINT_SERVICE}, {@link #SHORTCUT_SERVICE}, {@link #USB_SERVICE},
- * {@link #WALLPAPER_SERVICE}, {@link #WIFI_P2P_SERVICE}, {@link #WIFI_SERVICE},
- * {@link #WIFI_AWARE_SERVICE}. For these services this method will return <code>null</code>.
- * Generally, if you are running as an instant app you should always check whether the result
- * of this method is null.
+ * {@link #FINGERPRINT_SERVICE}, {@link #KEYGUARD_SERVICE}, {@link #SHORTCUT_SERVICE},
+ * {@link #USB_SERVICE}, {@link #WALLPAPER_SERVICE}, {@link #WIFI_P2P_SERVICE},
+ * {@link #WIFI_SERVICE}, {@link #WIFI_AWARE_SERVICE}. For these services this method will
+ * return <code>null</code>. Generally, if you are running as an instant app you should always
+ * check whether the result of this method is null.
*
* @param serviceClass The class of the desired service.
* @return The service or null if the class is not a supported system service.
diff --git a/core/java/android/content/pm/PackageItemInfo.java b/core/java/android/content/pm/PackageItemInfo.java
index 963f881..19af609 100644
--- a/core/java/android/content/pm/PackageItemInfo.java
+++ b/core/java/android/content/pm/PackageItemInfo.java
@@ -102,7 +102,13 @@
private static volatile boolean sForceSafeLabels = false;
- /** {@hide} */
+ /**
+ * Always use {@link #loadSafeLabel safe labels} when calling {@link #loadLabel}.
+ *
+ * @param forceSafeLabels {@code true} to enforce safe labels
+ *
+ * @hide
+ */
@SystemApi
public static void setForceSafeLabels(boolean forceSafeLabels) {
sForceSafeLabels = forceSafeLabels;
diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java
index 20e1454e..b5b4432 100644
--- a/core/java/android/content/pm/PackageManagerInternal.java
+++ b/core/java/android/content/pm/PackageManagerInternal.java
@@ -136,24 +136,6 @@
public abstract void setVoiceInteractionPackagesProvider(PackagesProvider provider);
/**
- * Sets the SMS packages provider.
- * @param provider The packages provider.
- */
- public abstract void setSmsAppPackagesProvider(PackagesProvider provider);
-
- /**
- * Sets the dialer packages provider.
- * @param provider The packages provider.
- */
- public abstract void setDialerAppPackagesProvider(PackagesProvider provider);
-
- /**
- * Sets the sim call manager packages provider.
- * @param provider The packages provider.
- */
- public abstract void setSimCallManagerPackagesProvider(PackagesProvider provider);
-
- /**
* Sets the Use Open Wifi packages provider.
* @param provider The packages provider.
*/
@@ -166,26 +148,28 @@
public abstract void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider);
/**
- * Requests granting of the default permissions to the current default SMS app.
- * @param packageName The default SMS package name.
- * @param userId The user for which to grant the permissions.
+ * Called when the package for the default dialer changed
+ *
+ * @param packageName the new dialer package
+ * @param userId user for which the change was made
*/
- public abstract void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId);
+ public void onDefaultDialerAppChanged(String packageName, int userId) {}
/**
- * Requests granting of the default permissions to the current default dialer app.
- * @param packageName The default dialer package name.
- * @param userId The user for which to grant the permissions.
+ * Called when the package for the default SMS handler changed
+ *
+ * @param packageName the new sms package
+ * @param userId user for which the change was made
*/
- public abstract void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId);
+ public void onDefaultSmsAppChanged(String packageName, int userId) {}
/**
- * Requests granting of the default permissions to the current default sim call manager.
- * @param packageName The default sim call manager package name.
- * @param userId The user for which to grant the permissions.
+ * Called when the package for the default sim call manager changed
+ *
+ * @param packageName the new sms package
+ * @param userId user for which the change was made
*/
- public abstract void grantDefaultPermissionsToDefaultSimCallManager(String packageName,
- int userId);
+ public void onDefaultSimCallManagerAppChanged(String packageName, int userId) {}
/**
* Requests granting of the default permissions to the current default Use Open Wifi app.
@@ -446,8 +430,8 @@
*
* @param packageName The package to check for
* @param uid the uid in which the package is running
- * @return {@link USER_TRUSTED} if the user has trusted the package, {@link USER_BLOCKED}
- * if user has blocked requests from the package, {@link USER_DEFAULT} if the user response
+ * @return {@link #USER_TRUSTED} if the user has trusted the package, {@link #USER_BLOCKED}
+ * if user has blocked requests from the package, {@link #USER_DEFAULT} if the user response
* is not yet available
*/
int getPackageTrustedToInstallApps(String packageName, int uid);
@@ -561,7 +545,7 @@
/**
* Returns a list without a change observer.
*
- * {@see #getPackageList(PackageListObserver)}
+ * @see #getPackageList(PackageListObserver)
*/
public @NonNull PackageList getPackageList() {
return getPackageList(null);
@@ -590,7 +574,16 @@
/**
* Returns a package object for the disabled system package name.
*/
- public abstract @Nullable PackageParser.Package getDisabledPackage(@NonNull String packageName);
+ public abstract @Nullable PackageParser.Package getDisabledSystemPackage(
+ @NonNull String packageName);
+
+ /**
+ * Returns the package name for the disabled system package.
+ *
+ * This is equivalent to
+ * {@link #getDisabledSystemPackage(String)}.{@link PackageParser.Package#packageName}
+ */
+ public abstract @Nullable String getDisabledSystemPackageName(@NonNull String packageName);
/**
* Returns whether or not the component is the resolver activity.
@@ -619,7 +612,7 @@
* Access may be limited based upon whether the calling or target applications
* are instant applications.
*
- * @see #canAccessInstantApps(int)
+ * @see #canAccessInstantApps
*/
public abstract boolean filterAppAccess(
@Nullable PackageParser.Package pkg, int callingUid, int userId);
@@ -635,6 +628,9 @@
public abstract void updatePermissionFlagsTEMP(@NonNull String permName,
@NonNull String packageName, int flagMask, int flagValues, int userId);
+ /** Returns whether the given package was signed by the platform */
+ public abstract boolean isPlatformSigned(String pkg);
+
/**
* Returns true if it's still safe to restore data backed up from this app's version
* that was signed with restoringFromSigHash.
diff --git a/core/java/android/permissionpresenterservice/RuntimePermissionPresenterService.java b/core/java/android/permissionpresenterservice/RuntimePermissionPresenterService.java
index f2da21e..18aea03 100644
--- a/core/java/android/permissionpresenterservice/RuntimePermissionPresenterService.java
+++ b/core/java/android/permissionpresenterservice/RuntimePermissionPresenterService.java
@@ -16,6 +16,7 @@
package android.permissionpresenterservice;
+import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.app.Service;
import android.content.Context;
@@ -73,12 +74,13 @@
public abstract List<RuntimePermissionPresentationInfo> onGetAppPermissions(String packageName);
/**
- * Revoke the permission {@code permissionName} for app {@code packageName}
+ * Revokes the permission {@code permissionName} for app {@code packageName}
*
* @param packageName The package for which to revoke
* @param permissionName The permission to revoke
*/
- public abstract void onRevokeRuntimePermission(String packageName, String permissionName);
+ public abstract void onRevokeRuntimePermission(@NonNull String packageName,
+ @NonNull String permissionName);
@Override
public final IBinder onBind(Intent intent) {
diff --git a/core/java/android/service/autofill/FillCallback.java b/core/java/android/service/autofill/FillCallback.java
index 663bdcb..3893f2a 100644
--- a/core/java/android/service/autofill/FillCallback.java
+++ b/core/java/android/service/autofill/FillCallback.java
@@ -43,13 +43,20 @@
}
/**
- * Notifies the Android System that an
- * {@link AutofillService#onFillRequest(FillRequest, android.os.CancellationSignal,
- * FillCallback)} was successfully fulfilled by the service.
+ * Notifies the Android System that a fill request
+ * ({@link AutofillService#onFillRequest(FillRequest, android.os.CancellationSignal,
+ * FillCallback)}) was successfully fulfilled by the service.
*
- * @param response autofill information for that activity, or {@code null} when the activity
- * cannot be autofilled (for example, if it only contains read-only fields). See
- * {@link FillResponse} for examples.
+ * <p>This method should always be called, even if the service doesn't have the heuristics to
+ * fulfill the request (in which case it should be called with {@code null}).
+ *
+ * <p>See the main {@link AutofillService} documentation for more details and examples.
+ *
+ * @param response autofill information for that activity, or {@code null} when the service
+ * cannot autofill the activity.
+ *
+ * @throws IllegalStateException if this method or {@link #onFailure(CharSequence)} was already
+ * called.
*/
public void onSuccess(@Nullable FillResponse response) {
assertNotCalled();
@@ -67,11 +74,25 @@
}
/**
- * Notifies the Android System that an
+ * Notifies the Android System that a fill request (
* {@link AutofillService#onFillRequest(FillRequest, android.os.CancellationSignal,
- * FillCallback)} could not be fulfilled by the service.
+ * FillCallback)}) could not be fulfilled by the service (for example, because the user data was
+ * not available yet), so the request could be retried later.
*
- * @param message error message to be displayed to the user.
+ * <p><b>Note: </b>this method should not be used when the service didn't have the heursitics to
+ * fulfill the request; in this case, the service should call {@link #onSuccess(FillResponse)
+ * onSuccess(null)} instead.
+ *
+ * <p><b>Note: </b>on Android versions up to {@link android.os.Build.VERSION_CODES#P}, this
+ * method is not working as intended, and the service should call
+ * {@link #onSuccess(FillResponse) onSuccess(null)} instead.
+ *
+ * @param message error message to be displayed to the user. <b>Note: </b> this message is
+ * displayed on {@code logcat} logs and should not contain PII (Personally Identifiable
+ * Information, such as username or email address).
+ *
+ * @throws IllegalStateException if this method or {@link #onSuccess(FillResponse)} was already
+ * called.
*/
public void onFailure(@Nullable CharSequence message) {
Log.w(TAG, "onFailure(): " + (message == null ? null : message.length() + "_chars"));
diff --git a/core/java/android/service/autofill/SaveCallback.java b/core/java/android/service/autofill/SaveCallback.java
index e252e96..0625095 100644
--- a/core/java/android/service/autofill/SaveCallback.java
+++ b/core/java/android/service/autofill/SaveCallback.java
@@ -45,6 +45,9 @@
* Notifies the Android System that an
* {@link AutofillService#onSaveRequest(SaveRequest, SaveCallback)} was successfully handled
* by the service.
+ *
+ * @throws IllegalStateException if this method, {@link #onSuccess(IntentSender)}, or
+ * {@link #onFailure(CharSequence)} was already called.
*/
public void onSuccess() {
onSuccessInternal(null);
@@ -62,6 +65,9 @@
*
* @param intentSender intent that will be launched from the context of activity being
* autofilled.
+ *
+ * @throws IllegalStateException if this method, {@link #onSuccess()},
+ * or {@link #onFailure(CharSequence)} was already called.
*/
public void onSuccess(@NonNull IntentSender intentSender) {
onSuccessInternal(Preconditions.checkNotNull(intentSender));
@@ -90,7 +96,12 @@
* you prefer to show your own message, call {@link #onSuccess()} or
* {@link #onSuccess(IntentSender)} instead.
*
- * @param message error message to be displayed to the user.
+ * @param message error message to be displayed to the user. <b>Note: </b> this message is
+ * displayed on {@code logcat} logs and should not contain PII (Personally Identifiable
+ * Information, such as username or email address).
+ *
+ * @throws IllegalStateException if this method, {@link #onSuccess()},
+ * or {@link #onSuccess(IntentSender)} was already called.
*/
public void onFailure(CharSequence message) {
Log.w(TAG, "onFailure(): " + (message == null ? null : message.length() + "_chars"));
diff --git a/core/java/android/service/voice/IVoiceInteractionService.aidl b/core/java/android/service/voice/IVoiceInteractionService.aidl
index e3d68a6..24819a6 100644
--- a/core/java/android/service/voice/IVoiceInteractionService.aidl
+++ b/core/java/android/service/voice/IVoiceInteractionService.aidl
@@ -16,6 +16,8 @@
package android.service.voice;
+import com.android.internal.app.IVoiceActionCheckCallback;
+
/**
* @hide
*/
@@ -24,4 +26,6 @@
void soundModelsChanged();
void shutdown();
void launchVoiceAssistFromKeyguard();
+ void getActiveServiceSupportedActions(in List<String> voiceActions,
+ in IVoiceActionCheckCallback callback);
}
diff --git a/core/java/android/service/voice/VoiceInteractionService.java b/core/java/android/service/voice/VoiceInteractionService.java
index 0bbc07e..e105fdf 100644
--- a/core/java/android/service/voice/VoiceInteractionService.java
+++ b/core/java/android/service/voice/VoiceInteractionService.java
@@ -16,6 +16,8 @@
package android.service.voice;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SdkConstant;
import android.annotation.UnsupportedAppUsage;
import android.app.Service;
@@ -26,17 +28,22 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
-import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.provider.Settings;
+import android.util.ArraySet;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.app.IVoiceActionCheckCallback;
import com.android.internal.app.IVoiceInteractionManagerService;
+import com.android.internal.util.function.pooled.PooledLambda;
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Locale;
+import java.util.Set;
/**
* Top-level service of the current global voice interactor, which is providing
@@ -71,23 +78,43 @@
public static final String SERVICE_META_DATA = "android.voice_interaction";
IVoiceInteractionService mInterface = new IVoiceInteractionService.Stub() {
- @Override public void ready() {
- mHandler.sendEmptyMessage(MSG_READY);
- }
- @Override public void shutdown() {
- mHandler.sendEmptyMessage(MSG_SHUTDOWN);
- }
- @Override public void soundModelsChanged() {
- mHandler.sendEmptyMessage(MSG_SOUND_MODELS_CHANGED);
- }
@Override
- public void launchVoiceAssistFromKeyguard() throws RemoteException {
- mHandler.sendEmptyMessage(MSG_LAUNCH_VOICE_ASSIST_FROM_KEYGUARD);
+ public void ready() {
+ Handler.getMain().executeOrSendMessage(PooledLambda.obtainMessage(
+ VoiceInteractionService::onReady, VoiceInteractionService.this));
+ }
+
+ @Override
+ public void shutdown() {
+ Handler.getMain().executeOrSendMessage(PooledLambda.obtainMessage(
+ VoiceInteractionService::onShutdownInternal, VoiceInteractionService.this));
+ }
+
+ @Override
+ public void soundModelsChanged() {
+ Handler.getMain().executeOrSendMessage(PooledLambda.obtainMessage(
+ VoiceInteractionService::onSoundModelsChangedInternal,
+ VoiceInteractionService.this));
+ }
+
+ @Override
+ public void launchVoiceAssistFromKeyguard() {
+ Handler.getMain().executeOrSendMessage(PooledLambda.obtainMessage(
+ VoiceInteractionService::onLaunchVoiceAssistFromKeyguard,
+ VoiceInteractionService.this));
+ }
+
+ @Override
+ public void getActiveServiceSupportedActions(List<String> voiceActions,
+ IVoiceActionCheckCallback callback) {
+ Handler.getMain().executeOrSendMessage(
+ PooledLambda.obtainMessage(VoiceInteractionService::onHandleVoiceActionCheck,
+ VoiceInteractionService.this,
+ voiceActions,
+ callback));
}
};
- MyHandler mHandler;
-
IVoiceInteractionManagerService mSystemService;
private final Object mLock = new Object();
@@ -96,33 +123,6 @@
private AlwaysOnHotwordDetector mHotwordDetector;
- static final int MSG_READY = 1;
- static final int MSG_SHUTDOWN = 2;
- static final int MSG_SOUND_MODELS_CHANGED = 3;
- static final int MSG_LAUNCH_VOICE_ASSIST_FROM_KEYGUARD = 4;
-
- class MyHandler extends Handler {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MSG_READY:
- onReady();
- break;
- case MSG_SHUTDOWN:
- onShutdownInternal();
- break;
- case MSG_SOUND_MODELS_CHANGED:
- onSoundModelsChangedInternal();
- break;
- case MSG_LAUNCH_VOICE_ASSIST_FROM_KEYGUARD:
- onLaunchVoiceAssistFromKeyguard();
- break;
- default:
- super.handleMessage(msg);
- }
- }
- }
-
/**
* Called when a user has activated an affordance to launch voice assist from the Keyguard.
*
@@ -186,7 +186,7 @@
* be any combination of
* {@link VoiceInteractionSession#SHOW_WITH_ASSIST VoiceInteractionSession.SHOW_WITH_ASSIST} and
* {@link VoiceInteractionSession#SHOW_WITH_SCREENSHOT
- * VoiceInteractionSession.SHOW_WITH_SCREENSHOT}
+ * VoiceInteractionSession.SHOW_WITH_SCREENSHOT}
* to request that the system generate and deliver assist data on the current foreground
* app as part of showing the session UI.
*/
@@ -200,10 +200,22 @@
}
}
- @Override
- public void onCreate() {
- super.onCreate();
- mHandler = new MyHandler();
+ /**
+ * Request to query for what extended voice actions this service supports. This method will
+ * be called when the system checks the supported actions of this
+ * {@link VoiceInteractionService}. Supported actions may be delivered to
+ * {@link VoiceInteractionSession} later to request a session to perform an action.
+ *
+ * <p>Voice actions are defined in support libraries and could vary based on platform context.
+ * For example, car related voice actions will be defined in car support libraries.
+ *
+ * @param voiceActions A set of checked voice actions.
+ * @return Returns a subset of checked voice actions. Additional voice actions in the
+ * returned set will be ignored. Returns null or empty set if no actions are supported.
+ */
+ @Nullable
+ public Set<String> onGetSupportedVoiceActions(@NonNull Set<String> voiceActions) {
+ return null;
}
@Override
@@ -254,6 +266,18 @@
}
}
+ private void onHandleVoiceActionCheck(List<String> voiceActions,
+ IVoiceActionCheckCallback callback) {
+ if (callback != null) {
+ try {
+ Set<String> voiceActionsSet = new ArraySet<>(voiceActions);
+ Set<String> resultSet = onGetSupportedVoiceActions(voiceActionsSet);
+ callback.onComplete(resultSet == null ? null : new ArrayList<>(resultSet));
+ } catch (RemoteException e) {
+ }
+ }
+ }
+
/**
* Creates an {@link AlwaysOnHotwordDetector} for the given keyphrase and locale.
* This instance must be retained and used by the client.
@@ -289,12 +313,12 @@
}
/**
- * Checks if a given keyphrase and locale are supported to create an
- * {@link AlwaysOnHotwordDetector}.
- *
- * @return true if the keyphrase and locale combination is supported, false otherwise.
- * @hide
- */
+ * Checks if a given keyphrase and locale are supported to create an
+ * {@link AlwaysOnHotwordDetector}.
+ *
+ * @return true if the keyphrase and locale combination is supported, false otherwise.
+ * @hide
+ */
@UnsupportedAppUsage
public final boolean isKeyphraseAndLocaleSupportedForHotword(String keyphrase, Locale locale) {
if (mKeyphraseEnrollmentInfo == null) {
diff --git a/core/java/android/text/GraphicsOperations.java b/core/java/android/text/GraphicsOperations.java
index 6edf845..6c15446 100644
--- a/core/java/android/text/GraphicsOperations.java
+++ b/core/java/android/text/GraphicsOperations.java
@@ -58,6 +58,6 @@
/**
* Just like {@link Paint#getTextRunCursor}.
*/
- int getTextRunCursor(int contextStart, int contextEnd, int dir, int offset,
+ int getTextRunCursor(int contextStart, int contextEnd, boolean isRtl, int offset,
int cursorOpt, Paint p);
}
diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java
index 33c977b..c89617f 100644
--- a/core/java/android/text/Layout.java
+++ b/core/java/android/text/Layout.java
@@ -619,7 +619,7 @@
previousLineBottom = lbottom;
int lbaseline = lbottom - getLineDescent(i);
- if (start >= spanEnd) {
+ if (end >= spanEnd) {
// These should be infrequent, so we'll use this so that
// we don't have to check as often.
spanEnd = mLineBackgroundSpans.getNextTransition(start, textLength);
diff --git a/core/java/android/text/SpannableStringBuilder.java b/core/java/android/text/SpannableStringBuilder.java
index 9d841e8..c5fabaf 100644
--- a/core/java/android/text/SpannableStringBuilder.java
+++ b/core/java/android/text/SpannableStringBuilder.java
@@ -1551,7 +1551,7 @@
*
* @param contextStart the start index of the context
* @param contextEnd the (non-inclusive) end index of the context
- * @param dir either DIRECTION_RTL or DIRECTION_LTR
+ * @param dir 1 if the run is RTL, otherwise 0
* @param offset the cursor position to move from
* @param cursorOpt how to move the cursor, one of CURSOR_AFTER,
* CURSOR_AT_OR_AFTER, CURSOR_BEFORE,
@@ -1563,21 +1563,28 @@
@Deprecated
public int getTextRunCursor(int contextStart, int contextEnd, int dir, int offset,
int cursorOpt, Paint p) {
+ return getTextRunCursor(contextStart, contextEnd, dir == 1, offset, cursorOpt, p);
+ }
+
+ /** @hide */
+ @Override
+ public int getTextRunCursor(int contextStart, int contextEnd, boolean isRtl, int offset,
+ int cursorOpt, Paint p) {
int ret;
int contextLen = contextEnd - contextStart;
if (contextEnd <= mGapStart) {
ret = p.getTextRunCursor(mText, contextStart, contextLen,
- dir, offset, cursorOpt);
+ isRtl, offset, cursorOpt);
} else if (contextStart >= mGapStart) {
ret = p.getTextRunCursor(mText, contextStart + mGapLength, contextLen,
- dir, offset + mGapLength, cursorOpt) - mGapLength;
+ isRtl, offset + mGapLength, cursorOpt) - mGapLength;
} else {
char[] buf = TextUtils.obtain(contextLen);
getChars(contextStart, contextEnd, buf, 0);
ret = p.getTextRunCursor(buf, 0, contextLen,
- dir, offset - contextStart, cursorOpt) + contextStart;
+ isRtl, offset - contextStart, cursorOpt) + contextStart;
TextUtils.recycle(buf);
}
diff --git a/core/java/android/text/TextLine.java b/core/java/android/text/TextLine.java
index ad7a851..b49a949 100644
--- a/core/java/android/text/TextLine.java
+++ b/core/java/android/text/TextLine.java
@@ -802,14 +802,13 @@
}
}
- int dir = runIsRtl ? Paint.DIRECTION_RTL : Paint.DIRECTION_LTR;
int cursorOpt = after ? Paint.CURSOR_AFTER : Paint.CURSOR_BEFORE;
if (mCharsValid) {
return wp.getTextRunCursor(mChars, spanStart, spanLimit - spanStart,
- dir, offset, cursorOpt);
+ runIsRtl, offset, cursorOpt);
} else {
return wp.getTextRunCursor(mText, mStart + spanStart,
- mStart + spanLimit, dir, mStart + offset, cursorOpt) - mStart;
+ mStart + spanLimit, runIsRtl, mStart + offset, cursorOpt) - mStart;
}
}
diff --git a/core/java/android/text/method/BaseKeyListener.java b/core/java/android/text/method/BaseKeyListener.java
index 5f0a46d..d4bcd12 100644
--- a/core/java/android/text/method/BaseKeyListener.java
+++ b/core/java/android/text/method/BaseKeyListener.java
@@ -310,7 +310,7 @@
return len;
}
- offset = paint.getTextRunCursor(text, offset, len, Paint.DIRECTION_LTR /* not used */,
+ offset = paint.getTextRunCursor(text, offset, len, false /* LTR, not used */,
offset, Paint.CURSOR_AFTER);
return adjustReplacementSpan(text, offset, false /* move to the end */);
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 2f677f9..be50dd1 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -1348,6 +1348,10 @@
mServedView.getWindowToken() == appWindowToken) {
finishInputLocked();
}
+ if (mCurRootView != null &&
+ mCurRootView.getWindowToken() == appWindowToken) {
+ mCurRootView = null;
+ }
}
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index dfbaf9a..bbfac44 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -12495,11 +12495,11 @@
advancesIndex);
}
- public int getTextRunCursor(int contextStart, int contextEnd, int dir,
+ public int getTextRunCursor(int contextStart, int contextEnd, boolean isRtl,
int offset, int cursorOpt, Paint p) {
int contextCount = contextEnd - contextStart;
return p.getTextRunCursor(mChars, contextStart + mStart,
- contextCount, dir, offset + mStart, cursorOpt);
+ contextCount, isRtl, offset + mStart, cursorOpt);
}
}
diff --git a/core/java/com/android/internal/app/AssistUtils.java b/core/java/com/android/internal/app/AssistUtils.java
index 9171959..0f8295a 100644
--- a/core/java/com/android/internal/app/AssistUtils.java
+++ b/core/java/com/android/internal/app/AssistUtils.java
@@ -16,8 +16,7 @@
package com.android.internal.app;
-import com.android.internal.R;
-
+import android.annotation.NonNull;
import android.app.SearchManager;
import android.content.ComponentName;
import android.content.Context;
@@ -32,6 +31,9 @@
import android.provider.Settings;
import android.util.Log;
+import java.util.ArrayList;
+import java.util.Set;
+
/**
* Utility method for dealing with the assistant aspects of
* {@link com.android.internal.app.IVoiceInteractionManagerService IVoiceInteractionManagerService}.
@@ -62,6 +64,30 @@
return false;
}
+ /**
+ * Checks the availability of a set of voice actions for the current active voice service.
+ *
+ * @param voiceActions A set of supported voice actions to be checked.
+ * @param callback The callback which will deliver a set of supported voice actions. If
+ * no voice actions are supported for the given voice action set, then null
+ * or empty set is provided.
+ */
+ public void getActiveServiceSupportedActions(@NonNull Set<String> voiceActions,
+ @NonNull IVoiceActionCheckCallback callback) {
+ try {
+ if (mVoiceInteractionManagerService != null) {
+ mVoiceInteractionManagerService
+ .getActiveServiceSupportedActions(new ArrayList<>(voiceActions), callback);
+ }
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed to call activeServiceSupportedActions", e);
+ try {
+ callback.onComplete(null);
+ } catch (RemoteException re) {
+ }
+ }
+ }
+
public void launchVoiceAssistFromKeyguard() {
try {
if (mVoiceInteractionManagerService != null) {
@@ -157,7 +183,7 @@
return getActiveServiceComponentName();
}
final SearchManager searchManager =
- (SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE);
+ (SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE);
if (searchManager == null) {
return null;
}
diff --git a/core/java/com/android/internal/app/IVoiceActionCheckCallback.aidl b/core/java/com/android/internal/app/IVoiceActionCheckCallback.aidl
new file mode 100644
index 0000000..66ba93d
--- /dev/null
+++ b/core/java/com/android/internal/app/IVoiceActionCheckCallback.aidl
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.app;
+
+oneway interface IVoiceActionCheckCallback {
+ void onComplete(in List<String> voiceActions);
+}
diff --git a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
index ff75a8b..5088cca 100644
--- a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
+++ b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
@@ -20,6 +20,7 @@
import android.content.Intent;
import android.os.Bundle;
+import com.android.internal.app.IVoiceActionCheckCallback;
import com.android.internal.app.IVoiceInteractionSessionShowCallback;
import com.android.internal.app.IVoiceInteractor;
import com.android.internal.app.IVoiceInteractionSessionListener;
@@ -143,4 +144,11 @@
* Register a voice interaction listener.
*/
void registerVoiceInteractionSessionListener(IVoiceInteractionSessionListener listener);
+
+ /**
+ * Checks the availability of a set of voice actions for the current active voice service.
+ * Returns all supported voice actions.
+ */
+ void getActiveServiceSupportedActions(in List<String> voiceActions,
+ in IVoiceActionCheckCallback callback);
}
diff --git a/core/java/com/android/internal/view/InputBindResult.java b/core/java/com/android/internal/view/InputBindResult.java
index 7548c22..101fd41 100644
--- a/core/java/com/android/internal/view/InputBindResult.java
+++ b/core/java/com/android/internal/view/InputBindResult.java
@@ -139,8 +139,7 @@
* The client should try to restart input when its {@link android.view.Window} is focused
* again.</p>
*
- * @see com.android.server.wm.WindowManagerInternal#inputMethodClientHasFocus(
- * IInputMethodClient)
+ * @see com.android.server.wm.WindowManagerInternal#isInputMethodClientFocus(int, int)
*/
int ERROR_NOT_IME_TARGET_WINDOW = 11;
/**
diff --git a/data/keyboards/Vendor_054c_Product_0268.kl b/data/keyboards/Vendor_054c_Product_0268.kl
index 522db3c..b463dd8 100644
--- a/data/keyboards/Vendor_054c_Product_0268.kl
+++ b/data/keyboards/Vendor_054c_Product_0268.kl
@@ -21,8 +21,6 @@
key 0x126 DPAD_DOWN
key 0x127 DPAD_LEFT
-key 0x120 BUTTON_SELECT
-key 0x123 BUTTON_START
key 0x12e BUTTON_A
key 0x12d BUTTON_B
key 0x12f BUTTON_X
@@ -34,9 +32,6 @@
key 0x121 BUTTON_THUMBL
key 0x122 BUTTON_THUMBR
-# PS key
-key 0x2d0 BUTTON_MODE
-
# Left Analog Stick
axis 0x00 X
axis 0x01 Y
@@ -74,3 +69,11 @@
# Square
# axis 0x37
+
+# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt
+# Select
+key 0x120 BUTTON_SELECT
+# Start
+key 0x123 BUTTON_START
+# PS key
+key 0x2d0 BUTTON_MODE
diff --git a/data/keyboards/Vendor_054c_Product_0268_Version_8000.kl b/data/keyboards/Vendor_054c_Product_0268_Version_8000.kl
new file mode 100644
index 0000000..3d93f0f
--- /dev/null
+++ b/data/keyboards/Vendor_054c_Product_0268_Version_8000.kl
@@ -0,0 +1,57 @@
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# Sony Playstation(R)3 Controller
+# - Version 0x8000 and 0x8100 are for Linux hid-sony driver >=4.12
+# and when connected over Bluetooth
+#
+
+key 0x220 DPAD_UP
+key 0x223 DPAD_RIGHT
+key 0x221 DPAD_DOWN
+key 0x222 DPAD_LEFT
+
+key 0x130 BUTTON_A
+key 0x131 BUTTON_B
+key 0x134 BUTTON_X
+key 0x133 BUTTON_Y
+key 0x136 BUTTON_L1
+key 0x137 BUTTON_R1
+key 0x138 BUTTON_L2
+key 0x139 BUTTON_R2
+key 0x13d BUTTON_THUMBL
+key 0x13e BUTTON_THUMBR
+
+# left Analog Stick
+axis 0x00 X
+axis 0x01 Y
+
+# Right Analog Stick
+axis 0x03 Z
+axis 0x04 RZ
+
+# L2 trigger
+axis 0x02 LTRIGGER
+
+# R2 trigger
+axis 0x05 RTRIGGER
+
+# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt
+# Select
+key 0x13a BUTTON_SELECT
+# Start
+key 0x13b BUTTON_START
+# PS key
+key 0x13c BUTTON_MODE
diff --git a/data/keyboards/Vendor_054c_Product_0268_Version_8100.kl b/data/keyboards/Vendor_054c_Product_0268_Version_8100.kl
new file mode 100644
index 0000000..3d93f0f
--- /dev/null
+++ b/data/keyboards/Vendor_054c_Product_0268_Version_8100.kl
@@ -0,0 +1,57 @@
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# Sony Playstation(R)3 Controller
+# - Version 0x8000 and 0x8100 are for Linux hid-sony driver >=4.12
+# and when connected over Bluetooth
+#
+
+key 0x220 DPAD_UP
+key 0x223 DPAD_RIGHT
+key 0x221 DPAD_DOWN
+key 0x222 DPAD_LEFT
+
+key 0x130 BUTTON_A
+key 0x131 BUTTON_B
+key 0x134 BUTTON_X
+key 0x133 BUTTON_Y
+key 0x136 BUTTON_L1
+key 0x137 BUTTON_R1
+key 0x138 BUTTON_L2
+key 0x139 BUTTON_R2
+key 0x13d BUTTON_THUMBL
+key 0x13e BUTTON_THUMBR
+
+# left Analog Stick
+axis 0x00 X
+axis 0x01 Y
+
+# Right Analog Stick
+axis 0x03 Z
+axis 0x04 RZ
+
+# L2 trigger
+axis 0x02 LTRIGGER
+
+# R2 trigger
+axis 0x05 RTRIGGER
+
+# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt
+# Select
+key 0x13a BUTTON_SELECT
+# Start
+key 0x13b BUTTON_START
+# PS key
+key 0x13c BUTTON_MODE
diff --git a/data/keyboards/Vendor_054c_Product_0268_Version_8111.kl b/data/keyboards/Vendor_054c_Product_0268_Version_8111.kl
new file mode 100644
index 0000000..5fe35f7
--- /dev/null
+++ b/data/keyboards/Vendor_054c_Product_0268_Version_8111.kl
@@ -0,0 +1,57 @@
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# Sony Playstation(R)3 Controller
+# - Version 0x8111 is for Linux hid-sony driver >=4.12 and when
+# connected over USB
+#
+
+key 0x220 DPAD_UP
+key 0x223 DPAD_RIGHT
+key 0x221 DPAD_DOWN
+key 0x222 DPAD_LEFT
+
+key 0x130 BUTTON_A
+key 0x131 BUTTON_B
+key 0x134 BUTTON_X
+key 0x133 BUTTON_Y
+key 0x136 BUTTON_L1
+key 0x137 BUTTON_R1
+key 0x138 BUTTON_L2
+key 0x139 BUTTON_R2
+key 0x13d BUTTON_THUMBL
+key 0x13e BUTTON_THUMBR
+
+# left Analog Stick
+axis 0x00 X
+axis 0x01 Y
+
+# Right Analog Stick
+axis 0x03 Z
+axis 0x04 RZ
+
+# L2 trigger
+axis 0x02 LTRIGGER
+
+# R2 trigger
+axis 0x05 RTRIGGER
+
+# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt
+# Select
+key 0x13a BUTTON_SELECT
+# Start
+key 0x13b BUTTON_START
+# PS key
+key 0x13c BUTTON_MODE
diff --git a/data/keyboards/Vendor_054c_Product_05c4.kl b/data/keyboards/Vendor_054c_Product_05c4.kl
index a1284a4..cd7ab1f 100644
--- a/data/keyboards/Vendor_054c_Product_05c4.kl
+++ b/data/keyboards/Vendor_054c_Product_05c4.kl
@@ -60,7 +60,6 @@
key 0x138 BUTTON_SELECT
# Options
key 0x139 BUTTON_START
-
# PS key
key 0x13c BUTTON_MODE
diff --git a/data/keyboards/Vendor_054c_Product_05c4_Version_8000.kl b/data/keyboards/Vendor_054c_Product_05c4_Version_8000.kl
new file mode 100644
index 0000000..19fcb86
--- /dev/null
+++ b/data/keyboards/Vendor_054c_Product_05c4_Version_8000.kl
@@ -0,0 +1,68 @@
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# Sony Playstation(R) DualShock 4 Controller
+# - Version 0x8000 and 0x8100 are for Linux hid-sony driver >=4.10
+# and when connected over Bluetooth
+#
+
+
+# Mapping according to https://developer.android.com/training/game-controllers/controller-input.html
+
+# Square
+key 0x134 BUTTON_X
+# Cross
+key 0x130 BUTTON_A
+# Circle
+key 0x131 BUTTON_B
+# Triangle
+key 0x133 BUTTON_Y
+
+key 0x136 BUTTON_L1
+key 0x137 BUTTON_R1
+key 0x138 BUTTON_L2
+key 0x139 BUTTON_R2
+
+# L2 axis
+axis 0x02 LTRIGGER
+# R2 axis
+axis 0x05 RTRIGGER
+
+# Left Analog Stick
+axis 0x00 X
+axis 0x01 Y
+# Right Analog Stick
+axis 0x03 Z
+axis 0x04 RZ
+
+# Left stick click
+key 0x13d BUTTON_THUMBL
+# Right stick click
+key 0x13e BUTTON_THUMBR
+
+# Hat
+axis 0x10 HAT_X
+axis 0x11 HAT_Y
+
+# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt
+# Share
+key 0x13a BUTTON_SELECT
+# Options
+key 0x13b BUTTON_START
+# PS key
+key 0x13c BUTTON_MODE
+
+# In kernel versions >= 4.10, the touchpad is a separate input device,
+# so the touchpad button click will not be covered by this layout.
diff --git a/data/keyboards/Vendor_054c_Product_05c4_Version_8100.kl b/data/keyboards/Vendor_054c_Product_05c4_Version_8100.kl
new file mode 100644
index 0000000..19fcb86
--- /dev/null
+++ b/data/keyboards/Vendor_054c_Product_05c4_Version_8100.kl
@@ -0,0 +1,68 @@
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# Sony Playstation(R) DualShock 4 Controller
+# - Version 0x8000 and 0x8100 are for Linux hid-sony driver >=4.10
+# and when connected over Bluetooth
+#
+
+
+# Mapping according to https://developer.android.com/training/game-controllers/controller-input.html
+
+# Square
+key 0x134 BUTTON_X
+# Cross
+key 0x130 BUTTON_A
+# Circle
+key 0x131 BUTTON_B
+# Triangle
+key 0x133 BUTTON_Y
+
+key 0x136 BUTTON_L1
+key 0x137 BUTTON_R1
+key 0x138 BUTTON_L2
+key 0x139 BUTTON_R2
+
+# L2 axis
+axis 0x02 LTRIGGER
+# R2 axis
+axis 0x05 RTRIGGER
+
+# Left Analog Stick
+axis 0x00 X
+axis 0x01 Y
+# Right Analog Stick
+axis 0x03 Z
+axis 0x04 RZ
+
+# Left stick click
+key 0x13d BUTTON_THUMBL
+# Right stick click
+key 0x13e BUTTON_THUMBR
+
+# Hat
+axis 0x10 HAT_X
+axis 0x11 HAT_Y
+
+# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt
+# Share
+key 0x13a BUTTON_SELECT
+# Options
+key 0x13b BUTTON_START
+# PS key
+key 0x13c BUTTON_MODE
+
+# In kernel versions >= 4.10, the touchpad is a separate input device,
+# so the touchpad button click will not be covered by this layout.
diff --git a/data/keyboards/Vendor_054c_Product_05c4_Version_8111.kl b/data/keyboards/Vendor_054c_Product_05c4_Version_8111.kl
new file mode 100644
index 0000000..d38bdec
--- /dev/null
+++ b/data/keyboards/Vendor_054c_Product_05c4_Version_8111.kl
@@ -0,0 +1,68 @@
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# Sony Playstation(R) DualShock 4 Controller
+# - Version 0x8111 is for Linux hid-sony driver >=4.10 and when
+# connected over USB
+#
+
+
+# Mapping according to https://developer.android.com/training/game-controllers/controller-input.html
+
+# Square
+key 0x134 BUTTON_X
+# Cross
+key 0x130 BUTTON_A
+# Circle
+key 0x131 BUTTON_B
+# Triangle
+key 0x133 BUTTON_Y
+
+key 0x136 BUTTON_L1
+key 0x137 BUTTON_R1
+key 0x138 BUTTON_L2
+key 0x139 BUTTON_R2
+
+# L2 axis
+axis 0x02 LTRIGGER
+# R2 axis
+axis 0x05 RTRIGGER
+
+# Left Analog Stick
+axis 0x00 X
+axis 0x01 Y
+# Right Analog Stick
+axis 0x03 Z
+axis 0x04 RZ
+
+# Left stick click
+key 0x13d BUTTON_THUMBL
+# Right stick click
+key 0x13e BUTTON_THUMBR
+
+# Hat
+axis 0x10 HAT_X
+axis 0x11 HAT_Y
+
+# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt
+# Share
+key 0x13a BUTTON_SELECT
+# Options
+key 0x13b BUTTON_START
+# PS key
+key 0x13c BUTTON_MODE
+
+# In kernel versions >= 4.10, the touchpad is a separate input device,
+# so the touchpad button click will not be covered by this layout.
diff --git a/data/keyboards/Vendor_054c_Product_09cc.kl b/data/keyboards/Vendor_054c_Product_09cc.kl
index a1284a4..cd7ab1f 100644
--- a/data/keyboards/Vendor_054c_Product_09cc.kl
+++ b/data/keyboards/Vendor_054c_Product_09cc.kl
@@ -60,7 +60,6 @@
key 0x138 BUTTON_SELECT
# Options
key 0x139 BUTTON_START
-
# PS key
key 0x13c BUTTON_MODE
diff --git a/data/keyboards/Vendor_054c_Product_09cc_Version_8000.kl b/data/keyboards/Vendor_054c_Product_09cc_Version_8000.kl
new file mode 100644
index 0000000..19fcb86
--- /dev/null
+++ b/data/keyboards/Vendor_054c_Product_09cc_Version_8000.kl
@@ -0,0 +1,68 @@
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# Sony Playstation(R) DualShock 4 Controller
+# - Version 0x8000 and 0x8100 are for Linux hid-sony driver >=4.10
+# and when connected over Bluetooth
+#
+
+
+# Mapping according to https://developer.android.com/training/game-controllers/controller-input.html
+
+# Square
+key 0x134 BUTTON_X
+# Cross
+key 0x130 BUTTON_A
+# Circle
+key 0x131 BUTTON_B
+# Triangle
+key 0x133 BUTTON_Y
+
+key 0x136 BUTTON_L1
+key 0x137 BUTTON_R1
+key 0x138 BUTTON_L2
+key 0x139 BUTTON_R2
+
+# L2 axis
+axis 0x02 LTRIGGER
+# R2 axis
+axis 0x05 RTRIGGER
+
+# Left Analog Stick
+axis 0x00 X
+axis 0x01 Y
+# Right Analog Stick
+axis 0x03 Z
+axis 0x04 RZ
+
+# Left stick click
+key 0x13d BUTTON_THUMBL
+# Right stick click
+key 0x13e BUTTON_THUMBR
+
+# Hat
+axis 0x10 HAT_X
+axis 0x11 HAT_Y
+
+# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt
+# Share
+key 0x13a BUTTON_SELECT
+# Options
+key 0x13b BUTTON_START
+# PS key
+key 0x13c BUTTON_MODE
+
+# In kernel versions >= 4.10, the touchpad is a separate input device,
+# so the touchpad button click will not be covered by this layout.
diff --git a/data/keyboards/Vendor_054c_Product_09cc_Version_8100.kl b/data/keyboards/Vendor_054c_Product_09cc_Version_8100.kl
new file mode 100644
index 0000000..19fcb86
--- /dev/null
+++ b/data/keyboards/Vendor_054c_Product_09cc_Version_8100.kl
@@ -0,0 +1,68 @@
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# Sony Playstation(R) DualShock 4 Controller
+# - Version 0x8000 and 0x8100 are for Linux hid-sony driver >=4.10
+# and when connected over Bluetooth
+#
+
+
+# Mapping according to https://developer.android.com/training/game-controllers/controller-input.html
+
+# Square
+key 0x134 BUTTON_X
+# Cross
+key 0x130 BUTTON_A
+# Circle
+key 0x131 BUTTON_B
+# Triangle
+key 0x133 BUTTON_Y
+
+key 0x136 BUTTON_L1
+key 0x137 BUTTON_R1
+key 0x138 BUTTON_L2
+key 0x139 BUTTON_R2
+
+# L2 axis
+axis 0x02 LTRIGGER
+# R2 axis
+axis 0x05 RTRIGGER
+
+# Left Analog Stick
+axis 0x00 X
+axis 0x01 Y
+# Right Analog Stick
+axis 0x03 Z
+axis 0x04 RZ
+
+# Left stick click
+key 0x13d BUTTON_THUMBL
+# Right stick click
+key 0x13e BUTTON_THUMBR
+
+# Hat
+axis 0x10 HAT_X
+axis 0x11 HAT_Y
+
+# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt
+# Share
+key 0x13a BUTTON_SELECT
+# Options
+key 0x13b BUTTON_START
+# PS key
+key 0x13c BUTTON_MODE
+
+# In kernel versions >= 4.10, the touchpad is a separate input device,
+# so the touchpad button click will not be covered by this layout.
diff --git a/data/keyboards/Vendor_054c_Product_09cc_Version_8111.kl b/data/keyboards/Vendor_054c_Product_09cc_Version_8111.kl
new file mode 100644
index 0000000..d38bdec
--- /dev/null
+++ b/data/keyboards/Vendor_054c_Product_09cc_Version_8111.kl
@@ -0,0 +1,68 @@
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# Sony Playstation(R) DualShock 4 Controller
+# - Version 0x8111 is for Linux hid-sony driver >=4.10 and when
+# connected over USB
+#
+
+
+# Mapping according to https://developer.android.com/training/game-controllers/controller-input.html
+
+# Square
+key 0x134 BUTTON_X
+# Cross
+key 0x130 BUTTON_A
+# Circle
+key 0x131 BUTTON_B
+# Triangle
+key 0x133 BUTTON_Y
+
+key 0x136 BUTTON_L1
+key 0x137 BUTTON_R1
+key 0x138 BUTTON_L2
+key 0x139 BUTTON_R2
+
+# L2 axis
+axis 0x02 LTRIGGER
+# R2 axis
+axis 0x05 RTRIGGER
+
+# Left Analog Stick
+axis 0x00 X
+axis 0x01 Y
+# Right Analog Stick
+axis 0x03 Z
+axis 0x04 RZ
+
+# Left stick click
+key 0x13d BUTTON_THUMBL
+# Right stick click
+key 0x13e BUTTON_THUMBR
+
+# Hat
+axis 0x10 HAT_X
+axis 0x11 HAT_Y
+
+# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt
+# Share
+key 0x13a BUTTON_SELECT
+# Options
+key 0x13b BUTTON_START
+# PS key
+key 0x13c BUTTON_MODE
+
+# In kernel versions >= 4.10, the touchpad is a separate input device,
+# so the touchpad button click will not be covered by this layout.
diff --git a/data/keyboards/Vendor_054c_Product_0ba0.kl b/data/keyboards/Vendor_054c_Product_0ba0.kl
new file mode 100644
index 0000000..bc6fc3b
--- /dev/null
+++ b/data/keyboards/Vendor_054c_Product_0ba0.kl
@@ -0,0 +1,70 @@
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# Sony Playstation(R) DualShock 4 USB Dongle
+#
+
+
+# Mapping according to https://developer.android.com/training/game-controllers/controller-input.html
+
+# Square
+key 0x130 BUTTON_X
+# Cross
+key 0x131 BUTTON_A
+# Circle
+key 0x132 BUTTON_B
+# Triangle
+key 0x133 BUTTON_Y
+
+key 0x134 BUTTON_L1
+key 0x135 BUTTON_R1
+key 0x136 BUTTON_L2
+key 0x137 BUTTON_R2
+
+# L2 axis
+axis 0x03 LTRIGGER
+# R2 axis
+axis 0x04 RTRIGGER
+
+
+# Left Analog Stick
+axis 0x00 X
+axis 0x01 Y
+# Right Analog Stick
+axis 0x02 Z
+axis 0x05 RZ
+
+# Left stick click
+key 0x13a BUTTON_THUMBL
+# Right stick click
+key 0x13b BUTTON_THUMBR
+
+# Hat
+axis 0x10 HAT_X
+axis 0x11 HAT_Y
+
+# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt
+# Share
+key 0x138 BUTTON_SELECT
+# Options
+key 0x139 BUTTON_START
+# PS key
+key 0x13c BUTTON_MODE
+
+# Touchpad press
+# The touchpad for this joystick will become a separate input device in future releases
+# and this button will be equivalent to left mouse button
+# Therefore, map it to KEYCODE_BUTTON_1 here to allow apps to still handle this on earlier versions
+key 0x13d BUTTON_1
diff --git a/data/keyboards/Vendor_054c_Product_0ba0_Version_8111.kl b/data/keyboards/Vendor_054c_Product_0ba0_Version_8111.kl
new file mode 100644
index 0000000..8b85a38
--- /dev/null
+++ b/data/keyboards/Vendor_054c_Product_0ba0_Version_8111.kl
@@ -0,0 +1,67 @@
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# Sony Playstation(R) DualShock 4 USB Dongle
+# - Version 0x8111 is for Linux hid-sony driver >=4.10
+#
+
+
+# Mapping according to https://developer.android.com/training/game-controllers/controller-input.html
+
+# Square
+key 0x134 BUTTON_X
+# Cross
+key 0x130 BUTTON_A
+# Circle
+key 0x131 BUTTON_B
+# Triangle
+key 0x133 BUTTON_Y
+
+key 0x136 BUTTON_L1
+key 0x137 BUTTON_R1
+key 0x138 BUTTON_L2
+key 0x139 BUTTON_R2
+
+# L2 axis
+axis 0x02 LTRIGGER
+# R2 axis
+axis 0x05 RTRIGGER
+
+# Left Analog Stick
+axis 0x00 X
+axis 0x01 Y
+# Right Analog Stick
+axis 0x03 Z
+axis 0x04 RZ
+
+# Left stick click
+key 0x13d BUTTON_THUMBL
+# Right stick click
+key 0x13e BUTTON_THUMBR
+
+# Hat
+axis 0x10 HAT_X
+axis 0x11 HAT_Y
+
+# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt
+# Share
+key 0x13a BUTTON_SELECT
+# Options
+key 0x13b BUTTON_START
+# PS key
+key 0x13c BUTTON_MODE
+
+# In kernel versions >= 4.10, the touchpad is a separate input device,
+# so the touchpad button click will not be covered by this layout.
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index 85b39fe..33caa00 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -17,6 +17,7 @@
package android.graphics;
import android.annotation.ColorInt;
+import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -37,6 +38,8 @@
import libcore.util.NativeAllocationRegistry;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -309,38 +312,47 @@
*/
public static final int DIRECTION_RTL = 1;
+ /** @hide */
+ @IntDef(prefix = { "CURSOR_" }, value = {
+ CURSOR_AFTER, CURSOR_AT_OR_AFTER, CURSOR_BEFORE, CURSOR_AT_OR_BEFORE
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface CursorOption {}
+
/**
- * Option for getTextRunCursor to compute the valid cursor after
- * offset or the limit of the context, whichever is less.
- * @hide
+ * Option for getTextRunCursor.
+ *
+ * Compute the valid cursor after offset or the limit of the context, whichever is less.
*/
public static final int CURSOR_AFTER = 0;
/**
- * Option for getTextRunCursor to compute the valid cursor at or after
- * the offset or the limit of the context, whichever is less.
- * @hide
+ * Option for getTextRunCursor.
+ *
+ * Compute the valid cursor at or after the offset or the limit of the context, whichever is
+ * less.
*/
public static final int CURSOR_AT_OR_AFTER = 1;
/**
- * Option for getTextRunCursor to compute the valid cursor before
- * offset or the start of the context, whichever is greater.
- * @hide
+ * Option for getTextRunCursor.
+ *
+ * Compute the valid cursor before offset or the start of the context, whichever is greater.
*/
public static final int CURSOR_BEFORE = 2;
/**
- * Option for getTextRunCursor to compute the valid cursor at or before
- * offset or the start of the context, whichever is greater.
- * @hide
+ * Option for getTextRunCursor.
+ *
+ * Compute the valid cursor at or before offset or the start of the context, whichever is
+ * greater.
*/
public static final int CURSOR_AT_OR_BEFORE = 3;
/**
- * Option for getTextRunCursor to return offset if the cursor at offset
- * is valid, or -1 if it isn't.
- * @hide
+ * Option for getTextRunCursor.
+ *
+ * Return offset if the cursor at offset is valid, or -1 if it isn't.
*/
public static final int CURSOR_AT = 4;
@@ -2410,34 +2422,32 @@
}
/**
- * Returns the next cursor position in the run. This avoids placing the
- * cursor between surrogates, between characters that form conjuncts,
- * between base characters and combining marks, or within a reordering
- * cluster.
+ * Returns the next cursor position in the run.
*
- * <p>ContextStart and offset are relative to the start of text.
- * The context is the shaping context for cursor movement, generally
- * the bounds of the metric span enclosing the cursor in the direction of
- * movement.
+ * This avoids placing the cursor between surrogates, between characters that form conjuncts,
+ * between base characters and combining marks, or within a reordering cluster.
*
- * <p>If cursorOpt is {@link #CURSOR_AT} and the offset is not a valid
- * cursor position, this returns -1. Otherwise this will never return a
- * value before contextStart or after contextStart + contextLength.
+ * <p>
+ * ContextStart and offset are relative to the start of text.
+ * The context is the shaping context for cursor movement, generally the bounds of the metric
+ * span enclosing the cursor in the direction of movement.
+ *
+ * <p>
+ * If cursorOpt is {@link #CURSOR_AT} and the offset is not a valid cursor position, this
+ * returns -1. Otherwise this will never return a value before contextStart or after
+ * contextStart + contextLength.
*
* @param text the text
* @param contextStart the start of the context
* @param contextLength the length of the context
- * @param dir either {@link #DIRECTION_RTL} or {@link #DIRECTION_LTR}
+ * @param isRtl true if the paragraph context is RTL, otherwise false
* @param offset the cursor position to move from
- * @param cursorOpt how to move the cursor, one of {@link #CURSOR_AFTER},
- * {@link #CURSOR_AT_OR_AFTER}, {@link #CURSOR_BEFORE},
- * {@link #CURSOR_AT_OR_BEFORE}, or {@link #CURSOR_AT}
+ * @param cursorOpt how to move the cursor
* @return the offset of the next position, or -1
- * @hide
*/
- @UnsupportedAppUsage
- public int getTextRunCursor(char[] text, int contextStart, int contextLength,
- int dir, int offset, int cursorOpt) {
+ public int getTextRunCursor(@NonNull char[] text, @IntRange(from = 0) int contextStart,
+ @IntRange(from = 0) int contextLength, boolean isRtl, @IntRange(from = 0) int offset,
+ @CursorOption int cursorOpt) {
int contextEnd = contextStart + contextLength;
if (((contextStart | contextEnd | offset | (contextEnd - contextStart)
| (offset - contextStart) | (contextEnd - offset)
@@ -2446,85 +2456,87 @@
throw new IndexOutOfBoundsException();
}
- return nGetTextRunCursor(mNativePaint, text, contextStart, contextLength, dir, offset,
- cursorOpt);
+ return nGetTextRunCursor(mNativePaint, text, contextStart, contextLength,
+ isRtl ? DIRECTION_RTL : DIRECTION_LTR, offset, cursorOpt);
}
/**
- * Returns the next cursor position in the run. This avoids placing the
- * cursor between surrogates, between characters that form conjuncts,
- * between base characters and combining marks, or within a reordering
- * cluster.
+ * Returns the next cursor position in the run.
*
- * <p>ContextStart, contextEnd, and offset are relative to the start of
+ * This avoids placing the cursor between surrogates, between characters that form conjuncts,
+ * between base characters and combining marks, or within a reordering cluster.
+ *
+ * <p>
+ * ContextStart, contextEnd, and offset are relative to the start of
* text. The context is the shaping context for cursor movement, generally
* the bounds of the metric span enclosing the cursor in the direction of
* movement.
*
- * <p>If cursorOpt is {@link #CURSOR_AT} and the offset is not a valid
- * cursor position, this returns -1. Otherwise this will never return a
- * value before contextStart or after contextEnd.
+ * <p>
+ * If cursorOpt is {@link #CURSOR_AT} and the offset is not a valid cursor position, this
+ * returns -1. Otherwise this will never return a value before contextStart or after
+ * contextEnd.
*
* @param text the text
* @param contextStart the start of the context
* @param contextEnd the end of the context
- * @param dir either {@link #DIRECTION_RTL} or {@link #DIRECTION_LTR}
+ * @param isRtl true if the paragraph context is RTL, otherwise false
* @param offset the cursor position to move from
- * @param cursorOpt how to move the cursor, one of {@link #CURSOR_AFTER},
- * {@link #CURSOR_AT_OR_AFTER}, {@link #CURSOR_BEFORE},
- * {@link #CURSOR_AT_OR_BEFORE}, or {@link #CURSOR_AT}
+ * @param cursorOpt how to move the cursor
* @return the offset of the next position, or -1
- * @hide
*/
- public int getTextRunCursor(CharSequence text, int contextStart,
- int contextEnd, int dir, int offset, int cursorOpt) {
+ public int getTextRunCursor(@NonNull CharSequence text, @IntRange(from = 0) int contextStart,
+ @IntRange(from = 0) int contextEnd, boolean isRtl, @IntRange(from = 0) int offset,
+ @CursorOption int cursorOpt) {
if (text instanceof String || text instanceof SpannedString ||
text instanceof SpannableString) {
return getTextRunCursor(text.toString(), contextStart, contextEnd,
- dir, offset, cursorOpt);
+ isRtl, offset, cursorOpt);
}
if (text instanceof GraphicsOperations) {
return ((GraphicsOperations) text).getTextRunCursor(
- contextStart, contextEnd, dir, offset, cursorOpt, this);
+ contextStart, contextEnd, isRtl, offset, cursorOpt, this);
}
int contextLen = contextEnd - contextStart;
char[] buf = TemporaryBuffer.obtain(contextLen);
TextUtils.getChars(text, contextStart, contextEnd, buf, 0);
- int relPos = getTextRunCursor(buf, 0, contextLen, dir, offset - contextStart, cursorOpt);
+ int relPos = getTextRunCursor(buf, 0, contextLen, isRtl, offset - contextStart, cursorOpt);
TemporaryBuffer.recycle(buf);
return (relPos == -1) ? -1 : relPos + contextStart;
}
/**
- * Returns the next cursor position in the run. This avoids placing the
- * cursor between surrogates, between characters that form conjuncts,
- * between base characters and combining marks, or within a reordering
- * cluster.
+ * Returns the next cursor position in the run.
*
- * <p>ContextStart, contextEnd, and offset are relative to the start of
- * text. The context is the shaping context for cursor movement, generally
- * the bounds of the metric span enclosing the cursor in the direction of
- * movement.
+ * This avoids placing the cursor between surrogates, between characters that form conjuncts,
+ * between base characters and combining marks, or within a reordering cluster.
*
- * <p>If cursorOpt is {@link #CURSOR_AT} and the offset is not a valid
- * cursor position, this returns -1. Otherwise this will never return a
- * value before contextStart or after contextEnd.
+ * <p>
+ * ContextStart, contextEnd, and offset are relative to the start of text. The context is the
+ * shaping context for cursor movement, generally the bounds of the metric span enclosing the
+ * cursor in the direction of movement.
+ * </p>
+ *
+ * <p>
+ * If cursorOpt is {@link #CURSOR_AT} and the offset is not a valid cursor position, this
+ * returns -1. Otherwise this will never return a value before contextStart or after
+ * contextEnd.
+ * </p>
*
* @param text the text
* @param contextStart the start of the context
* @param contextEnd the end of the context
- * @param dir either {@link #DIRECTION_RTL} or {@link #DIRECTION_LTR}
+ * @param isRtl true if the paragraph context is RTL, otherwise false.
* @param offset the cursor position to move from
- * @param cursorOpt how to move the cursor, one of {@link #CURSOR_AFTER},
- * {@link #CURSOR_AT_OR_AFTER}, {@link #CURSOR_BEFORE},
- * {@link #CURSOR_AT_OR_BEFORE}, or {@link #CURSOR_AT}
+ * @param cursorOpt how to move the cursor
* @return the offset of the next position, or -1
* @hide
*/
- public int getTextRunCursor(String text, int contextStart, int contextEnd,
- int dir, int offset, int cursorOpt) {
+ public int getTextRunCursor(@NonNull String text, @IntRange(from = 0) int contextStart,
+ @IntRange(from = 0) int contextEnd, boolean isRtl, @IntRange(from = 0) int offset,
+ @CursorOption int cursorOpt) {
if (((contextStart | contextEnd | offset | (contextEnd - contextStart)
| (offset - contextStart) | (contextEnd - offset)
| (text.length() - contextEnd) | cursorOpt) < 0)
@@ -2532,8 +2544,8 @@
throw new IndexOutOfBoundsException();
}
- return nGetTextRunCursor(mNativePaint, text, contextStart, contextEnd, dir, offset,
- cursorOpt);
+ return nGetTextRunCursor(mNativePaint, text, contextStart, contextEnd,
+ isRtl ? DIRECTION_RTL : DIRECTION_LTR, offset, cursorOpt);
}
/**
@@ -2599,11 +2611,13 @@
* Return in bounds (allocated by the caller) the smallest rectangle that
* encloses all of the characters, with an implied origin at (0,0).
*
+ * Note that styles are ignored even if you pass {@link android.text.Spanned} instance.
+ * Use {@link android.text.StaticLayout} for measuring bounds of {@link android.text.Spanned}.
+ *
* @param text text to measure and return its bounds
* @param start index of the first char in the text to measure
* @param end 1 past the last char in the text to measure
* @param bounds returns the unioned bounds of all the text. Must be allocated by the caller
- * @hide
*/
public void getTextBounds(CharSequence text, int start, int end, Rect bounds) {
if ((start | end | (end - start) | (text.length() - end)) < 0) {
diff --git a/libs/hwui/JankTracker.cpp b/libs/hwui/JankTracker.cpp
index e6d2a6f..f2d50cd 100644
--- a/libs/hwui/JankTracker.cpp
+++ b/libs/hwui/JankTracker.cpp
@@ -146,7 +146,7 @@
frame[FrameInfoIndex::IntendedVsync] + mFrameInterval);
// If we hit the deadline, cool!
- if (frame[FrameInfoIndex::FrameCompleted] < mSwapDeadline) {
+ if (frame[FrameInfoIndex::FrameCompleted] < mSwapDeadline || totalDuration < mFrameInterval) {
if (isTripleBuffered) {
mData->reportJankType(JankType::kHighInputLatency);
(*mGlobalData)->reportJankType(JankType::kHighInputLatency);
diff --git a/media/java/android/media/MediaPlayer2.java b/media/java/android/media/MediaPlayer2.java
index 89827bc..7492aa6 100644
--- a/media/java/android/media/MediaPlayer2.java
+++ b/media/java/android/media/MediaPlayer2.java
@@ -1108,12 +1108,9 @@
/**
* Sets playback rate using {@link PlaybackParams}. The object sets its internal
- * PlaybackParams to the input, except that the object remembers previous speed
- * when input speed is zero. This allows the object to resume at previous speed
- * when play() is called. Calling it before the object is prepared does not change
- * the object state. After the object is prepared, calling it with zero speed is
- * equivalent to calling pause(). After the object is prepared, calling it with
- * non-zero speed is equivalent to calling play().
+ * PlaybackParams to the input. This allows the object to resume at previous speed
+ * when play() is called. Speed of zero is not allowed. Calling it does not change
+ * the object state.
*
* @param params the playback params.
*/
diff --git a/packages/SystemUI/res/layout/recents_onboarding.xml b/packages/SystemUI/res/layout/recents_onboarding.xml
index adf1e74..2538612 100644
--- a/packages/SystemUI/res/layout/recents_onboarding.xml
+++ b/packages/SystemUI/res/layout/recents_onboarding.xml
@@ -37,7 +37,7 @@
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="center_vertical"
- android:textColor="@android:color/white"
+ android:textColor="?attr/wallpaperTextColor"
android:textSize="16sp"/>
<ImageView
android:id="@+id/dismiss"
@@ -49,6 +49,7 @@
android:layout_marginEnd="2dp"
android:alpha="0.7"
android:src="@drawable/ic_close_white"
+ android:tint="?attr/wallpaperTextColor"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/accessibility_desc_close"/>
</LinearLayout>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index f7615e6..d8f7b61 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -121,7 +121,8 @@
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
- Dependency.get(StatusBarStateController.class).addListener(mStateListener);
+ Dependency.get(StatusBarStateController.class)
+ .addListener(mStateListener, StatusBarStateController.RANK_SHELF);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateController.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateController.java
index 7a69f2e..d6719f0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateController.java
@@ -16,42 +16,70 @@
package com.android.systemui.statusbar;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+import android.annotation.IntDef;
import android.util.ArraySet;
+import android.util.Log;
+import com.android.internal.annotations.GuardedBy;
+import java.lang.annotation.Retention;
+import java.util.ArrayList;
+import java.util.Comparator;
/**
* Tracks and reports on {@link StatusBarState}.
*/
public class StatusBarStateController {
+ private static final String TAG = "SbStateController";
private static final int MAX_STATE = StatusBarState.FULLSCREEN_USER_SWITCHER;
private static final int MIN_STATE = StatusBarState.SHADE;
- private final ArraySet<StateListener> mListeners = new ArraySet<>();
+ private static final Comparator <RankedListener> mComparator
+ = (o1, o2) -> Integer.compare(o1.rank, o2.rank);
+
+ private final ArrayList<RankedListener> mListeners = new ArrayList<>();
private int mState;
private int mLastState;
private boolean mLeaveOpenOnKeyguardHide;
+ // TODO: b/115739177 (remove this explicit ordering if we can)
+ @Retention(SOURCE)
+ @IntDef({RANK_STATUS_BAR, RANK_STATUS_BAR_WINDOW_CONTROLLER, RANK_STACK_SCROLLER, RANK_SHELF})
+ public @interface SbStateListenerRank {}
+ // This is the set of known dependencies when updating StatusBarState
+ public static final int RANK_STATUS_BAR = 0;
+ public static final int RANK_STATUS_BAR_WINDOW_CONTROLLER = 1;
+ public static final int RANK_STACK_SCROLLER = 2;
+ public static final int RANK_SHELF = 3;
+
public int getState() {
return mState;
}
- public void setState(int state) {
+ public boolean setState(int state) {
if (state > MAX_STATE || state < MIN_STATE) {
throw new IllegalArgumentException("Invalid state " + state);
}
if (state == mState) {
- return;
+ return false;
}
synchronized (mListeners) {
- for (StateListener listener : new ArraySet<>(mListeners)) {
- listener.onStatePreChange(mState, state);
+ for (RankedListener rl : new ArrayList<>(mListeners)) {
+ rl.listener.onStatePreChange(mState, state);
}
mLastState = mState;
mState = state;
- for (StateListener listener : new ArraySet<>(mListeners)) {
- listener.onStateChanged(mState);
+ for (RankedListener rl : new ArrayList<>(mListeners)) {
+ rl.listener.onStateChanged(mState);
+ }
+
+ for (RankedListener rl : new ArrayList<>(mListeners)) {
+ rl.listener.onStatePostChange();
}
}
+
+ return true;
}
public boolean goingToFullShade() {
@@ -72,20 +100,67 @@
public void addListener(StateListener listener) {
synchronized (mListeners) {
- mListeners.add(listener);
+ addListenerInternalLocked(listener, Integer.MAX_VALUE);
}
}
+ /**
+ * Add a listener and a rank based on the priority of this message
+ * @param listener the listener
+ * @param rank the order in which you'd like to be called. Ranked listeners will be
+ * notified before unranked, and we will sort ranked listeners from low to high
+ *
+ * @deprecated This method exists only to solve latent inter-dependencies from refactoring
+ * StatusBarState out of StatusBar.java. Any new listeners should be built not to need ranking
+ * (i.e., they are non-dependent on the order of operations of StatusBarState listeners).
+ */
+ public void addListener(StateListener listener, @SbStateListenerRank int rank) {
+ synchronized (mListeners) {
+ addListenerInternalLocked(listener, rank);
+ }
+ }
+
+ @GuardedBy("mListeners")
+ private void addListenerInternalLocked(StateListener listener, int rank) {
+ // Protect against double-subscribe
+ for (RankedListener rl : mListeners) {
+ if (rl.listener.equals(listener)) {
+ return;
+ }
+ }
+
+ RankedListener rl = new RankedListener(listener, rank);
+ mListeners.add(rl);
+ mListeners.sort(mComparator);
+ }
+
public void removeListener(StateListener listener) {
synchronized (mListeners) {
- mListeners.remove(listener);
+ mListeners.removeIf((it) -> it.listener.equals(listener));
}
}
+ public static String describe(int state) {
+ return StatusBarState.toShortString(state);
+ }
+
public interface StateListener {
public default void onStatePreChange(int oldState, int newState) {
}
+ public default void onStatePostChange() {
+ }
+
public void onStateChanged(int newState);
}
+
+ private class RankedListener {
+ private final StateListener listener;
+ private final int rank;
+
+ private RankedListener(StateListener l, int r) {
+ listener = l;
+ rank = r;
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index a725a0b..da98565 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -620,7 +620,8 @@
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
protected void onAttachedToWindow() {
super.onAttachedToWindow();
- Dependency.get(StatusBarStateController.class).addListener(mStateListener);
+ Dependency.get(StatusBarStateController.class)
+ .addListener(mStateListener, StatusBarStateController.RANK_STACK_SCROLLER);
Dependency.get(ConfigurationController.class).addCallback(this);
}
@@ -4248,8 +4249,9 @@
mDimAnimator.addUpdateListener(mDimUpdateListener);
mDimAnimator.start();
}
+
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
- public void setHideSensitive(boolean hideSensitive, boolean animate) {
+ private void setHideSensitive(boolean hideSensitive, boolean animate) {
if (hideSensitive != mAmbientState.isHideSensitive()) {
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
@@ -5008,8 +5010,12 @@
private void setStatusBarState(int statusBarState) {
mStatusBarState = statusBarState;
mAmbientState.setStatusBarState(statusBarState);
+ }
+
+ private void onStatePostChange() {
boolean onKeyguard = onKeyguard();
boolean publicMode = mLockscreenUserManager.isAnyProfilePublicMode();
+
if (mHeadsUpAppearanceController != null) {
mHeadsUpAppearanceController.setPublicMode(publicMode);
}
@@ -5026,6 +5032,8 @@
updateFooter();
updateChildren();
onUpdateRowStates();
+
+ mEntryManager.updateNotifications();
}
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
@@ -5949,5 +5957,10 @@
public void onStateChanged(int newState) {
setStatusBarState(newState);
}
- };
+
+ @Override
+ public void onStatePostChange() {
+ NotificationStackScrollLayout.this.onStatePostChange();
+ }
+ };
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 459b4d7..759e8ea 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -632,7 +632,7 @@
mColorExtractor = Dependency.get(SysuiColorExtractor.class);
mColorExtractor.addOnColorsChangedListener(this);
- mStatusBarStateController.addListener(this);
+ mStatusBarStateController.addListener(this, StatusBarStateController.RANK_STATUS_BAR);
mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
@@ -3453,7 +3453,14 @@
mIsKeyguard = false;
Trace.beginSection("StatusBar#hideKeyguard");
boolean staying = mStatusBarStateController.leaveOpenOnKeyguardHide();
- mStatusBarStateController.setState(StatusBarState.SHADE);
+ if (!(mStatusBarStateController.setState(StatusBarState.SHADE))) {
+ //TODO: StatusBarStateController should probably know about hiding the keyguard and
+ // notify listeners.
+
+ // If the state didn't change, we may still need to update public mode
+ updatePublicMode();
+ mEntryManager.updateNotifications();
+ }
View viewToClick = null;
if (mStatusBarStateController.leaveOpenOnKeyguardHide()) {
if (!mKeyguardRequested) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
index 51a5df2..57c7e28 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
@@ -93,7 +93,8 @@
mKeyguardScreenRotation = shouldEnableKeyguardScreenRotation();
mDozeParameters = dozeParameters;
mScreenBrightnessDoze = mDozeParameters.getScreenBrightnessDoze();
- Dependency.get(StatusBarStateController.class).addListener(mStateListener);
+ Dependency.get(StatusBarStateController.class).addListener(
+ mStateListener, StatusBarStateController.RANK_STATUS_BAR_WINDOW_CONTROLLER);
Dependency.get(ConfigurationController.class).addCallback(this);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
index 0adb439..29a6b95 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
@@ -403,7 +403,7 @@
boolean hasCACerts = !(conn.getService().getUserCaAliases().getList().isEmpty());
return new Pair<Integer, Boolean>(userId[0], hasCACerts);
} catch (RemoteException | InterruptedException | AssertionError e) {
- Log.i(TAG, e.getMessage());
+ Log.i(TAG, "failed to get CA certs", e);
new Handler(Dependency.get(Dependency.BG_LOOPER)).postDelayed(
() -> new CACertLoader().execute(userId[0]),
CA_CERT_LOADING_RETRY_TIME_IN_MS);
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index b71d7a7..da52d40 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -1834,7 +1834,7 @@
if (provider.widgets.isEmpty()) {
// cancel the future updates
- cancelBroadcasts(provider);
+ cancelBroadcastsLocked(provider);
// send the broacast saying that the provider is not in use any more
sendDisabledIntentLocked(provider);
@@ -1843,18 +1843,16 @@
}
}
- private void cancelBroadcasts(Provider provider) {
+ private void cancelBroadcastsLocked(Provider provider) {
if (DEBUG) {
- Slog.i(TAG, "cancelBroadcasts() for " + provider);
+ Slog.i(TAG, "cancelBroadcastsLocked() for " + provider);
}
if (provider.broadcast != null) {
- mAlarmManager.cancel(provider.broadcast);
- long token = Binder.clearCallingIdentity();
- try {
- provider.broadcast.cancel();
- } finally {
- Binder.restoreCallingIdentity(token);
- }
+ final PendingIntent broadcast = provider.broadcast;
+ mSaveStateHandler.post(() -> {
+ mAlarmManager.cancel(broadcast);
+ broadcast.cancel();
+ });
provider.broadcast = null;
}
}
@@ -2315,7 +2313,7 @@
mProviders.remove(provider);
// no need to send the DISABLE broadcast, since the receiver is gone anyway
- cancelBroadcasts(provider);
+ cancelBroadcastsLocked(provider);
}
private void sendEnableIntentLocked(Provider p) {
@@ -2369,17 +2367,14 @@
Binder.restoreCallingIdentity(token);
}
if (!alreadyRegistered) {
- long period = provider.info.updatePeriodMillis;
- if (period < MIN_UPDATE_PERIOD) {
- period = MIN_UPDATE_PERIOD;
- }
- final long oldId = Binder.clearCallingIdentity();
- try {
+ // Set the alarm outside of our locks; we've latched the first-time
+ // invariant and established the PendingIntent safely.
+ final long period = Math.max(provider.info.updatePeriodMillis, MIN_UPDATE_PERIOD);
+ final PendingIntent broadcast = provider.broadcast;
+ mSaveStateHandler.post(() ->
mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
- SystemClock.elapsedRealtime() + period, period, provider.broadcast);
- } finally {
- Binder.restoreCallingIdentity(oldId);
- }
+ SystemClock.elapsedRealtime() + period, period, broadcast)
+ );
}
}
}
@@ -3382,7 +3377,7 @@
// Reschedule for the new updatePeriodMillis (don't worry about handling
// it specially if updatePeriodMillis didn't change because we just sent
// an update, and the next one will be updatePeriodMillis from now).
- cancelBroadcasts(provider);
+ cancelBroadcastsLocked(provider);
registerForBroadcastsLocked(provider, appWidgetIds);
// If it's currently showing, call back with the new
// AppWidgetProviderInfo.
diff --git a/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java b/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java
index 9af952d..c933833 100644
--- a/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java
+++ b/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java
@@ -105,7 +105,7 @@
try {
IBackupTransport transport =
transportClient.connectOrThrow(
- "AppBackupUtils.appIsEligibleForBackupAtRuntime");
+ "AppBackupUtils.appIsRunningAndEligibleForBackupWithTransport");
return transport.isAppEligibleForBackup(
packageInfo, AppBackupUtils.appGetsFullBackup(packageInfo));
} catch (Exception e) {
diff --git a/services/core/java/com/android/server/IpSecService.java b/services/core/java/com/android/server/IpSecService.java
index 380f6a7..a69d416 100644
--- a/services/core/java/com/android/server/IpSecService.java
+++ b/services/core/java/com/android/server/IpSecService.java
@@ -1490,23 +1490,19 @@
}
}
- private static final String TUNNEL_OP = "STOPSHIP"; // = AppOpsManager.OP_MANAGE_IPSEC_TUNNELS;
+ private static final String TUNNEL_OP = AppOpsManager.OPSTR_MANAGE_IPSEC_TUNNELS;
private void enforceTunnelPermissions(String callingPackage) {
checkNotNull(callingPackage, "Null calling package cannot create IpSec tunnels");
- if (false) { // STOPSHIP if this line is present
- switch (getAppOpsManager().noteOp(
- TUNNEL_OP,
- Binder.getCallingUid(), callingPackage)) {
- case AppOpsManager.MODE_DEFAULT:
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.MANAGE_IPSEC_TUNNELS, "IpSecService");
- break;
- case AppOpsManager.MODE_ALLOWED:
- return;
- default:
- throw new SecurityException("Request to ignore AppOps for non-legacy API");
- }
+ switch (getAppOpsManager().noteOp(TUNNEL_OP, Binder.getCallingUid(), callingPackage)) {
+ case AppOpsManager.MODE_DEFAULT:
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.MANAGE_IPSEC_TUNNELS, "IpSecService");
+ break;
+ case AppOpsManager.MODE_ALLOWED:
+ return;
+ default:
+ throw new SecurityException("Request to ignore AppOps for non-legacy API");
}
}
diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java
index cb03255..f436286 100644
--- a/services/core/java/com/android/server/UiModeManagerService.java
+++ b/services/core/java/com/android/server/UiModeManagerService.java
@@ -42,31 +42,25 @@
import android.os.ServiceManager;
import android.os.ShellCallback;
import android.os.ShellCommand;
-import android.os.SystemProperties;
import android.os.UserHandle;
import android.provider.Settings;
import android.service.dreams.Sandman;
import android.service.vr.IVrManager;
import android.service.vr.IVrStateCallbacks;
-import android.text.TextUtils;
import android.util.Slog;
-import java.io.File;
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Collections;
-
import com.android.internal.R;
import com.android.internal.app.DisableCarModeActivity;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.notification.SystemNotificationChannels;
import com.android.internal.util.DumpUtils;
-import com.android.server.power.ShutdownThread;
import com.android.server.twilight.TwilightListener;
import com.android.server.twilight.TwilightManager;
import com.android.server.twilight.TwilightState;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
final class UiModeManagerService extends SystemService {
private static final String TAG = UiModeManager.class.getSimpleName();
private static final boolean LOG = false;
@@ -466,7 +460,7 @@
uiMode |= mNightMode << 4;
}
- if (mPowerSave && !mNightModeLocked) {
+ if (mPowerSave) {
uiMode &= ~Configuration.UI_MODE_NIGHT_NO;
uiMode |= Configuration.UI_MODE_NIGHT_YES;
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 7533db1..b898a90 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -8406,10 +8406,17 @@
}
}
+ /** @deprecated - Use {@link #removeContentProviderExternalAsUser} which takes a user ID. */
+ @Deprecated
+ @Override
public void removeContentProviderExternal(String name, IBinder token) {
+ removeContentProviderExternalAsUser(name, token, UserHandle.getCallingUserId());
+ }
+
+ @Override
+ public void removeContentProviderExternalAsUser(String name, IBinder token, int userId) {
enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
"Do not have permission in call removeContentProviderExternal()");
- int userId = UserHandle.getCallingUserId();
long ident = Binder.clearCallingIdentity();
try {
removeContentProviderExternalUnchecked(name, token, userId);
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 628207c..2199bb7 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -17,18 +17,18 @@
package com.android.server.am;
import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
-import static android.app.ActivityTaskManager.INVALID_STACK_ID;
import static android.app.ActivityManager.TaskDescription.ATTR_TASKDESCRIPTION_PREFIX;
import static android.app.ActivityOptions.ANIM_CLIP_REVEAL;
import static android.app.ActivityOptions.ANIM_CUSTOM;
+import static android.app.ActivityOptions.ANIM_OPEN_CROSS_PROFILE_APPS;
import static android.app.ActivityOptions.ANIM_REMOTE_ANIMATION;
import static android.app.ActivityOptions.ANIM_SCALE_UP;
import static android.app.ActivityOptions.ANIM_SCENE_TRANSITION;
-import static android.app.ActivityOptions.ANIM_OPEN_CROSS_PROFILE_APPS;
import static android.app.ActivityOptions.ANIM_THUMBNAIL_ASPECT_SCALE_DOWN;
import static android.app.ActivityOptions.ANIM_THUMBNAIL_ASPECT_SCALE_UP;
import static android.app.ActivityOptions.ANIM_THUMBNAIL_SCALE_DOWN;
import static android.app.ActivityOptions.ANIM_THUMBNAIL_SCALE_UP;
+import static android.app.ActivityTaskManager.INVALID_STACK_ID;
import static android.app.AppOpsManager.MODE_ALLOWED;
import static android.app.AppOpsManager.OP_PICTURE_IN_PICTURE;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
@@ -81,6 +81,8 @@
import static android.os.Build.VERSION_CODES.O;
import static android.os.Process.SYSTEM_UID;
import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_LEFT;
+
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SAVED_STATE;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STATES;
@@ -93,6 +95,13 @@
import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.am.ActivityRecordProto.CONFIGURATION_CONTAINER;
+import static com.android.server.am.ActivityRecordProto.FRONT_OF_TASK;
+import static com.android.server.am.ActivityRecordProto.IDENTIFIER;
+import static com.android.server.am.ActivityRecordProto.PROC_ID;
+import static com.android.server.am.ActivityRecordProto.STATE;
+import static com.android.server.am.ActivityRecordProto.TRANSLUCENT;
+import static com.android.server.am.ActivityRecordProto.VISIBLE;
import static com.android.server.am.ActivityStack.ActivityState.INITIALIZING;
import static com.android.server.am.ActivityStack.ActivityState.PAUSED;
import static com.android.server.am.ActivityStack.ActivityState.PAUSING;
@@ -110,14 +119,6 @@
import static com.android.server.am.TaskPersister.DEBUG;
import static com.android.server.am.TaskPersister.IMAGE_EXTENSION;
import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
-import static com.android.server.am.ActivityRecordProto.CONFIGURATION_CONTAINER;
-import static com.android.server.am.ActivityRecordProto.FRONT_OF_TASK;
-import static com.android.server.am.ActivityRecordProto.IDENTIFIER;
-import static com.android.server.am.ActivityRecordProto.PROC_ID;
-import static com.android.server.am.ActivityRecordProto.STATE;
-import static com.android.server.am.ActivityRecordProto.TRANSLUCENT;
-import static com.android.server.am.ActivityRecordProto.VISIBLE;
-import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_LEFT;
import static com.android.server.wm.IdentifierProto.HASH_CODE;
import static com.android.server.wm.IdentifierProto.TITLE;
import static com.android.server.wm.IdentifierProto.USER_ID;
@@ -132,6 +133,7 @@
import android.app.PendingIntent;
import android.app.PictureInPictureParams;
import android.app.ResultInfo;
+import android.app.servertransaction.ActivityConfigurationChangeItem;
import android.app.servertransaction.ActivityLifecycleItem;
import android.app.servertransaction.ActivityRelaunchItem;
import android.app.servertransaction.ClientTransaction;
@@ -143,7 +145,6 @@
import android.app.servertransaction.PipModeChangeItem;
import android.app.servertransaction.ResumeActivityItem;
import android.app.servertransaction.WindowVisibilityItem;
-import android.app.servertransaction.ActivityConfigurationChangeItem;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ActivityInfo;
@@ -1279,20 +1280,14 @@
/**
* Check whether this activity can be launched on the specified display.
+ *
* @param displayId Target display id.
- * @return {@code true} if either it is the default display or this activity is resizeable and
- * can be put a secondary screen.
+ * @return {@code true} if either it is the default display or this activity can be put on a
+ * secondary screen.
*/
boolean canBeLaunchedOnDisplay(int displayId) {
- final TaskRecord task = getTask();
-
- // The resizeability of an Activity's parent task takes precendence over the ActivityInfo.
- // This allows for a non resizable activity to be launched into a resizeable task.
- final boolean resizeable =
- task != null ? task.isResizeable() : supportsResizeableMultiWindow();
-
- return service.mStackSupervisor.canPlaceEntityOnDisplay(displayId,
- resizeable, launchedFromPid, launchedFromUid, info);
+ return service.mStackSupervisor.canPlaceEntityOnDisplay(displayId, launchedFromPid,
+ launchedFromUid, info);
}
/**
@@ -2495,6 +2490,14 @@
}
}
+ /**
+ * @return {@code true} if this activity was reparented to another display but
+ * {@link #ensureActivityConfiguration} is not called.
+ */
+ boolean shouldUpdateConfigForDisplayChanged() {
+ return mLastReportedDisplayId != getDisplayId();
+ }
+
boolean ensureActivityConfiguration(int globalChanges, boolean preserveWindow) {
return ensureActivityConfiguration(globalChanges, preserveWindow,
false /* ignoreStopState */);
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index aa4e68d..91e677b 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -5375,12 +5375,14 @@
display.positionChildAtTop(this, false /* includingParents */);
}
+ /** NOTE: Should only be called from {@link TaskRecord#reparent}. */
void moveToFrontAndResumeStateIfNeeded(ActivityRecord r, boolean moveToFront, boolean setResume,
boolean setPause, String reason) {
if (!moveToFront) {
return;
}
+ final ActivityState origState = r.getState();
// If the activity owns the last resumed activity, transfer that together,
// so that we don't resume the same activity again in the new stack.
// Apps may depend on onResume()/onPause() being called in pairs.
@@ -5393,9 +5395,14 @@
mPausingActivity = r;
schedulePauseTimeout(r);
}
- // Move the stack in which we are placing the activity to the front. The call will also
- // make sure the activity focus is set.
+ // Move the stack in which we are placing the activity to the front.
moveToFront(reason);
+ // If the original state is resumed, there is no state change to update focused app.
+ // So here makes sure the activity focus is set if it is the top.
+ if (origState == RESUMED && r == mStackSupervisor.getTopResumedActivity()) {
+ // TODO(b/111361570): Support multiple focused apps in WM
+ mService.setResumedActivityUncheckLocked(r, reason);
+ }
}
public int getStackId() {
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 310898e..8649e83 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -488,8 +488,8 @@
}
/** Check if placing task or activity on specified display is allowed. */
- boolean canPlaceEntityOnDisplay(int displayId, boolean resizeable, int callingPid,
- int callingUid, ActivityInfo activityInfo) {
+ boolean canPlaceEntityOnDisplay(int displayId, int callingPid, int callingUid,
+ ActivityInfo activityInfo) {
if (displayId == DEFAULT_DISPLAY) {
// No restrictions for the default display.
return true;
@@ -498,10 +498,6 @@
// Can't launch on secondary displays if feature is not supported.
return false;
}
- if (!resizeable && !displayConfigMatchesGlobal(displayId)) {
- // Can't apply wrong configuration to non-resizeable activities.
- return false;
- }
if (!isCallerAllowedToLaunchOnDisplay(callingPid, callingUid, displayId, activityInfo)) {
// Can't place activities to a display that has restricted launch rules.
// In this case the request should be made by explicitly adding target display id and
@@ -4530,11 +4526,14 @@
mService.setTaskWindowingMode(task.taskId,
WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY, true /* toTop */);
if (preferredDisplayId != actualDisplayId) {
- // Display a warning toast that we tried to put a non-resizeable task on a secondary
- // display with config different from global config.
+ Slog.w(TAG, "Failed to put " + task + " on display " + preferredDisplayId);
+ // Display a warning toast that we failed to put a task on a secondary display.
mService.getTaskChangeNotificationController()
.notifyActivityLaunchOnSecondaryDisplayFailed();
return;
+ } else if (!forceNonResizable && handleForcedResizableTask(task,
+ FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY)) {
+ return;
}
}
@@ -4554,16 +4553,23 @@
return;
}
+ handleForcedResizableTask(task, FORCED_RESIZEABLE_REASON_SPLIT_SCREEN);
+ }
+
+ /**
+ * @return {@code true} if the top activity of the task is forced to be resizable and the user
+ * was notified about activity being forced resized.
+ */
+ private boolean handleForcedResizableTask(TaskRecord task, int reason) {
final ActivityRecord topActivity = task.getTopActivity();
if (topActivity != null && topActivity.isNonResizableOrForcedResizable()
- && !topActivity.noDisplay) {
+ && !topActivity.noDisplay) {
final String packageName = topActivity.appInfo.packageName;
- final int reason = isSecondaryDisplayPreferred
- ? FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY
- : FORCED_RESIZEABLE_REASON_SPLIT_SCREEN;
mService.getTaskChangeNotificationController().notifyActivityForcedResizable(
task.taskId, reason, packageName);
+ return true;
}
+ return false;
}
void activityRelaunchedLocked(IBinder token) {
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index bcb2b9b..7df255d 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -945,7 +945,8 @@
auxiliaryResponse == null ? null : auxiliaryResponse.filters);
}
- void postStartActivityProcessing(ActivityRecord r, int result, ActivityStack targetStack) {
+ void postStartActivityProcessing(ActivityRecord r, int result,
+ ActivityStack startedActivityStack) {
if (ActivityManager.isStartResultFatalError(result)) {
return;
}
@@ -957,14 +958,6 @@
// about this, so it waits for the new activity to become visible instead.
mSupervisor.reportWaitingActivityLaunchedIfNeeded(r, result);
- ActivityStack startedActivityStack = null;
- final ActivityStack currentStack = r.getStack();
- if (currentStack != null) {
- startedActivityStack = currentStack;
- } else if (mTargetStack != null) {
- startedActivityStack = targetStack;
- }
-
if (startedActivityStack == null) {
return;
}
@@ -1240,23 +1233,41 @@
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
ActivityRecord[] outActivity) {
int result = START_CANCELED;
+ final ActivityStack startedActivityStack;
try {
mService.mWindowManager.deferSurfaceLayout();
result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, outActivity);
} finally {
- // If we are not able to proceed, disassociate the activity from the task. Leaving an
- // activity in an incomplete state can lead to issues, such as performing operations
- // without a window container.
- final ActivityStack stack = mStartActivity.getStack();
- if (!ActivityManager.isStartResultSuccessful(result) && stack != null) {
- stack.finishActivityLocked(mStartActivity, RESULT_CANCELED,
- null /* intentResultData */, "startActivity", true /* oomAdj */);
+ final ActivityStack currentStack = r.getStack();
+ startedActivityStack = currentStack != null ? currentStack : mTargetStack;
+
+ if (ActivityManager.isStartResultSuccessful(result)) {
+ if (startedActivityStack != null) {
+ // If there is no state change (e.g. a resumed activity is reparented to
+ // top of another display) to trigger a visibility/configuration checking,
+ // we have to update the configuration for changing to different display.
+ final ActivityRecord currentTop =
+ startedActivityStack.topRunningActivityLocked();
+ if (currentTop != null && currentTop.shouldUpdateConfigForDisplayChanged()) {
+ mSupervisor.ensureVisibilityAndConfig(currentTop, currentTop.getDisplayId(),
+ true /* markFrozenIfConfigChanged */, false /* deferResume */);
+ }
+ }
+ } else {
+ // If we are not able to proceed, disassociate the activity from the task.
+ // Leaving an activity in an incomplete state can lead to issues, such as
+ // performing operations without a window container.
+ final ActivityStack stack = mStartActivity.getStack();
+ if (stack != null) {
+ stack.finishActivityLocked(mStartActivity, RESULT_CANCELED,
+ null /* intentResultData */, "startActivity", true /* oomAdj */);
+ }
}
mService.mWindowManager.continueSurfaceLayout();
}
- postStartActivityProcessing(r, result, mTargetStack);
+ postStartActivityProcessing(r, result, startedActivityStack);
return result;
}
diff --git a/services/core/java/com/android/server/am/ActivityTaskManagerService.java b/services/core/java/com/android/server/am/ActivityTaskManagerService.java
index 212844a..6935703d 100644
--- a/services/core/java/com/android/server/am/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityTaskManagerService.java
@@ -4688,11 +4688,7 @@
return mSleeping;
}
- /**
- * Update AMS states when an activity is resumed. This should only be called by
- * {@link ActivityStack#onActivityStateChanged(
- * ActivityRecord, ActivityStack.ActivityState, String)} when an activity is resumed.
- */
+ /** Update AMS states when an activity is resumed. */
void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
final TaskRecord task = r.getTask();
if (task.isActivityTypeStandard()) {
diff --git a/services/core/java/com/android/server/am/MemoryStatUtil.java b/services/core/java/com/android/server/am/MemoryStatUtil.java
index f9dccea0..aad890b 100644
--- a/services/core/java/com/android/server/am/MemoryStatUtil.java
+++ b/services/core/java/com/android/server/am/MemoryStatUtil.java
@@ -22,6 +22,7 @@
import android.annotation.Nullable;
import android.os.FileUtils;
+import android.os.SystemProperties;
import android.util.Slog;
import com.android.internal.annotations.VisibleForTesting;
@@ -38,6 +39,10 @@
final class MemoryStatUtil {
private static final String TAG = TAG_WITH_CLASS_NAME ? "MemoryStatUtil" : TAG_AM;
+ /** True if device has per-app memcg */
+ private static final Boolean DEVICE_HAS_PER_APP_MEMCG =
+ SystemProperties.getBoolean("ro.config.per_app_memcg", false);
+
/** Path to check if device has memcg */
private static final String MEMCG_TEST_PATH = "/dev/memcg/apps/memory.stat";
/** Path to memory stat file for logging app start memory state */
@@ -55,15 +60,12 @@
private static final int PGMAJFAULT_INDEX = 11;
private static final int RSS_IN_BYTES_INDEX = 23;
- /** True if device has memcg */
- private static volatile Boolean sDeviceHasMemCg;
-
private MemoryStatUtil() {}
/**
* Reads memory stat for a process.
*
- * Reads from memcg if available on device, else fallback to procfs.
+ * Reads from per-app memcg if available on device, else fallback to procfs.
* Returns null if no stats can be read.
*/
@Nullable
@@ -156,15 +158,10 @@
}
/**
- * Checks if memcg is available on device.
- *
- * Touches the filesystem to do the check.
+ * Returns whether per-app memcg is available on device.
*/
static boolean hasMemcg() {
- if (sDeviceHasMemCg == null) {
- sDeviceHasMemCg = (new File(MEMCG_TEST_PATH)).exists();
- }
- return sDeviceHasMemCg;
+ return DEVICE_HAS_PER_APP_MEMCG;
}
static final class MemoryStat {
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 7256e23..9b42d65 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -1521,14 +1521,14 @@
/**
* Check whether this task can be launched on the specified display.
+ *
* @param displayId Target display id.
- * @return {@code true} if either it is the default display or this activity is resizeable and
- * can be put a secondary screen.
+ * @return {@code true} if either it is the default display or this activity can be put on a
+ * secondary display.
*/
boolean canBeLaunchedOnDisplay(int displayId) {
return mService.mStackSupervisor.canPlaceEntityOnDisplay(displayId,
- isResizeable(false /* checkSupportsPip */), -1 /* don't check PID */,
- -1 /* don't check UID */, null /* activityInfo */);
+ -1 /* don't check PID */, -1 /* don't check UID */, null /* activityInfo */);
}
/**
diff --git a/services/core/java/com/android/server/clipboard/ClipboardService.java b/services/core/java/com/android/server/clipboard/ClipboardService.java
index c028a43..873a8e3 100644
--- a/services/core/java/com/android/server/clipboard/ClipboardService.java
+++ b/services/core/java/com/android/server/clipboard/ClipboardService.java
@@ -639,12 +639,20 @@
}
}
- // Otherwise only focused applications can access the clipboard.
- boolean uidFocused = mWm.isUidFocused(callingUid);
- if (!uidFocused) {
- Slog.e(TAG, "Denying clipboard access to " + callingPackage
- + ", application is not in focus.");
+ switch (op) {
+ case AppOpsManager.OP_READ_CLIPBOARD:
+ // Clipboard can only be read by applications with focus.
+ boolean uidFocused = mWm.isUidFocused(callingUid);
+ if (!uidFocused) {
+ Slog.e(TAG, "Denying clipboard access to " + callingPackage
+ + ", application is not in focus.");
+ }
+ return uidFocused;
+ case AppOpsManager.OP_WRITE_CLIPBOARD:
+ // Writing is allowed without focus.
+ return true;
+ default:
+ throw new IllegalArgumentException("Unknown clipboard appop " + op);
}
- return uidFocused;
}
}
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index b2287ac..a0432011 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -2536,7 +2536,11 @@
// We need to check if this is the current client with
// focus in the window manager, to allow this call to
// be made before input is started in it.
- if (!mWindowManagerInternal.inputMethodClientHasFocus(client)) {
+ final ClientState cs = mClients.get(client.asBinder());
+ if (cs == null) {
+ throw new IllegalArgumentException("unknown client " + client.asBinder());
+ }
+ if (!mWindowManagerInternal.isInputMethodClientFocus(cs.uid, cs.pid)) {
Slog.w(TAG, "Ignoring showSoftInput of uid " + uid + ": " + client);
return false;
}
@@ -2616,7 +2620,11 @@
// We need to check if this is the current client with
// focus in the window manager, to allow this call to
// be made before input is started in it.
- if (!mWindowManagerInternal.inputMethodClientHasFocus(client)) {
+ final ClientState cs = mClients.get(client.asBinder());
+ if (cs == null) {
+ throw new IllegalArgumentException("unknown client " + client.asBinder());
+ }
+ if (!mWindowManagerInternal.isInputMethodClientFocus(cs.uid, cs.pid)) {
if (DEBUG) {
Slog.w(TAG, "Ignoring hideSoftInput of uid " + uid + ": " + client);
}
@@ -2734,7 +2742,7 @@
+ client.asBinder());
}
- if (!mWindowManagerInternal.inputMethodClientHasFocus(cs.client)) {
+ if (!mWindowManagerInternal.isInputMethodClientFocus(cs.uid, cs.pid)) {
// Check with the window manager to make sure this client actually
// has a window with focus. If not, reject. This is thread safe
// because if the focus changes some time before or after, the
diff --git a/services/core/java/com/android/server/pm/ComponentResolver.java b/services/core/java/com/android/server/pm/ComponentResolver.java
index 44b9c15..3b11525 100644
--- a/services/core/java/com/android/server/pm/ComponentResolver.java
+++ b/services/core/java/com/android/server/pm/ComponentResolver.java
@@ -378,7 +378,7 @@
for (int i = newIntents.size() - 1; i >= 0; --i) {
final PackageParser.ActivityIntentInfo intentInfo = newIntents.get(i);
final PackageParser.Package disabledPkg = sPackageManagerInternal
- .getDisabledPackage(intentInfo.activity.info.packageName);
+ .getDisabledSystemPackage(intentInfo.activity.info.packageName);
final List<PackageParser.Activity> systemActivities =
disabledPkg != null ? disabledPkg.activities : null;
adjustPriority(systemActivities, intentInfo, setupWizardPackage);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index db0c13c..91af0ec 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -718,6 +718,8 @@
@GuardedBy("mPackages")
final private ArraySet<PackageListObserver> mPackageListObservers = new ArraySet<>();
+ private PackageManager mPackageManager;
+
class PackageParserCallback implements PackageParser.Callback {
@Override public final boolean hasFeature(String feature) {
return PackageManagerService.this.hasSystemFeature(feature, 0);
@@ -22236,6 +22238,22 @@
}
@Override
+ public boolean isPlatformSigned(String packageName) {
+ PackageSetting packageSetting = mSettings.mPackages.get(packageName);
+ if (packageSetting == null) {
+ return false;
+ }
+ PackageParser.Package pkg = packageSetting.pkg;
+ if (pkg == null) {
+ // May happen if package in on a removable sd card
+ return false;
+ }
+ return pkg.mSigningDetails.hasAncestorOrSelf(mPlatformPackage.mSigningDetails)
+ || mPlatformPackage.mSigningDetails.checkCapability(pkg.mSigningDetails,
+ PackageParser.SigningDetails.CertCapabilities.PERMISSION);
+ }
+
+ @Override
public boolean isDataRestoreSafe(byte[] restoringFromSigHash, String packageName) {
SigningDetails sd = getSigningDetails(packageName);
if (sd == null) {
@@ -22347,7 +22365,7 @@
}
@Override
- public PackageParser.Package getDisabledPackage(String packageName) {
+ public PackageParser.Package getDisabledSystemPackage(String packageName) {
synchronized (mPackages) {
final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
return (ps != null) ? ps.pkg : null;
@@ -22355,6 +22373,12 @@
}
@Override
+ public @Nullable String getDisabledSystemPackageName(@NonNull String packageName) {
+ PackageParser.Package pkg = getDisabledSystemPackage(packageName);
+ return pkg == null ? null : pkg.packageName;
+ }
+
+ @Override
public String getKnownPackageName(int knownPackage, int userId) {
switch(knownPackage) {
case PackageManagerInternal.PACKAGE_BROWSER:
@@ -22392,21 +22416,6 @@
}
@Override
- public void setSmsAppPackagesProvider(PackagesProvider provider) {
- mDefaultPermissionPolicy.setSmsAppPackagesProvider(provider);
- }
-
- @Override
- public void setDialerAppPackagesProvider(PackagesProvider provider) {
- mDefaultPermissionPolicy.setDialerAppPackagesProvider(provider);
- }
-
- @Override
- public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
- mDefaultPermissionPolicy.setSimCallManagerPackagesProvider(provider);
- }
-
- @Override
public void setUseOpenWifiAppPackagesProvider(PackagesProvider provider) {
mDefaultPermissionPolicy.setUseOpenWifiAppPackagesProvider(provider);
}
@@ -22417,22 +22426,10 @@
}
@Override
- public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) {
- mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsApp(packageName, userId);
- }
-
- @Override
- public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) {
+ public void onDefaultDialerAppChanged(String packageName, int userId) {
synchronized (mPackages) {
mSettings.setDefaultDialerPackageNameLPw(packageName, userId);
}
- mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerApp(packageName, userId);
- }
-
- @Override
- public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
- mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManager(
- packageName, userId);
}
@Override
diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
index 846c7b7..3c9dd63 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -23,12 +23,13 @@
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.DownloadManager;
+import android.app.SearchManager;
import android.app.admin.DevicePolicyManager;
import android.companion.CompanionDeviceManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageList;
+import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.PackageManagerInternal.PackagesProvider;
@@ -53,6 +54,7 @@
import android.provider.MediaStore;
import android.provider.Telephony.Sms.Intents;
import android.security.Credentials;
+import android.speech.RecognitionService;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.ArrayMap;
@@ -61,6 +63,7 @@
import android.util.Slog;
import android.util.Xml;
+import com.android.internal.util.ArrayUtils;
import com.android.internal.util.XmlUtils;
import com.android.server.LocalServices;
@@ -73,6 +76,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -94,10 +98,15 @@
private static final String TAG = "DefaultPermGrantPolicy"; // must be <= 23 chars
private static final boolean DEBUG = false;
- private static final int DEFAULT_FLAGS =
+ @PackageManager.ResolveInfoFlags
+ private static final int DEFAULT_INTENT_QUERY_FLAGS =
PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
| PackageManager.MATCH_UNINSTALLED_PACKAGES;
+ @PackageManager.PackageInfoFlags
+ private static final int DEFAULT_PACKAGE_INFO_QUERY_FLAGS =
+ PackageManager.MATCH_UNINSTALLED_PACKAGES | PackageManager.GET_PERMISSIONS;
+
private static final String AUDIO_MIME_TYPE = "audio/mpeg";
private static final String TAG_EXCEPTIONS = "exceptions";
@@ -108,6 +117,8 @@
private static final String ATTR_FIXED = "fixed";
private static final Set<String> PHONE_PERMISSIONS = new ArraySet<>();
+
+
static {
PHONE_PERMISSIONS.add(Manifest.permission.READ_PHONE_STATE);
PHONE_PERMISSIONS.add(Manifest.permission.CALL_PHONE);
@@ -219,7 +230,7 @@
private final DefaultPermissionGrantedCallback mPermissionGrantedCallback;
public interface DefaultPermissionGrantedCallback {
/** Callback when permissions have been granted */
- public void onDefaultRuntimePermissionsGranted(int userId);
+ void onDefaultRuntimePermissionsGranted(int userId);
}
public DefaultPermissionGrantPolicy(Context context, Looper looper,
@@ -291,9 +302,9 @@
grantDefaultPermissionExceptions(userId);
}
- private void grantRuntimePermissionsForPackage(int userId, PackageParser.Package pkg) {
+ private void grantRuntimePermissionsForSystemPackage(int userId, PackageInfo pkg) {
Set<String> permissions = new ArraySet<>();
- for (String permission : pkg.requestedPermissions) {
+ for (String permission : pkg.requestedPermissions) {
final BasePermission bp = mPermissionManager.getPermission(permission);
if (bp == null) {
continue;
@@ -307,36 +318,71 @@
}
}
- private void grantAllRuntimePermissions(int userId) {
- Log.i(TAG, "Granting all runtime permissions for user " + userId);
- final PackageList packageList = mServiceInternal.getPackageList();
- for (String packageName : packageList.getPackageNames()) {
- final PackageParser.Package pkg = mServiceInternal.getPackage(packageName);
- if (pkg == null) {
- continue;
- }
- grantRuntimePermissionsForPackage(userId, pkg);
- }
- }
-
public void scheduleReadDefaultPermissionExceptions() {
mHandler.sendEmptyMessage(MSG_READ_DEFAULT_PERMISSION_EXCEPTIONS);
}
private void grantPermissionsToSysComponentsAndPrivApps(int userId) {
Log.i(TAG, "Granting permissions to platform components for user " + userId);
- final PackageList packageList = mServiceInternal.getPackageList();
- for (String packageName : packageList.getPackageNames()) {
- final PackageParser.Package pkg = mServiceInternal.getPackage(packageName);
+ List<PackageInfo> packages = mContext.getPackageManager().getInstalledPackagesAsUser(
+ DEFAULT_PACKAGE_INFO_QUERY_FLAGS, UserHandle.USER_SYSTEM);
+ for (PackageInfo pkg : packages) {
if (pkg == null) {
continue;
}
if (!isSysComponentOrPersistentPlatformSignedPrivApp(pkg)
|| !doesPackageSupportRuntimePermissions(pkg)
- || pkg.requestedPermissions.isEmpty()) {
+ || ArrayUtils.isEmpty(pkg.requestedPermissions)) {
continue;
}
- grantRuntimePermissionsForPackage(userId, pkg);
+ grantRuntimePermissionsForSystemPackage(userId, pkg);
+ }
+ }
+
+ @SafeVarargs
+ private final void grantIgnoringSystemPackage(String packageName, int userId,
+ Set<String>... permissionGroups) {
+ grantPermissionsToSystemPackage(packageName, userId, false, true, permissionGroups);
+ }
+
+ @SafeVarargs
+ private final void grantSystemFixedPermissionsToSystemPackage(String packageName, int userId,
+ Set<String>... permissionGroups) {
+ grantPermissionsToSystemPackage(packageName, userId, true, false, permissionGroups);
+ }
+
+ @SafeVarargs
+ private final void grantPermissionsToSystemPackage(
+ String packageName, int userId, Set<String>... permissionGroups) {
+ grantPermissionsToSystemPackage(packageName, userId, false, false, permissionGroups);
+ }
+
+ @SafeVarargs
+ private final void grantPermissionsToSystemPackage(String packageName, int userId,
+ boolean systemFixed, boolean ignoreSystemPackage, Set<String>... permissionGroups) {
+ if (!ignoreSystemPackage && !isSystemPackage(packageName)) {
+ return;
+ }
+ grantRuntimePermissionsToPackage(getSystemPackageInfo(packageName),
+ userId, systemFixed, ignoreSystemPackage, permissionGroups);
+ }
+
+ @SafeVarargs
+ private final void grantRuntimePermissionsToPackage(String packageName, int userId,
+ boolean systemFixed, boolean ignoreSystemPackage, Set<String>... permissionGroups) {
+ grantRuntimePermissionsToPackage(getPackageInfo(packageName),
+ userId, systemFixed, ignoreSystemPackage, permissionGroups);
+ }
+
+ @SafeVarargs
+ private final void grantRuntimePermissionsToPackage(PackageInfo packageName, int userId,
+ boolean systemFixed, boolean ignoreSystemPackage, Set<String>... permissionGroups) {
+ if (packageName == null) return;
+ if (doesPackageSupportRuntimePermissions(packageName)) {
+ for (Set<String> permissionGroup : permissionGroups) {
+ grantRuntimePermissions(packageName, permissionGroup, systemFixed,
+ ignoreSystemPackage, userId);
+ }
}
}
@@ -379,594 +425,373 @@
syncAdapterPackagesProvider.getPackages(CalendarContract.AUTHORITY, userId) : null;
// Installer
- final String installerPackageName = mServiceInternal.getKnownPackageName(
- PackageManagerInternal.PACKAGE_INSTALLER, userId);
- PackageParser.Package installerPackage = getSystemPackage(installerPackageName);
- if (installerPackage != null
- && doesPackageSupportRuntimePermissions(installerPackage)) {
- grantRuntimePermissions(installerPackage, STORAGE_PERMISSIONS, true, userId);
- }
+ grantSystemFixedPermissionsToSystemPackage(
+ getKnownPackage(PackageManagerInternal.PACKAGE_INSTALLER, userId),
+ userId, STORAGE_PERMISSIONS);
// Verifier
- final String verifierPackageName = mServiceInternal.getKnownPackageName(
- PackageManagerInternal.PACKAGE_VERIFIER, userId);
- PackageParser.Package verifierPackage = getSystemPackage(verifierPackageName);
- if (verifierPackage != null
- && doesPackageSupportRuntimePermissions(verifierPackage)) {
- grantRuntimePermissions(verifierPackage, STORAGE_PERMISSIONS, true, userId);
- grantRuntimePermissions(verifierPackage, PHONE_PERMISSIONS, false, userId);
- grantRuntimePermissions(verifierPackage, SMS_PERMISSIONS, false, userId);
- }
+ final String verifier = getKnownPackage(PackageManagerInternal.PACKAGE_VERIFIER, userId);
+ grantSystemFixedPermissionsToSystemPackage(verifier, userId, STORAGE_PERMISSIONS);
+ grantPermissionsToSystemPackage(verifier, userId, PHONE_PERMISSIONS, SMS_PERMISSIONS);
// SetupWizard
- final String setupWizardPackageName = mServiceInternal.getKnownPackageName(
- PackageManagerInternal.PACKAGE_SETUP_WIZARD, userId);
- PackageParser.Package setupPackage = getSystemPackage(setupWizardPackageName);
- if (setupPackage != null
- && doesPackageSupportRuntimePermissions(setupPackage)) {
- grantRuntimePermissions(setupPackage, PHONE_PERMISSIONS, userId);
- grantRuntimePermissions(setupPackage, CONTACTS_PERMISSIONS, userId);
- grantRuntimePermissions(setupPackage, LOCATION_PERMISSIONS, userId);
- grantRuntimePermissions(setupPackage, CAMERA_PERMISSIONS, userId);
- }
+ grantPermissionsToSystemPackage(
+ getKnownPackage(PackageManagerInternal.PACKAGE_SETUP_WIZARD, userId), userId,
+ PHONE_PERMISSIONS, CONTACTS_PERMISSIONS, LOCATION_PERMISSIONS, CAMERA_PERMISSIONS);
// Camera
- Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
- PackageParser.Package cameraPackage = getDefaultSystemHandlerActivityPackage(
- cameraIntent, userId);
- if (cameraPackage != null
- && doesPackageSupportRuntimePermissions(cameraPackage)) {
- grantRuntimePermissions(cameraPackage, CAMERA_PERMISSIONS, userId);
- grantRuntimePermissions(cameraPackage, MICROPHONE_PERMISSIONS, userId);
- grantRuntimePermissions(cameraPackage, STORAGE_PERMISSIONS, userId);
- }
+ grantPermissionsToSystemPackage(
+ getDefaultSystemHandlerActivityPackage(MediaStore.ACTION_IMAGE_CAPTURE, userId),
+ userId, CAMERA_PERMISSIONS, MICROPHONE_PERMISSIONS, STORAGE_PERMISSIONS);
// Media provider
- PackageParser.Package mediaStorePackage = getDefaultProviderAuthorityPackage(
- MediaStore.AUTHORITY, userId);
- if (mediaStorePackage != null) {
- grantRuntimePermissions(mediaStorePackage, STORAGE_PERMISSIONS, true, userId);
- grantRuntimePermissions(mediaStorePackage, MEDIA_AURAL_PERMISSIONS, true, userId);
- grantRuntimePermissions(mediaStorePackage, MEDIA_VISUAL_PERMISSIONS, true, userId);
- grantRuntimePermissions(mediaStorePackage, PHONE_PERMISSIONS, true, userId);
- }
+ grantSystemFixedPermissionsToSystemPackage(
+ getDefaultProviderAuthorityPackage(MediaStore.AUTHORITY, userId), userId,
+ STORAGE_PERMISSIONS, MEDIA_AURAL_PERMISSIONS, MEDIA_VISUAL_PERMISSIONS,
+ PHONE_PERMISSIONS);
// Downloads provider
- PackageParser.Package downloadsPackage = getDefaultProviderAuthorityPackage(
- "downloads", userId);
- if (downloadsPackage != null) {
- grantRuntimePermissions(downloadsPackage, STORAGE_PERMISSIONS, true, userId);
- }
+ grantSystemFixedPermissionsToSystemPackage(
+ getDefaultProviderAuthorityPackage("downloads", userId), userId,
+ STORAGE_PERMISSIONS);
// Downloads UI
- Intent downloadsUiIntent = new Intent(DownloadManager.ACTION_VIEW_DOWNLOADS);
- PackageParser.Package downloadsUiPackage = getDefaultSystemHandlerActivityPackage(
- downloadsUiIntent, userId);
- if (downloadsUiPackage != null
- && doesPackageSupportRuntimePermissions(downloadsUiPackage)) {
- grantRuntimePermissions(downloadsUiPackage, STORAGE_PERMISSIONS, true, userId);
- }
+ grantSystemFixedPermissionsToSystemPackage(
+ getDefaultSystemHandlerActivityPackage(
+ DownloadManager.ACTION_VIEW_DOWNLOADS, userId),
+ userId, STORAGE_PERMISSIONS);
// Storage provider
- PackageParser.Package storagePackage = getDefaultProviderAuthorityPackage(
- "com.android.externalstorage.documents", userId);
- if (storagePackage != null) {
- grantRuntimePermissions(storagePackage, STORAGE_PERMISSIONS, true, userId);
- }
+ grantSystemFixedPermissionsToSystemPackage(
+ getDefaultProviderAuthorityPackage("com.android.externalstorage.documents", userId),
+ userId, STORAGE_PERMISSIONS);
// CertInstaller
- Intent certInstallerIntent = new Intent(Credentials.INSTALL_ACTION);
- PackageParser.Package certInstallerPackage = getDefaultSystemHandlerActivityPackage(
- certInstallerIntent, userId);
- if (certInstallerPackage != null
- && doesPackageSupportRuntimePermissions(certInstallerPackage)) {
- grantRuntimePermissions(certInstallerPackage, STORAGE_PERMISSIONS, true, userId);
- }
+ grantSystemFixedPermissionsToSystemPackage(
+ getDefaultSystemHandlerActivityPackage(Credentials.INSTALL_ACTION, userId), userId,
+ STORAGE_PERMISSIONS);
// Dialer
if (dialerAppPackageNames == null) {
- Intent dialerIntent = new Intent(Intent.ACTION_DIAL);
- PackageParser.Package dialerPackage = getDefaultSystemHandlerActivityPackage(
- dialerIntent, userId);
- if (dialerPackage != null) {
- grantDefaultPermissionsToDefaultSystemDialerApp(dialerPackage, userId);
- }
+ String dialerPackage =
+ getDefaultSystemHandlerActivityPackage(Intent.ACTION_DIAL, userId);
+ grantDefaultPermissionsToDefaultSystemDialerApp(dialerPackage, userId);
} else {
for (String dialerAppPackageName : dialerAppPackageNames) {
- PackageParser.Package dialerPackage = getSystemPackage(dialerAppPackageName);
- if (dialerPackage != null) {
- grantDefaultPermissionsToDefaultSystemDialerApp(dialerPackage, userId);
- }
+ grantDefaultPermissionsToDefaultSystemDialerApp(dialerAppPackageName, userId);
}
}
// Sim call manager
if (simCallManagerPackageNames != null) {
for (String simCallManagerPackageName : simCallManagerPackageNames) {
- PackageParser.Package simCallManagerPackage =
- getSystemPackage(simCallManagerPackageName);
- if (simCallManagerPackage != null) {
- grantDefaultPermissionsToDefaultSimCallManager(simCallManagerPackage,
- userId);
- }
+ grantDefaultPermissionsToDefaultSystemSimCallManager(
+ simCallManagerPackageName, userId);
}
}
// Use Open Wifi
if (useOpenWifiAppPackageNames != null) {
for (String useOpenWifiPackageName : useOpenWifiAppPackageNames) {
- PackageParser.Package useOpenWifiPackage =
- getSystemPackage(useOpenWifiPackageName);
- if (useOpenWifiPackage != null) {
- grantDefaultPermissionsToDefaultSystemUseOpenWifiApp(useOpenWifiPackage,
- userId);
- }
+ grantDefaultPermissionsToDefaultSystemUseOpenWifiApp(
+ useOpenWifiPackageName, userId);
}
}
// SMS
if (smsAppPackageNames == null) {
- Intent smsIntent = new Intent(Intent.ACTION_MAIN);
- smsIntent.addCategory(Intent.CATEGORY_APP_MESSAGING);
- PackageParser.Package smsPackage = getDefaultSystemHandlerActivityPackage(
- smsIntent, userId);
- if (smsPackage != null) {
- grantDefaultPermissionsToDefaultSystemSmsApp(smsPackage, userId);
- }
+ String smsPackage = getDefaultSystemHandlerActivityPackageForCategory(
+ Intent.CATEGORY_APP_MESSAGING, userId);
+ grantDefaultPermissionsToDefaultSystemSmsApp(smsPackage, userId);
} else {
- for (String smsPackageName : smsAppPackageNames) {
- PackageParser.Package smsPackage = getSystemPackage(smsPackageName);
- if (smsPackage != null) {
- grantDefaultPermissionsToDefaultSystemSmsApp(smsPackage, userId);
- }
+ for (String smsPackage : smsAppPackageNames) {
+ grantDefaultPermissionsToDefaultSystemSmsApp(smsPackage, userId);
}
}
// Cell Broadcast Receiver
- Intent cbrIntent = new Intent(Intents.SMS_CB_RECEIVED_ACTION);
- PackageParser.Package cbrPackage =
- getDefaultSystemHandlerActivityPackage(cbrIntent, userId);
- if (cbrPackage != null && doesPackageSupportRuntimePermissions(cbrPackage)) {
- grantRuntimePermissions(cbrPackage, SMS_PERMISSIONS, userId);
- }
+ grantPermissionsToSystemPackage(
+ getDefaultSystemHandlerActivityPackage(Intents.SMS_CB_RECEIVED_ACTION, userId),
+ userId, SMS_PERMISSIONS);
// Carrier Provisioning Service
- Intent carrierProvIntent = new Intent(Intents.SMS_CARRIER_PROVISION_ACTION);
- PackageParser.Package carrierProvPackage =
- getDefaultSystemHandlerServicePackage(carrierProvIntent, userId);
- if (carrierProvPackage != null
- && doesPackageSupportRuntimePermissions(carrierProvPackage)) {
- grantRuntimePermissions(carrierProvPackage, SMS_PERMISSIONS, false, userId);
- }
+ grantPermissionsToSystemPackage(
+ getDefaultSystemHandlerServicePackage(Intents.SMS_CARRIER_PROVISION_ACTION, userId),
+ userId, SMS_PERMISSIONS);
// Calendar
- Intent calendarIntent = new Intent(Intent.ACTION_MAIN);
- calendarIntent.addCategory(Intent.CATEGORY_APP_CALENDAR);
- PackageParser.Package calendarPackage = getDefaultSystemHandlerActivityPackage(
- calendarIntent, userId);
- if (calendarPackage != null
- && doesPackageSupportRuntimePermissions(calendarPackage)) {
- grantRuntimePermissions(calendarPackage, CALENDAR_PERMISSIONS, userId);
- grantRuntimePermissions(calendarPackage, CONTACTS_PERMISSIONS, userId);
- }
+ grantPermissionsToSystemPackage(
+ getDefaultSystemHandlerActivityPackageForCategory(
+ Intent.CATEGORY_APP_CALENDAR, userId),
+ userId, CALENDAR_PERMISSIONS, CONTACTS_PERMISSIONS);
// Calendar provider
- PackageParser.Package calendarProviderPackage = getDefaultProviderAuthorityPackage(
- CalendarContract.AUTHORITY, userId);
- if (calendarProviderPackage != null) {
- grantRuntimePermissions(calendarProviderPackage, CONTACTS_PERMISSIONS, userId);
- grantRuntimePermissions(calendarProviderPackage, CALENDAR_PERMISSIONS,
- true, userId);
- grantRuntimePermissions(calendarProviderPackage, STORAGE_PERMISSIONS, userId);
- }
+ String calendarProvider =
+ getDefaultProviderAuthorityPackage(CalendarContract.AUTHORITY, userId);
+ grantPermissionsToSystemPackage(calendarProvider, userId,
+ CONTACTS_PERMISSIONS, STORAGE_PERMISSIONS);
+ grantSystemFixedPermissionsToSystemPackage(calendarProvider, userId, CALENDAR_PERMISSIONS);
// Calendar provider sync adapters
- List<PackageParser.Package> calendarSyncAdapters = getHeadlessSyncAdapterPackages(
- calendarSyncAdapterPackages, userId);
- final int calendarSyncAdapterCount = calendarSyncAdapters.size();
- for (int i = 0; i < calendarSyncAdapterCount; i++) {
- PackageParser.Package calendarSyncAdapter = calendarSyncAdapters.get(i);
- if (doesPackageSupportRuntimePermissions(calendarSyncAdapter)) {
- grantRuntimePermissions(calendarSyncAdapter, CALENDAR_PERMISSIONS, userId);
- }
- }
+ grantPermissionToEachSystemPackage(
+ getHeadlessSyncAdapterPackages(calendarSyncAdapterPackages, userId),
+ userId, CALENDAR_PERMISSIONS);
// Contacts
- Intent contactsIntent = new Intent(Intent.ACTION_MAIN);
- contactsIntent.addCategory(Intent.CATEGORY_APP_CONTACTS);
- PackageParser.Package contactsPackage = getDefaultSystemHandlerActivityPackage(
- contactsIntent, userId);
- if (contactsPackage != null
- && doesPackageSupportRuntimePermissions(contactsPackage)) {
- grantRuntimePermissions(contactsPackage, CONTACTS_PERMISSIONS, userId);
- grantRuntimePermissions(contactsPackage, PHONE_PERMISSIONS, userId);
- }
+ grantPermissionsToSystemPackage(
+ getDefaultSystemHandlerActivityPackageForCategory(
+ Intent.CATEGORY_APP_CONTACTS, userId),
+ userId, CONTACTS_PERMISSIONS, PHONE_PERMISSIONS);
// Contacts provider sync adapters
- List<PackageParser.Package> contactsSyncAdapters = getHeadlessSyncAdapterPackages(
- contactsSyncAdapterPackages, userId);
- final int contactsSyncAdapterCount = contactsSyncAdapters.size();
- for (int i = 0; i < contactsSyncAdapterCount; i++) {
- PackageParser.Package contactsSyncAdapter = contactsSyncAdapters.get(i);
- if (doesPackageSupportRuntimePermissions(contactsSyncAdapter)) {
- grantRuntimePermissions(contactsSyncAdapter, CONTACTS_PERMISSIONS, userId);
- }
- }
+ grantPermissionToEachSystemPackage(
+ getHeadlessSyncAdapterPackages(contactsSyncAdapterPackages, userId),
+ userId, CONTACTS_PERMISSIONS);
// Contacts provider
- PackageParser.Package contactsProviderPackage = getDefaultProviderAuthorityPackage(
- ContactsContract.AUTHORITY, userId);
- if (contactsProviderPackage != null) {
- grantRuntimePermissions(contactsProviderPackage, CONTACTS_PERMISSIONS,
- true, userId);
- grantRuntimePermissions(contactsProviderPackage, PHONE_PERMISSIONS,
- true, userId);
- grantRuntimePermissions(contactsProviderPackage, STORAGE_PERMISSIONS, userId);
- }
+ String contactsProviderPackage =
+ getDefaultProviderAuthorityPackage(ContactsContract.AUTHORITY, userId);
+ grantSystemFixedPermissionsToSystemPackage(contactsProviderPackage, userId,
+ CONTACTS_PERMISSIONS, PHONE_PERMISSIONS);
+ grantPermissionsToSystemPackage(contactsProviderPackage, userId, STORAGE_PERMISSIONS);
// Device provisioning
- Intent deviceProvisionIntent = new Intent(
- DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE);
- PackageParser.Package deviceProvisionPackage =
- getDefaultSystemHandlerActivityPackage(deviceProvisionIntent, userId);
- if (deviceProvisionPackage != null
- && doesPackageSupportRuntimePermissions(deviceProvisionPackage)) {
- grantRuntimePermissions(deviceProvisionPackage, CONTACTS_PERMISSIONS, userId);
- }
+ grantPermissionsToSystemPackage(
+ getDefaultSystemHandlerActivityPackage(
+ DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, userId),
+ userId, CONTACTS_PERMISSIONS);
// Maps
- Intent mapsIntent = new Intent(Intent.ACTION_MAIN);
- mapsIntent.addCategory(Intent.CATEGORY_APP_MAPS);
- PackageParser.Package mapsPackage = getDefaultSystemHandlerActivityPackage(
- mapsIntent, userId);
- if (mapsPackage != null
- && doesPackageSupportRuntimePermissions(mapsPackage)) {
- grantRuntimePermissions(mapsPackage, LOCATION_PERMISSIONS, userId);
- }
+ grantPermissionsToSystemPackage(
+ getDefaultSystemHandlerActivityPackageForCategory(Intent.CATEGORY_APP_MAPS, userId),
+ userId, LOCATION_PERMISSIONS);
// Gallery
- Intent galleryIntent = new Intent(Intent.ACTION_MAIN);
- galleryIntent.addCategory(Intent.CATEGORY_APP_GALLERY);
- PackageParser.Package galleryPackage = getDefaultSystemHandlerActivityPackage(
- galleryIntent, userId);
- if (galleryPackage != null
- && doesPackageSupportRuntimePermissions(galleryPackage)) {
- grantRuntimePermissions(galleryPackage, STORAGE_PERMISSIONS, userId);
- grantRuntimePermissions(galleryPackage, MEDIA_VISUAL_PERMISSIONS, userId);
- }
+ grantPermissionsToSystemPackage(
+ getDefaultSystemHandlerActivityPackageForCategory(
+ Intent.CATEGORY_APP_GALLERY, userId),
+ userId, STORAGE_PERMISSIONS, MEDIA_VISUAL_PERMISSIONS);
// Email
- Intent emailIntent = new Intent(Intent.ACTION_MAIN);
- emailIntent.addCategory(Intent.CATEGORY_APP_EMAIL);
- PackageParser.Package emailPackage = getDefaultSystemHandlerActivityPackage(
- emailIntent, userId);
- if (emailPackage != null
- && doesPackageSupportRuntimePermissions(emailPackage)) {
- grantRuntimePermissions(emailPackage, CONTACTS_PERMISSIONS, userId);
- grantRuntimePermissions(emailPackage, CALENDAR_PERMISSIONS, userId);
- }
+ grantPermissionsToSystemPackage(
+ getDefaultSystemHandlerActivityPackageForCategory(
+ Intent.CATEGORY_APP_EMAIL, userId),
+ userId, CONTACTS_PERMISSIONS, CALENDAR_PERMISSIONS);
// Browser
- PackageParser.Package browserPackage = null;
- String defaultBrowserPackage = mServiceInternal.getKnownPackageName(
- PackageManagerInternal.PACKAGE_BROWSER, userId);
- if (defaultBrowserPackage != null) {
- browserPackage = getPackage(defaultBrowserPackage);
- }
+ String browserPackage = getKnownPackage(PackageManagerInternal.PACKAGE_BROWSER, userId);
if (browserPackage == null) {
- Intent browserIntent = new Intent(Intent.ACTION_MAIN);
- browserIntent.addCategory(Intent.CATEGORY_APP_BROWSER);
- browserPackage = getDefaultSystemHandlerActivityPackage(
- browserIntent, userId);
+ browserPackage = getDefaultSystemHandlerActivityPackageForCategory(
+ Intent.CATEGORY_APP_BROWSER, userId);
+ if (!isSystemPackage(browserPackage)) {
+ browserPackage = null;
+ }
}
- if (browserPackage != null
- && doesPackageSupportRuntimePermissions(browserPackage)) {
- grantRuntimePermissions(browserPackage, LOCATION_PERMISSIONS, userId);
- }
+ grantRuntimePermissionsToPackage(browserPackage, userId,
+ false /* systemFixed */, false /* ignoreSystemPackage */,
+ LOCATION_PERMISSIONS);
// Voice interaction
if (voiceInteractPackageNames != null) {
for (String voiceInteractPackageName : voiceInteractPackageNames) {
- PackageParser.Package voiceInteractPackage = getSystemPackage(
- voiceInteractPackageName);
- if (voiceInteractPackage != null
- && doesPackageSupportRuntimePermissions(voiceInteractPackage)) {
- grantRuntimePermissions(voiceInteractPackage,
- CONTACTS_PERMISSIONS, userId);
- grantRuntimePermissions(voiceInteractPackage,
- CALENDAR_PERMISSIONS, userId);
- grantRuntimePermissions(voiceInteractPackage,
- MICROPHONE_PERMISSIONS, userId);
- grantRuntimePermissions(voiceInteractPackage,
- PHONE_PERMISSIONS, userId);
- grantRuntimePermissions(voiceInteractPackage,
- SMS_PERMISSIONS, userId);
- grantRuntimePermissions(voiceInteractPackage,
- LOCATION_PERMISSIONS, userId);
- }
+ grantPermissionsToSystemPackage(voiceInteractPackageName, userId,
+ CONTACTS_PERMISSIONS, CALENDAR_PERMISSIONS, MICROPHONE_PERMISSIONS,
+ PHONE_PERMISSIONS, SMS_PERMISSIONS, LOCATION_PERMISSIONS);
}
}
if (ActivityManager.isLowRamDeviceStatic()) {
// Allow voice search on low-ram devices
- Intent globalSearchIntent = new Intent("android.search.action.GLOBAL_SEARCH");
- PackageParser.Package globalSearchPickerPackage =
- getDefaultSystemHandlerActivityPackage(globalSearchIntent, userId);
-
- if (globalSearchPickerPackage != null
- && doesPackageSupportRuntimePermissions(globalSearchPickerPackage)) {
- grantRuntimePermissions(globalSearchPickerPackage,
- MICROPHONE_PERMISSIONS, false, userId);
- grantRuntimePermissions(globalSearchPickerPackage,
- LOCATION_PERMISSIONS, false, userId);
- }
+ grantPermissionsToSystemPackage(
+ getDefaultSystemHandlerActivityPackage(
+ SearchManager.INTENT_ACTION_GLOBAL_SEARCH, userId),
+ userId, MICROPHONE_PERMISSIONS, LOCATION_PERMISSIONS);
}
// Voice recognition
- Intent voiceRecoIntent = new Intent("android.speech.RecognitionService");
- voiceRecoIntent.addCategory(Intent.CATEGORY_DEFAULT);
- PackageParser.Package voiceRecoPackage = getDefaultSystemHandlerServicePackage(
- voiceRecoIntent, userId);
- if (voiceRecoPackage != null
- && doesPackageSupportRuntimePermissions(voiceRecoPackage)) {
- grantRuntimePermissions(voiceRecoPackage, MICROPHONE_PERMISSIONS, userId);
- }
+ Intent voiceRecoIntent = new Intent(RecognitionService.SERVICE_INTERFACE)
+ .addCategory(Intent.CATEGORY_DEFAULT);
+ grantPermissionsToSystemPackage(
+ getDefaultSystemHandlerServicePackage(voiceRecoIntent, userId), userId,
+ MICROPHONE_PERMISSIONS);
// Location
if (locationPackageNames != null) {
for (String packageName : locationPackageNames) {
- PackageParser.Package locationPackage = getSystemPackage(packageName);
- if (locationPackage != null
- && doesPackageSupportRuntimePermissions(locationPackage)) {
- grantRuntimePermissions(locationPackage, CONTACTS_PERMISSIONS, userId);
- grantRuntimePermissions(locationPackage, CALENDAR_PERMISSIONS, userId);
- grantRuntimePermissions(locationPackage, MICROPHONE_PERMISSIONS, userId);
- grantRuntimePermissions(locationPackage, PHONE_PERMISSIONS, userId);
- grantRuntimePermissions(locationPackage, SMS_PERMISSIONS, userId);
- grantRuntimePermissions(locationPackage, LOCATION_PERMISSIONS,
- true, userId);
- grantRuntimePermissions(locationPackage, CAMERA_PERMISSIONS, userId);
- grantRuntimePermissions(locationPackage, SENSORS_PERMISSIONS, userId);
- grantRuntimePermissions(locationPackage, STORAGE_PERMISSIONS, userId);
- }
+ grantPermissionsToSystemPackage(packageName, userId,
+ CONTACTS_PERMISSIONS, CALENDAR_PERMISSIONS, MICROPHONE_PERMISSIONS,
+ PHONE_PERMISSIONS, SMS_PERMISSIONS, CAMERA_PERMISSIONS,
+ SENSORS_PERMISSIONS, STORAGE_PERMISSIONS);
+ grantSystemFixedPermissionsToSystemPackage(packageName, userId,
+ LOCATION_PERMISSIONS);
}
}
// Music
- Intent musicIntent = new Intent(Intent.ACTION_VIEW);
- musicIntent.addCategory(Intent.CATEGORY_DEFAULT);
- musicIntent.setDataAndType(Uri.fromFile(new File("foo.mp3")),
- AUDIO_MIME_TYPE);
- PackageParser.Package musicPackage = getDefaultSystemHandlerActivityPackage(
- musicIntent, userId);
- if (musicPackage != null
- && doesPackageSupportRuntimePermissions(musicPackage)) {
- grantRuntimePermissions(musicPackage, STORAGE_PERMISSIONS, userId);
- grantRuntimePermissions(musicPackage, MEDIA_AURAL_PERMISSIONS, userId);
- }
+ Intent musicIntent = new Intent(Intent.ACTION_VIEW)
+ .addCategory(Intent.CATEGORY_DEFAULT)
+ .setDataAndType(Uri.fromFile(new File("foo.mp3")), AUDIO_MIME_TYPE);
+ grantPermissionsToSystemPackage(
+ getDefaultSystemHandlerActivityPackage(musicIntent, userId), userId,
+ STORAGE_PERMISSIONS, MEDIA_AURAL_PERMISSIONS);
// Home
- Intent homeIntent = new Intent(Intent.ACTION_MAIN);
- homeIntent.addCategory(Intent.CATEGORY_HOME);
- homeIntent.addCategory(Intent.CATEGORY_LAUNCHER_APP);
- PackageParser.Package homePackage = getDefaultSystemHandlerActivityPackage(
- homeIntent, userId);
- if (homePackage != null
- && doesPackageSupportRuntimePermissions(homePackage)) {
- grantRuntimePermissions(homePackage, LOCATION_PERMISSIONS, false, userId);
- }
+ Intent homeIntent = new Intent(Intent.ACTION_MAIN)
+ .addCategory(Intent.CATEGORY_HOME)
+ .addCategory(Intent.CATEGORY_LAUNCHER_APP);
+ grantPermissionsToSystemPackage(
+ getDefaultSystemHandlerActivityPackage(homeIntent, userId), userId,
+ LOCATION_PERMISSIONS);
// Watches
if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH, 0)) {
// Home application on watches
- Intent wearHomeIntent = new Intent(Intent.ACTION_MAIN);
- wearHomeIntent.addCategory(Intent.CATEGORY_HOME_MAIN);
- PackageParser.Package wearHomePackage = getDefaultSystemHandlerActivityPackage(
- wearHomeIntent, userId);
-
- if (wearHomePackage != null
- && doesPackageSupportRuntimePermissions(wearHomePackage)) {
- grantRuntimePermissions(wearHomePackage, CONTACTS_PERMISSIONS, false,
- userId);
- grantRuntimePermissions(wearHomePackage, PHONE_PERMISSIONS, true, userId);
- grantRuntimePermissions(wearHomePackage, MICROPHONE_PERMISSIONS, false,
- userId);
- grantRuntimePermissions(wearHomePackage, LOCATION_PERMISSIONS, false,
- userId);
- }
+ String wearPackage = getDefaultSystemHandlerActivityPackageForCategory(
+ Intent.CATEGORY_HOME_MAIN, userId);
+ grantPermissionsToSystemPackage(wearPackage, userId,
+ CONTACTS_PERMISSIONS, MICROPHONE_PERMISSIONS, LOCATION_PERMISSIONS);
+ grantSystemFixedPermissionsToSystemPackage(wearPackage, userId, PHONE_PERMISSIONS);
// Fitness tracking on watches
- Intent trackIntent = new Intent(ACTION_TRACK);
- PackageParser.Package trackPackage = getDefaultSystemHandlerActivityPackage(
- trackIntent, userId);
- if (trackPackage != null
- && doesPackageSupportRuntimePermissions(trackPackage)) {
- grantRuntimePermissions(trackPackage, SENSORS_PERMISSIONS, false, userId);
- grantRuntimePermissions(trackPackage, LOCATION_PERMISSIONS, false, userId);
- }
+ grantPermissionsToSystemPackage(
+ getDefaultSystemHandlerActivityPackage(ACTION_TRACK, userId), userId,
+ SENSORS_PERMISSIONS, LOCATION_PERMISSIONS);
}
// Print Spooler
- PackageParser.Package printSpoolerPackage = getSystemPackage(
- PrintManager.PRINT_SPOOLER_PACKAGE_NAME);
- if (printSpoolerPackage != null
- && doesPackageSupportRuntimePermissions(printSpoolerPackage)) {
- grantRuntimePermissions(printSpoolerPackage, LOCATION_PERMISSIONS, true, userId);
- }
+ grantSystemFixedPermissionsToSystemPackage(PrintManager.PRINT_SPOOLER_PACKAGE_NAME, userId,
+ LOCATION_PERMISSIONS);
// EmergencyInfo
- Intent emergencyInfoIntent = new Intent(TelephonyManager.ACTION_EMERGENCY_ASSISTANCE);
- PackageParser.Package emergencyInfoPckg = getDefaultSystemHandlerActivityPackage(
- emergencyInfoIntent, userId);
- if (emergencyInfoPckg != null
- && doesPackageSupportRuntimePermissions(emergencyInfoPckg)) {
- grantRuntimePermissions(emergencyInfoPckg, CONTACTS_PERMISSIONS, true, userId);
- grantRuntimePermissions(emergencyInfoPckg, PHONE_PERMISSIONS, true, userId);
- }
+ grantSystemFixedPermissionsToSystemPackage(
+ getDefaultSystemHandlerActivityPackage(
+ TelephonyManager.ACTION_EMERGENCY_ASSISTANCE, userId),
+ userId, CONTACTS_PERMISSIONS, PHONE_PERMISSIONS);
// NFC Tag viewer
- Intent nfcTagIntent = new Intent(Intent.ACTION_VIEW);
- nfcTagIntent.setType("vnd.android.cursor.item/ndef_msg");
- PackageParser.Package nfcTagPkg = getDefaultSystemHandlerActivityPackage(
- nfcTagIntent, userId);
- if (nfcTagPkg != null
- && doesPackageSupportRuntimePermissions(nfcTagPkg)) {
- grantRuntimePermissions(nfcTagPkg, CONTACTS_PERMISSIONS, false, userId);
- grantRuntimePermissions(nfcTagPkg, PHONE_PERMISSIONS, false, userId);
- }
+ Intent nfcTagIntent = new Intent(Intent.ACTION_VIEW)
+ .setType("vnd.android.cursor.item/ndef_msg");
+ grantPermissionsToSystemPackage(
+ getDefaultSystemHandlerActivityPackage(nfcTagIntent, userId), userId,
+ CONTACTS_PERMISSIONS, PHONE_PERMISSIONS);
// Storage Manager
- Intent storageManagerIntent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
- PackageParser.Package storageManagerPckg = getDefaultSystemHandlerActivityPackage(
- storageManagerIntent, userId);
- if (storageManagerPckg != null
- && doesPackageSupportRuntimePermissions(storageManagerPckg)) {
- grantRuntimePermissions(storageManagerPckg, STORAGE_PERMISSIONS, true, userId);
- }
+ grantSystemFixedPermissionsToSystemPackage(
+ getDefaultSystemHandlerActivityPackage(
+ StorageManager.ACTION_MANAGE_STORAGE, userId),
+ userId, STORAGE_PERMISSIONS);
// Companion devices
- PackageParser.Package companionDeviceDiscoveryPackage = getSystemPackage(
- CompanionDeviceManager.COMPANION_DEVICE_DISCOVERY_PACKAGE_NAME);
- if (companionDeviceDiscoveryPackage != null
- && doesPackageSupportRuntimePermissions(companionDeviceDiscoveryPackage)) {
- grantRuntimePermissions(companionDeviceDiscoveryPackage,
- LOCATION_PERMISSIONS, true, userId);
- }
+ grantSystemFixedPermissionsToSystemPackage(
+ CompanionDeviceManager.COMPANION_DEVICE_DISCOVERY_PACKAGE_NAME, userId,
+ LOCATION_PERMISSIONS);
// Ringtone Picker
- Intent ringtonePickerIntent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
- PackageParser.Package ringtonePickerPackage =
- getDefaultSystemHandlerActivityPackage(ringtonePickerIntent, userId);
- if (ringtonePickerPackage != null
- && doesPackageSupportRuntimePermissions(ringtonePickerPackage)) {
- grantRuntimePermissions(ringtonePickerPackage,
- STORAGE_PERMISSIONS, true, userId);
- }
+ grantSystemFixedPermissionsToSystemPackage(
+ getDefaultSystemHandlerActivityPackage(
+ RingtoneManager.ACTION_RINGTONE_PICKER, userId),
+ userId, STORAGE_PERMISSIONS);
// TextClassifier Service
String textClassifierPackageName =
mContext.getPackageManager().getSystemTextClassifierPackageName();
if (!TextUtils.isEmpty(textClassifierPackageName)) {
- PackageParser.Package textClassifierPackage =
- getSystemPackage(textClassifierPackageName);
- if (textClassifierPackage != null
- && doesPackageSupportRuntimePermissions(textClassifierPackage)) {
- grantRuntimePermissions(textClassifierPackage, PHONE_PERMISSIONS, false, userId);
- grantRuntimePermissions(textClassifierPackage, SMS_PERMISSIONS, false, userId);
- grantRuntimePermissions(textClassifierPackage, CALENDAR_PERMISSIONS, false, userId);
- grantRuntimePermissions(textClassifierPackage, LOCATION_PERMISSIONS, false, userId);
- grantRuntimePermissions(textClassifierPackage, CONTACTS_PERMISSIONS, false, userId);
- }
+ grantPermissionsToSystemPackage(textClassifierPackageName, userId,
+ PHONE_PERMISSIONS, SMS_PERMISSIONS, CALENDAR_PERMISSIONS,
+ LOCATION_PERMISSIONS, CONTACTS_PERMISSIONS);
}
// There is no real "marker" interface to identify the shared storage backup, it is
// hardcoded in BackupManagerService.SHARED_BACKUP_AGENT_PACKAGE.
- PackageParser.Package sharedStorageBackupPackage = getSystemPackage(
- "com.android.sharedstoragebackup");
- if (sharedStorageBackupPackage != null) {
- grantRuntimePermissions(sharedStorageBackupPackage, STORAGE_PERMISSIONS, true, userId);
- }
+ grantSystemFixedPermissionsToSystemPackage("com.android.sharedstoragebackup", userId,
+ STORAGE_PERMISSIONS);
if (mPermissionGrantedCallback != null) {
mPermissionGrantedCallback.onDefaultRuntimePermissionsGranted(userId);
}
}
- private void grantDefaultPermissionsToDefaultSystemDialerApp(
- PackageParser.Package dialerPackage, int userId) {
- if (doesPackageSupportRuntimePermissions(dialerPackage)) {
- boolean isPhonePermFixed =
- mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH, 0);
- grantRuntimePermissions(
- dialerPackage, PHONE_PERMISSIONS, isPhonePermFixed, userId);
- grantRuntimePermissions(dialerPackage, CONTACTS_PERMISSIONS, userId);
- grantRuntimePermissions(dialerPackage, SMS_PERMISSIONS, userId);
- grantRuntimePermissions(dialerPackage, MICROPHONE_PERMISSIONS, userId);
- grantRuntimePermissions(dialerPackage, CAMERA_PERMISSIONS, userId);
+ private String getDefaultSystemHandlerActivityPackageForCategory(String category, int userId) {
+ return getDefaultSystemHandlerActivityPackage(
+ new Intent(Intent.ACTION_MAIN).addCategory(category), userId);
+ }
+
+ @SafeVarargs
+ private final void grantPermissionToEachSystemPackage(
+ ArrayList<String> packages, int userId, Set<String>... permissions) {
+ if (packages == null) return;
+ final int count = packages.size();
+ for (int i = 0; i < count; i++) {
+ grantPermissionsToSystemPackage(packages.get(i), userId, permissions);
}
}
- private void grantDefaultPermissionsToDefaultSystemSmsApp(
- PackageParser.Package smsPackage, int userId) {
- if (doesPackageSupportRuntimePermissions(smsPackage)) {
- grantRuntimePermissions(smsPackage, PHONE_PERMISSIONS, userId);
- grantRuntimePermissions(smsPackage, CONTACTS_PERMISSIONS, userId);
- grantRuntimePermissions(smsPackage, SMS_PERMISSIONS, userId);
- grantRuntimePermissions(smsPackage, STORAGE_PERMISSIONS, userId);
- grantRuntimePermissions(smsPackage, MICROPHONE_PERMISSIONS, userId);
- grantRuntimePermissions(smsPackage, CAMERA_PERMISSIONS, userId);
+ private String getKnownPackage(int knownPkgId, int userId) {
+ return mServiceInternal.getKnownPackageName(knownPkgId, userId);
+ }
+
+ private void grantDefaultPermissionsToDefaultSystemDialerApp(
+ String dialerPackage, int userId) {
+ if (dialerPackage == null) {
+ return;
}
+ boolean isPhonePermFixed =
+ mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH, 0);
+ if (isPhonePermFixed) {
+ grantSystemFixedPermissionsToSystemPackage(dialerPackage, userId, PHONE_PERMISSIONS);
+ } else {
+ grantPermissionsToSystemPackage(dialerPackage, userId, PHONE_PERMISSIONS);
+ }
+ grantPermissionsToSystemPackage(dialerPackage, userId,
+ CONTACTS_PERMISSIONS, SMS_PERMISSIONS, MICROPHONE_PERMISSIONS, CAMERA_PERMISSIONS);
+ }
+
+ private void grantDefaultPermissionsToDefaultSystemSmsApp(String smsPackage, int userId) {
+ grantPermissionsToSystemPackage(smsPackage, userId,
+ PHONE_PERMISSIONS, CONTACTS_PERMISSIONS, SMS_PERMISSIONS,
+ STORAGE_PERMISSIONS, MICROPHONE_PERMISSIONS, CAMERA_PERMISSIONS);
}
private void grantDefaultPermissionsToDefaultSystemUseOpenWifiApp(
- PackageParser.Package useOpenWifiPackage, int userId) {
- if (doesPackageSupportRuntimePermissions(useOpenWifiPackage)) {
- grantRuntimePermissions(useOpenWifiPackage, COARSE_LOCATION_PERMISSIONS, userId);
- }
+ String useOpenWifiPackage, int userId) {
+ grantPermissionsToSystemPackage(
+ useOpenWifiPackage, userId, COARSE_LOCATION_PERMISSIONS);
}
public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) {
Log.i(TAG, "Granting permissions to default sms app for user:" + userId);
- if (packageName == null) {
- return;
- }
- PackageParser.Package smsPackage = getPackage(packageName);
- if (smsPackage != null && doesPackageSupportRuntimePermissions(smsPackage)) {
- grantRuntimePermissions(smsPackage, PHONE_PERMISSIONS, false, true, userId);
- grantRuntimePermissions(smsPackage, CONTACTS_PERMISSIONS, false, true, userId);
- grantRuntimePermissions(smsPackage, SMS_PERMISSIONS, false, true, userId);
- grantRuntimePermissions(smsPackage, STORAGE_PERMISSIONS, false, true, userId);
- grantRuntimePermissions(smsPackage, MICROPHONE_PERMISSIONS, false, true, userId);
- grantRuntimePermissions(smsPackage, CAMERA_PERMISSIONS, false, true, userId);
- }
+ grantIgnoringSystemPackage(packageName, userId,
+ PHONE_PERMISSIONS, CONTACTS_PERMISSIONS, SMS_PERMISSIONS, STORAGE_PERMISSIONS,
+ MICROPHONE_PERMISSIONS, CAMERA_PERMISSIONS);
}
public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) {
+ mServiceInternal.onDefaultDialerAppChanged(packageName, userId);
Log.i(TAG, "Granting permissions to default dialer app for user:" + userId);
- if (packageName == null) {
- return;
- }
- PackageParser.Package dialerPackage = getPackage(packageName);
- if (dialerPackage != null
- && doesPackageSupportRuntimePermissions(dialerPackage)) {
- grantRuntimePermissions(dialerPackage, PHONE_PERMISSIONS, false, true, userId);
- grantRuntimePermissions(dialerPackage, CONTACTS_PERMISSIONS, false, true, userId);
- grantRuntimePermissions(dialerPackage, SMS_PERMISSIONS, false, true, userId);
- grantRuntimePermissions(dialerPackage, MICROPHONE_PERMISSIONS, false, true, userId);
- grantRuntimePermissions(dialerPackage, CAMERA_PERMISSIONS, false, true, userId);
- }
+ grantIgnoringSystemPackage(packageName, userId,
+ PHONE_PERMISSIONS, CONTACTS_PERMISSIONS, SMS_PERMISSIONS,
+ MICROPHONE_PERMISSIONS, CAMERA_PERMISSIONS);
}
public void grantDefaultPermissionsToDefaultUseOpenWifiApp(String packageName, int userId) {
Log.i(TAG, "Granting permissions to default Use Open WiFi app for user:" + userId);
- if (packageName == null) {
- return;
- }
- PackageParser.Package useOpenWifiPackage = getPackage(packageName);
- if (useOpenWifiPackage != null
- && doesPackageSupportRuntimePermissions(useOpenWifiPackage)) {
- grantRuntimePermissions(
- useOpenWifiPackage, COARSE_LOCATION_PERMISSIONS, false, true, userId);
- }
- }
-
- private void grantDefaultPermissionsToDefaultSimCallManager(
- PackageParser.Package simCallManagerPackage, int userId) {
- Log.i(TAG, "Granting permissions to sim call manager for user:" + userId);
- if (doesPackageSupportRuntimePermissions(simCallManagerPackage)) {
- grantRuntimePermissions(simCallManagerPackage, PHONE_PERMISSIONS, userId);
- grantRuntimePermissions(simCallManagerPackage, MICROPHONE_PERMISSIONS, userId);
- }
+ grantIgnoringSystemPackage(packageName, userId, COARSE_LOCATION_PERMISSIONS);
}
public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
if (packageName == null) {
return;
}
- PackageParser.Package simCallManagerPackage = getPackage(packageName);
- if (simCallManagerPackage != null) {
- grantDefaultPermissionsToDefaultSimCallManager(simCallManagerPackage, userId);
+ Log.i(TAG, "Granting permissions to sim call manager for user:" + userId);
+ grantRuntimePermissionsToPackage(packageName, userId, false, false,
+ PHONE_PERMISSIONS, MICROPHONE_PERMISSIONS);
+ }
+
+ private void grantDefaultPermissionsToDefaultSystemSimCallManager(
+ String packageName, int userId) {
+ if (isSystemPackage(packageName)) {
+ grantDefaultPermissionsToDefaultSimCallManager(packageName, userId);
}
}
@@ -976,13 +801,8 @@
return;
}
for (String packageName : packageNames) {
- PackageParser.Package carrierPackage = getSystemPackage(packageName);
- if (carrierPackage != null
- && doesPackageSupportRuntimePermissions(carrierPackage)) {
- grantRuntimePermissions(carrierPackage, PHONE_PERMISSIONS, userId);
- grantRuntimePermissions(carrierPackage, LOCATION_PERMISSIONS, userId);
- grantRuntimePermissions(carrierPackage, SMS_PERMISSIONS, userId);
- }
+ grantPermissionsToSystemPackage(packageName, userId,
+ PHONE_PERMISSIONS, LOCATION_PERMISSIONS, SMS_PERMISSIONS);
}
}
@@ -992,15 +812,9 @@
return;
}
for (String packageName : packageNames) {
- PackageParser.Package imsServicePackage = getSystemPackage(packageName);
- if (imsServicePackage != null
- && doesPackageSupportRuntimePermissions(imsServicePackage)) {
- grantRuntimePermissions(imsServicePackage, PHONE_PERMISSIONS, userId);
- grantRuntimePermissions(imsServicePackage, MICROPHONE_PERMISSIONS, userId);
- grantRuntimePermissions(imsServicePackage, LOCATION_PERMISSIONS, userId);
- grantRuntimePermissions(imsServicePackage, CAMERA_PERMISSIONS, userId);
- grantRuntimePermissions(imsServicePackage, CONTACTS_PERMISSIONS, userId);
- }
+ grantPermissionsToSystemPackage(packageName, userId,
+ PHONE_PERMISSIONS, MICROPHONE_PERMISSIONS, LOCATION_PERMISSIONS,
+ CAMERA_PERMISSIONS, CONTACTS_PERMISSIONS);
}
}
@@ -1011,15 +825,12 @@
return;
}
for (String packageName : packageNames) {
- PackageParser.Package dataServicePackage = getSystemPackage(packageName);
- if (dataServicePackage != null
- && doesPackageSupportRuntimePermissions(dataServicePackage)) {
- // Grant these permissions as system-fixed, so that nobody can accidentally
- // break cellular data.
- grantRuntimePermissions(dataServicePackage, PHONE_PERMISSIONS, true, userId);
- grantRuntimePermissions(dataServicePackage, LOCATION_PERMISSIONS, true, userId);
- }
+ // Grant these permissions as system-fixed, so that nobody can accidentally
+ // break cellular data.
+ grantSystemFixedPermissionsToSystemPackage(packageName, userId,
+ PHONE_PERMISSIONS, LOCATION_PERMISSIONS);
}
+
}
public void revokeDefaultPermissionsFromDisabledTelephonyDataServices(
@@ -1029,25 +840,17 @@
return;
}
for (String packageName : packageNames) {
- PackageParser.Package dataServicePackage = getSystemPackage(packageName);
- if (dataServicePackage != null
- && doesPackageSupportRuntimePermissions(dataServicePackage)) {
- revokeRuntimePermissions(dataServicePackage, PHONE_PERMISSIONS, true, userId);
- revokeRuntimePermissions(dataServicePackage, LOCATION_PERMISSIONS, true, userId);
+ PackageInfo pkg = getSystemPackageInfo(packageName);
+ if (isSystemPackage(pkg) && doesPackageSupportRuntimePermissions(pkg)) {
+ revokeRuntimePermissions(packageName, PHONE_PERMISSIONS, true, userId);
+ revokeRuntimePermissions(packageName, LOCATION_PERMISSIONS, true, userId);
}
}
}
public void grantDefaultPermissionsToActiveLuiApp(String packageName, int userId) {
Log.i(TAG, "Granting permissions to active LUI app for user:" + userId);
- if (packageName == null) {
- return;
- }
- PackageParser.Package luiAppPackage = getSystemPackage(packageName);
- if (luiAppPackage != null
- && doesPackageSupportRuntimePermissions(luiAppPackage)) {
- grantRuntimePermissions(luiAppPackage, CAMERA_PERMISSIONS, true, userId);
- }
+ grantSystemFixedPermissionsToSystemPackage(packageName, userId, CAMERA_PERMISSIONS);
}
public void revokeDefaultPermissionsFromLuiApps(String[] packageNames, int userId) {
@@ -1056,123 +859,116 @@
return;
}
for (String packageName : packageNames) {
- PackageParser.Package luiAppPackage = getSystemPackage(packageName);
- if (luiAppPackage != null
- && doesPackageSupportRuntimePermissions(luiAppPackage)) {
- revokeRuntimePermissions(luiAppPackage, CAMERA_PERMISSIONS, true, userId);
+ PackageInfo pkg = getSystemPackageInfo(packageName);
+ if (isSystemPackage(pkg) && doesPackageSupportRuntimePermissions(pkg)) {
+ revokeRuntimePermissions(packageName, CAMERA_PERMISSIONS, true, userId);
}
}
}
public void grantDefaultPermissionsToDefaultBrowser(String packageName, int userId) {
Log.i(TAG, "Granting permissions to default browser for user:" + userId);
- if (packageName == null) {
- return;
- }
- PackageParser.Package browserPackage = getSystemPackage(packageName);
- if (browserPackage != null
- && doesPackageSupportRuntimePermissions(browserPackage)) {
- grantRuntimePermissions(browserPackage, LOCATION_PERMISSIONS, false, false, userId);
- }
+ grantPermissionsToSystemPackage(packageName, userId, LOCATION_PERMISSIONS);
}
- private PackageParser.Package getDefaultSystemHandlerActivityPackage(
- Intent intent, int userId) {
+ private String getDefaultSystemHandlerActivityPackage(String intentAction, int userId) {
+ return getDefaultSystemHandlerActivityPackage(new Intent(intentAction), userId);
+ }
+
+ private String getDefaultSystemHandlerActivityPackage(Intent intent, int userId) {
ResolveInfo handler = mServiceInternal.resolveIntent(intent,
- intent.resolveType(mContext.getContentResolver()), DEFAULT_FLAGS, userId, false,
- Binder.getCallingUid());
+ intent.resolveType(mContext.getContentResolver()), DEFAULT_INTENT_QUERY_FLAGS,
+ userId, false, Binder.getCallingUid());
if (handler == null || handler.activityInfo == null) {
return null;
}
if (mServiceInternal.isResolveActivityComponent(handler.activityInfo)) {
return null;
}
- return getSystemPackage(handler.activityInfo.packageName);
+ String packageName = handler.activityInfo.packageName;
+ return isSystemPackage(packageName) ? packageName : null;
}
- private PackageParser.Package getDefaultSystemHandlerServicePackage(
+ private String getDefaultSystemHandlerServicePackage(String intentAction, int userId) {
+ return getDefaultSystemHandlerServicePackage(new Intent(intentAction), userId);
+ }
+
+ private String getDefaultSystemHandlerServicePackage(
Intent intent, int userId) {
List<ResolveInfo> handlers = mServiceInternal.queryIntentServices(
- intent, DEFAULT_FLAGS, Binder.getCallingUid(), userId);
+ intent, DEFAULT_INTENT_QUERY_FLAGS, Binder.getCallingUid(), userId);
if (handlers == null) {
return null;
}
final int handlerCount = handlers.size();
for (int i = 0; i < handlerCount; i++) {
ResolveInfo handler = handlers.get(i);
- PackageParser.Package handlerPackage = getSystemPackage(
- handler.serviceInfo.packageName);
- if (handlerPackage != null) {
+ String handlerPackage = handler.serviceInfo.packageName;
+ if (isSystemPackage(handlerPackage)) {
return handlerPackage;
}
}
return null;
}
- private List<PackageParser.Package> getHeadlessSyncAdapterPackages(
+ private ArrayList<String> getHeadlessSyncAdapterPackages(
String[] syncAdapterPackageNames, int userId) {
- List<PackageParser.Package> syncAdapterPackages = new ArrayList<>();
+ ArrayList<String> syncAdapterPackages = new ArrayList<>();
- Intent homeIntent = new Intent(Intent.ACTION_MAIN);
- homeIntent.addCategory(Intent.CATEGORY_LAUNCHER);
+ Intent homeIntent = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_LAUNCHER);
for (String syncAdapterPackageName : syncAdapterPackageNames) {
homeIntent.setPackage(syncAdapterPackageName);
ResolveInfo homeActivity = mServiceInternal.resolveIntent(homeIntent,
- homeIntent.resolveType(mContext.getContentResolver()), DEFAULT_FLAGS,
+ homeIntent.resolveType(mContext.getContentResolver()),
+ DEFAULT_INTENT_QUERY_FLAGS,
userId, false, Binder.getCallingUid());
if (homeActivity != null) {
continue;
}
- PackageParser.Package syncAdapterPackage = getSystemPackage(syncAdapterPackageName);
- if (syncAdapterPackage != null) {
- syncAdapterPackages.add(syncAdapterPackage);
+ if (isSystemPackage(syncAdapterPackageName)) {
+ syncAdapterPackages.add(syncAdapterPackageName);
}
}
return syncAdapterPackages;
}
- private PackageParser.Package getDefaultProviderAuthorityPackage(
- String authority, int userId) {
- ProviderInfo provider =
- mServiceInternal.resolveContentProvider(authority, DEFAULT_FLAGS, userId);
+ private String getDefaultProviderAuthorityPackage(String authority, int userId) {
+ ProviderInfo provider = mServiceInternal.resolveContentProvider(
+ authority, DEFAULT_INTENT_QUERY_FLAGS, userId);
if (provider != null) {
- return getSystemPackage(provider.packageName);
+ return provider.packageName;
}
return null;
}
- private PackageParser.Package getPackage(String packageName) {
- return mServiceInternal.getPackage(packageName);
+ private boolean isSystemPackage(String packageName) {
+ return isSystemPackage(getPackageInfo(packageName));
}
- private PackageParser.Package getSystemPackage(String packageName) {
- PackageParser.Package pkg = getPackage(packageName);
- if (pkg != null && pkg.isSystem()) {
- return !isSysComponentOrPersistentPlatformSignedPrivApp(pkg) ? pkg : null;
+ private boolean isSystemPackage(PackageInfo pkg) {
+ if (pkg == null) {
+ return false;
}
- return null;
+ return pkg.applicationInfo.isSystemApp()
+ && !isSysComponentOrPersistentPlatformSignedPrivApp(pkg);
}
- private void grantRuntimePermissions(PackageParser.Package pkg, Set<String> permissions,
- int userId) {
- grantRuntimePermissions(pkg, permissions, false, false, userId);
- }
-
- private void grantRuntimePermissions(PackageParser.Package pkg, Set<String> permissions,
+ private void grantRuntimePermissions(PackageInfo pkg, Set<String> permissions,
boolean systemFixed, int userId) {
grantRuntimePermissions(pkg, permissions, systemFixed, false, userId);
}
- private void revokeRuntimePermissions(PackageParser.Package pkg, Set<String> permissions,
+ private void revokeRuntimePermissions(String packageName, Set<String> permissions,
boolean systemFixed, int userId) {
- if (pkg.requestedPermissions.isEmpty()) {
+ PackageInfo pkg = getSystemPackageInfo(packageName);
+ if (ArrayUtils.isEmpty(pkg.requestedPermissions)) {
return;
}
- Set<String> revokablePermissions = new ArraySet<>(pkg.requestedPermissions);
+ Set<String> revokablePermissions = new ArraySet<>(Arrays.asList(pkg.requestedPermissions));
for (String permission : permissions) {
// We can't revoke what wasn't requested.
@@ -1181,7 +977,7 @@
}
final int flags = mServiceInternal.getPermissionFlagsTEMP(
- permission, pkg.packageName, userId);
+ permission, packageName, userId);
// We didn't get this through the default grant policy. Move along.
if ((flags & PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT) == 0) {
@@ -1197,29 +993,35 @@
if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0 && !systemFixed) {
continue;
}
- mServiceInternal.revokeRuntimePermission(pkg.packageName, permission, userId, false);
+ mServiceInternal.revokeRuntimePermission(packageName, permission, userId, false);
if (DEBUG) {
Log.i(TAG, "revoked " + (systemFixed ? "fixed " : "not fixed ")
- + permission + " to " + pkg.packageName);
+ + permission + " to " + packageName);
}
// Remove the GRANTED_BY_DEFAULT flag without touching the others.
// Note that we do not revoke FLAG_PERMISSION_SYSTEM_FIXED. That bit remains
// sticky once set.
- mServiceInternal.updatePermissionFlagsTEMP(permission, pkg.packageName,
+ mServiceInternal.updatePermissionFlagsTEMP(permission, packageName,
PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT, 0, userId);
}
}
- private void grantRuntimePermissions(PackageParser.Package pkg,
+ private void grantRuntimePermissions(PackageInfo pkg,
Set<String> permissionsWithoutSplits, boolean systemFixed, boolean ignoreSystemPackage,
int userId) {
- if (pkg.requestedPermissions.isEmpty()) {
+ if (pkg == null) {
+ return;
+ }
+
+ String[] requestedPermissions = pkg.requestedPermissions;
+ if (ArrayUtils.isEmpty(requestedPermissions)) {
return;
}
final ArraySet<String> permissions = new ArraySet<>(permissionsWithoutSplits);
+ ApplicationInfo applicationInfo = pkg.applicationInfo;
// Automatically attempt to grant split permissions to older APKs
final int numSplitPerms = PackageParser.SPLIT_PERMISSIONS.length;
@@ -1227,13 +1029,13 @@
final PackageParser.SplitPermissionInfo splitPerm =
PackageParser.SPLIT_PERMISSIONS[splitPermNum];
- if (pkg.applicationInfo.targetSdkVersion < splitPerm.targetSdk
+ if (applicationInfo != null
+ && applicationInfo.targetSdkVersion < splitPerm.targetSdk
&& permissionsWithoutSplits.contains(splitPerm.rootPerm)) {
Collections.addAll(permissions, splitPerm.newPerms);
}
}
- List<String> requestedPermissions = pkg.requestedPermissions;
Set<String> grantablePermissions = null;
// In some cases, like for the Phone or SMS app, we grant permissions regardless
@@ -1242,23 +1044,25 @@
// choice to grant this app the permissions needed to function. For all other
// apps, (default grants on first boot and user creation) we don't grant default
// permissions if the version on the system image does not declare them.
- if (!ignoreSystemPackage && pkg.isUpdatedSystemApp()) {
- final PackageParser.Package disabledPkg =
- mServiceInternal.getDisabledPackage(pkg.packageName);
+ if (!ignoreSystemPackage
+ && applicationInfo != null
+ && applicationInfo.isUpdatedSystemApp()) {
+ final PackageInfo disabledPkg = getSystemPackageInfo(
+ mServiceInternal.getDisabledSystemPackageName(pkg.packageName));
if (disabledPkg != null) {
- if (disabledPkg.requestedPermissions.isEmpty()) {
+ if (ArrayUtils.isEmpty(disabledPkg.requestedPermissions)) {
return;
}
if (!requestedPermissions.equals(disabledPkg.requestedPermissions)) {
- grantablePermissions = new ArraySet<>(requestedPermissions);
+ grantablePermissions = new ArraySet<>(Arrays.asList(requestedPermissions));
requestedPermissions = disabledPkg.requestedPermissions;
}
}
}
- final int grantablePermissionCount = requestedPermissions.size();
+ final int grantablePermissionCount = requestedPermissions.length;
for (int i = 0; i < grantablePermissionCount; i++) {
- String permission = requestedPermissions.get(i);
+ String permission = requestedPermissions[i];
// If there is a disabled system app it may request a permission the updated
// version ot the data partition doesn't, In this case skip the permission.
@@ -1288,7 +1092,7 @@
pkg.packageName, permission, userId, false);
if (DEBUG) {
Log.i(TAG, "Granted " + (systemFixed ? "fixed " : "not fixed ")
- + permission + " to default handler " + pkg.packageName);
+ + permission + " to default handler " + pkg);
}
int newFlags = PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
@@ -1307,7 +1111,7 @@
&& !systemFixed) {
if (DEBUG) {
Log.i(TAG, "Granted not fixed " + permission + " to default handler "
- + pkg.packageName);
+ + pkg);
}
mServiceInternal.updatePermissionFlagsTEMP(permission, pkg.packageName,
PackageManager.FLAG_PERMISSION_SYSTEM_FIXED, 0, userId);
@@ -1316,28 +1120,42 @@
}
}
- private boolean isSysComponentOrPersistentPlatformSignedPrivApp(PackageParser.Package pkg) {
+ private PackageInfo getSystemPackageInfo(String pkg) {
+ //TODO not MATCH_SYSTEM_ONLY?
+ return getPackageInfo(pkg, PackageManager.MATCH_FACTORY_ONLY);
+ }
+
+ private PackageInfo getPackageInfo(String pkg) {
+ return getPackageInfo(pkg, 0 /* extraFlags */);
+ }
+
+ private PackageInfo getPackageInfo(String pkg,
+ @PackageManager.PackageInfoFlags int extraFlags) {
+ return mServiceInternal.getPackageInfo(pkg,
+ DEFAULT_PACKAGE_INFO_QUERY_FLAGS | extraFlags,
+ //TODO is this the right filterCallingUid?
+ UserHandle.USER_SYSTEM, UserHandle.USER_SYSTEM);
+ }
+
+ private boolean isSysComponentOrPersistentPlatformSignedPrivApp(PackageInfo pkg) {
if (UserHandle.getAppId(pkg.applicationInfo.uid) < FIRST_APPLICATION_UID) {
return true;
}
- if (!pkg.isPrivileged()) {
+ if (!pkg.applicationInfo.isPrivilegedApp()) {
return false;
}
- final PackageParser.Package disabledPkg =
- mServiceInternal.getDisabledPackage(pkg.packageName);
+ final PackageInfo disabledPkg = getSystemPackageInfo(
+ mServiceInternal.getDisabledSystemPackageName(pkg.applicationInfo.packageName));
if (disabledPkg != null) {
- if ((disabledPkg.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) == 0) {
+ ApplicationInfo disabledPackageAppInfo = disabledPkg.applicationInfo;
+ if (disabledPackageAppInfo != null
+ && (disabledPackageAppInfo.flags & ApplicationInfo.FLAG_PERSISTENT) == 0) {
return false;
}
} else if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) == 0) {
return false;
}
- final String systemPackageName = mServiceInternal.getKnownPackageName(
- PackageManagerInternal.PACKAGE_SYSTEM, UserHandle.USER_SYSTEM);
- final PackageParser.Package systemPackage = getPackage(systemPackageName);
- return pkg.mSigningDetails.hasAncestorOrSelf(systemPackage.mSigningDetails)
- || systemPackage.mSigningDetails.checkCapability(pkg.mSigningDetails,
- PackageParser.SigningDetails.CertCapabilities.PERMISSION);
+ return mServiceInternal.isPlatformSigned(pkg.packageName);
}
private void grantDefaultPermissionExceptions(int userId) {
@@ -1357,7 +1175,7 @@
final int exceptionCount = mGrantExceptions.size();
for (int i = 0; i < exceptionCount; i++) {
String packageName = mGrantExceptions.keyAt(i);
- PackageParser.Package pkg = getSystemPackage(packageName);
+ PackageInfo pkg = getSystemPackageInfo(packageName);
List<DefaultPermissionGrant> permissionGrants = mGrantExceptions.valueAt(i);
final int permissionGrantCount = permissionGrants.size();
for (int j = 0; j < permissionGrantCount; j++) {
@@ -1368,8 +1186,7 @@
permissions.clear();
}
permissions.add(permissionGrant.name);
- grantRuntimePermissions(pkg, permissions,
- permissionGrant.fixed, userId);
+ grantRuntimePermissions(pkg, permissions, permissionGrant.fixed, userId);
}
}
}
@@ -1474,15 +1291,14 @@
outGrantExceptions.get(packageName);
if (packageExceptions == null) {
// The package must be on the system image
- PackageParser.Package pkg = getSystemPackage(packageName);
- if (pkg == null) {
+ if (!isSystemPackage(packageName)) {
Log.w(TAG, "Unknown package:" + packageName);
XmlUtils.skipCurrentTag(parser);
continue;
}
// The package must support runtime permissions
- if (!doesPackageSupportRuntimePermissions(pkg)) {
+ if (!doesPackageSupportRuntimePermissions(getSystemPackageInfo(packageName))) {
Log.w(TAG, "Skipping non supporting runtime permissions package:"
+ packageName);
XmlUtils.skipCurrentTag(parser);
@@ -1527,8 +1343,9 @@
}
}
- private static boolean doesPackageSupportRuntimePermissions(PackageParser.Package pkg) {
- return pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1;
+ private static boolean doesPackageSupportRuntimePermissions(PackageInfo pkg) {
+ return pkg.applicationInfo != null
+ && pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1;
}
private static final class DefaultPermissionGrant {
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index c4f90a12..4b6760c 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -1189,7 +1189,7 @@
// is granted only if it had been defined by the original application.
if (pkg.isUpdatedSystemApp()) {
final PackageParser.Package disabledPkg =
- mPackageManagerInt.getDisabledPackage(pkg.packageName);
+ mPackageManagerInt.getDisabledSystemPackage(pkg.packageName);
final PackageSetting disabledPs =
(disabledPkg != null) ? (PackageSetting) disabledPkg.mExtras : null;
if (disabledPs != null
@@ -1221,7 +1221,7 @@
// packages can also get the permission.
if (pkg.parentPackage != null) {
final PackageParser.Package disabledParentPkg = mPackageManagerInt
- .getDisabledPackage(pkg.parentPackage.packageName);
+ .getDisabledSystemPackage(pkg.parentPackage.packageName);
final PackageSetting disabledParentPs = (disabledParentPkg != null)
? (PackageSetting) disabledParentPkg.mExtras : null;
if (disabledParentPkg != null
@@ -1372,7 +1372,7 @@
return;
}
final PackageParser.Package disabledPkg =
- mPackageManagerInt.getDisabledPackage(pkg.parentPackage.packageName);
+ mPackageManagerInt.getDisabledSystemPackage(pkg.parentPackage.packageName);
if (disabledPkg == null || disabledPkg.mExtras == null) {
return;
}
diff --git a/services/core/java/com/android/server/policy/TEST_MAPPING b/services/core/java/com/android/server/policy/TEST_MAPPING
new file mode 100644
index 0000000..e212b04
--- /dev/null
+++ b/services/core/java/com/android/server/policy/TEST_MAPPING
@@ -0,0 +1,50 @@
+{
+ "presubmit": [
+ {
+ "name": "FrameworksServicesTests",
+ "options": [
+ {
+ "include-filter": "com.android.server.policy."
+ },
+ {
+ "include-annotation": "android.platform.test.annotations.Presubmit"
+ },
+ {
+ "exclude-annotation": "android.support.test.filters.FlakyTest"
+ }
+ ]
+ },
+ {
+ "name": "WmTests",
+ "options": [
+ {
+ "include-filter": "com.android.server.policy."
+ },
+ {
+ "include-annotation": "android.platform.test.annotations.Presubmit"
+ },
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ }
+ ]
+ }
+ ],
+ "postsubmit": [
+ {
+ "name": "FrameworksServicesTests",
+ "options": [
+ {
+ "include-filter": "com.android.server.policy."
+ }
+ ]
+ },
+ {
+ "name": "WmTests",
+ "options": [
+ {
+ "include-filter": "com.android.server.policy."
+ }
+ ]
+ }
+ ]
+}
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index 5981ab0..68e636a 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -49,6 +49,7 @@
import android.util.Slog;
import android.util.StatsLog;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IBatteryStats;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -75,7 +76,8 @@
* tell the system when we go to sleep so that it can lock the keyguard if needed.
* </p>
*/
-final class Notifier {
+@VisibleForTesting
+public class Notifier {
private static final String TAG = "PowerManagerNotifier";
private static final boolean DEBUG = false;
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index bdf12ca..9f6b3dd 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -64,7 +64,6 @@
import android.os.WorkSource;
import android.os.WorkSource.WorkChain;
import android.provider.Settings;
-import android.provider.Settings.Global;
import android.provider.Settings.SettingNotFoundException;
import android.service.dreams.DreamManagerInternal;
import android.service.vr.IVrManager;
@@ -84,7 +83,6 @@
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.os.BackgroundThread;
-import com.android.internal.util.ArrayUtils;
import com.android.internal.util.DumpUtils;
import com.android.server.EventLogTags;
import com.android.server.LockGuard;
@@ -230,6 +228,10 @@
private final BatterySaverController mBatterySaverController;
private final BatterySaverStateMachine mBatterySaverStateMachine;
private final BatterySavingStats mBatterySavingStats;
+ private final BinderService mBinderService;
+ private final LocalService mLocalService;
+ private final NativeWrapper mNativeWrapper;
+ private final Injector mInjector;
private LightsManager mLightsManager;
private BatteryManagerInternal mBatteryManagerInternal;
@@ -636,10 +638,76 @@
}
}
+ /**
+ * Wrapper around the static-native methods of PowerManagerService.
+ *
+ * This class exists to allow us to mock static native methods in our tests. If mocking static
+ * methods becomes easier than this in the future, we can delete this class.
+ */
+ @VisibleForTesting
+ public static class NativeWrapper {
+ /** Wrapper for PowerManager.nativeInit */
+ public void nativeInit(PowerManagerService service) {
+ service.nativeInit();
+ }
+
+ /** Wrapper for PowerManager.nativeAcquireSuspectBlocker */
+ public void nativeAcquireSuspendBlocker(String name) {
+ PowerManagerService.nativeAcquireSuspendBlocker(name);
+ }
+
+ /** Wrapper for PowerManager.nativeReleaseSuspendBlocker */
+ public void nativeReleaseSuspendBlocker(String name) {
+ PowerManagerService.nativeReleaseSuspendBlocker(name);
+ }
+
+ /** Wrapper for PowerManager.nativeSetInteractive */
+ public void nativeSetInteractive(boolean enable) {
+ PowerManagerService.nativeSetInteractive(enable);
+ }
+
+ /** Wrapper for PowerManager.nativeSetAutoSuspend */
+ public void nativeSetAutoSuspend(boolean enable) {
+ PowerManagerService.nativeSetAutoSuspend(enable);
+ }
+
+ /** Wrapper for PowerManager.nativeSendPowerHint */
+ public void nativeSendPowerHint(int hintId, int data) {
+ PowerManagerService.nativeSendPowerHint(hintId, data);
+ }
+
+ /** Wrapper for PowerManager.nativeSetFeature */
+ public void nativeSetFeature(int featureId, int data) {
+ PowerManagerService.nativeSetFeature(featureId, data);
+ }
+ }
+
+ @VisibleForTesting
+ static class Injector {
+ Notifier createNotifier(Looper looper, Context context, IBatteryStats batteryStats,
+ SuspendBlocker suspendBlocker, WindowManagerPolicy policy) {
+ return new Notifier(looper, context, batteryStats, suspendBlocker, policy);
+ }
+
+ SuspendBlocker createSuspendBlocker(PowerManagerService service, String name) {
+ SuspendBlocker suspendBlocker = service.new SuspendBlockerImpl(name);
+ service.mSuspendBlockers.add(suspendBlocker);
+ return suspendBlocker;
+ }
+
+ BatterySaverPolicy createBatterySaverPolicy(
+ Object lock, Context context, BatterySavingStats batterySavingStats) {
+ return new BatterySaverPolicy(lock, context, batterySavingStats);
+ }
+
+ NativeWrapper createNativeWrapper() {
+ return new NativeWrapper();
+ }
+ }
+
final Constants mConstants;
private native void nativeInit();
-
private static native void nativeAcquireSuspendBlocker(String name);
private static native void nativeReleaseSuspendBlocker(String name);
private static native void nativeSetInteractive(boolean enable);
@@ -648,8 +716,19 @@
private static native void nativeSetFeature(int featureId, int data);
public PowerManagerService(Context context) {
+ this(context, new Injector());
+ }
+
+ @VisibleForTesting
+ PowerManagerService(Context context, Injector injector) {
super(context);
+
mContext = context;
+ mBinderService = new BinderService();
+ mLocalService = new LocalService();
+ mNativeWrapper = injector.createNativeWrapper();
+ mInjector = injector;
+
mHandlerThread = new ServiceThread(TAG,
Process.THREAD_PRIORITY_DISPLAY, false /*allowIo*/);
mHandlerThread.start();
@@ -658,57 +737,40 @@
mAmbientDisplayConfiguration = new AmbientDisplayConfiguration(mContext);
mBatterySavingStats = new BatterySavingStats(mLock);
- mBatterySaverPolicy = new BatterySaverPolicy(mLock, mContext, mBatterySavingStats);
+ mBatterySaverPolicy =
+ mInjector.createBatterySaverPolicy(mLock, mContext, mBatterySavingStats);
mBatterySaverController = new BatterySaverController(mLock, mContext,
- BackgroundThread.get().getLooper(), mBatterySaverPolicy, mBatterySavingStats);
+ BackgroundThread.get().getLooper(), mBatterySaverPolicy,
+ mBatterySavingStats);
mBatterySaverStateMachine = new BatterySaverStateMachine(
mLock, mContext, mBatterySaverController);
synchronized (mLock) {
- mWakeLockSuspendBlocker = createSuspendBlockerLocked("PowerManagerService.WakeLocks");
- mDisplaySuspendBlocker = createSuspendBlockerLocked("PowerManagerService.Display");
- mDisplaySuspendBlocker.acquire();
- mHoldingDisplaySuspendBlocker = true;
+ mWakeLockSuspendBlocker =
+ mInjector.createSuspendBlocker(this, "PowerManagerService.WakeLocks");
+ mDisplaySuspendBlocker =
+ mInjector.createSuspendBlocker(this, "PowerManagerService.Display");
+ if (mDisplaySuspendBlocker != null) {
+ mDisplaySuspendBlocker.acquire();
+ mHoldingDisplaySuspendBlocker = true;
+ }
mHalAutoSuspendModeEnabled = false;
mHalInteractiveModeEnabled = true;
mWakefulness = WAKEFULNESS_AWAKE;
-
sQuiescent = SystemProperties.get(SYSTEM_PROPERTY_QUIESCENT, "0").equals("1");
- nativeInit();
- nativeSetAutoSuspend(false);
- nativeSetInteractive(true);
- nativeSetFeature(POWER_FEATURE_DOUBLE_TAP_TO_WAKE, 0);
+ mNativeWrapper.nativeInit(this);
+ mNativeWrapper.nativeSetAutoSuspend(false);
+ mNativeWrapper.nativeSetInteractive(true);
+ mNativeWrapper.nativeSetFeature(POWER_FEATURE_DOUBLE_TAP_TO_WAKE, 0);
}
}
- @VisibleForTesting
- PowerManagerService(Context context, BatterySaverPolicy batterySaverPolicy) {
- super(context);
-
- mContext = context;
- mHandlerThread = new ServiceThread(TAG,
- Process.THREAD_PRIORITY_DISPLAY, false /*allowIo*/);
- mHandlerThread.start();
- mHandler = new PowerManagerHandler(mHandlerThread.getLooper());
- mConstants = new Constants(mHandler);
- mAmbientDisplayConfiguration = new AmbientDisplayConfiguration(mContext);
- mDisplaySuspendBlocker = null;
- mWakeLockSuspendBlocker = null;
-
- mBatterySavingStats = new BatterySavingStats(mLock);
- mBatterySaverPolicy = batterySaverPolicy;
- mBatterySaverController = new BatterySaverController(mLock, context,
- BackgroundThread.getHandler().getLooper(), batterySaverPolicy, mBatterySavingStats);
- mBatterySaverStateMachine = new BatterySaverStateMachine(
- mLock, mContext, mBatterySaverController);
- }
-
@Override
public void onStart() {
- publishBinderService(Context.POWER_SERVICE, new BinderService());
- publishLocalService(PowerManagerInternal.class, new LocalService());
+ publishBinderService(Context.POWER_SERVICE, mBinderService);
+ publishLocalService(PowerManagerInternal.class, mLocalService);
Watchdog.getInstance().addMonitor(this);
Watchdog.getInstance().addThread(mHandler);
@@ -752,11 +814,13 @@
// The notifier runs on the system server's main looper so as not to interfere
// with the animations and other critical functions of the power manager.
mBatteryStats = BatteryStatsService.getService();
- mNotifier = new Notifier(Looper.getMainLooper(), mContext, mBatteryStats,
- createSuspendBlockerLocked("PowerManagerService.Broadcasts"), mPolicy);
+ mNotifier = mInjector.createNotifier(Looper.getMainLooper(), mContext, mBatteryStats,
+ mInjector.createSuspendBlocker(this, "PowerManagerService.Broadcasts"),
+ mPolicy);
mWirelessChargerDetector = new WirelessChargerDetector(sensorManager,
- createSuspendBlockerLocked("PowerManagerService.WirelessChargerDetector"),
+ mInjector.createSuspendBlocker(
+ this, "PowerManagerService.WirelessChargerDetector"),
mHandler);
mSettingsObserver = new SettingsObserver(mHandler);
@@ -824,7 +888,7 @@
resolver.registerContentObserver(Settings.Global.getUriFor(
Settings.Global.DEVICE_DEMO_MODE),
false, mSettingsObserver, UserHandle.USER_SYSTEM);
- IVrManager vrManager = (IVrManager) getBinderService(Context.VR_SERVICE);
+ IVrManager vrManager = IVrManager.Stub.asInterface(getBinderService(Context.VR_SERVICE));
if (vrManager != null) {
try {
vrManager.registerListener(mVrStateCallbacks);
@@ -927,7 +991,8 @@
UserHandle.USER_CURRENT) != 0;
if (doubleTapWakeEnabled != mDoubleTapWakeEnabled) {
mDoubleTapWakeEnabled = doubleTapWakeEnabled;
- nativeSetFeature(POWER_FEATURE_DOUBLE_TAP_TO_WAKE, mDoubleTapWakeEnabled ? 1 : 0);
+ mNativeWrapper.nativeSetFeature(
+ POWER_FEATURE_DOUBLE_TAP_TO_WAKE, mDoubleTapWakeEnabled ? 1 : 0);
}
}
@@ -1509,6 +1574,11 @@
}
}
+ @VisibleForTesting
+ int getWakefulness() {
+ return mWakefulness;
+ }
+
/**
* Logs the time the device would have spent awake before user activity timeout,
* had the system not been told the user was inactive.
@@ -2640,7 +2710,7 @@
mHalAutoSuspendModeEnabled = enable;
Trace.traceBegin(Trace.TRACE_TAG_POWER, "setHalAutoSuspend(" + enable + ")");
try {
- nativeSetAutoSuspend(enable);
+ mNativeWrapper.nativeSetAutoSuspend(enable);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_POWER);
}
@@ -2655,7 +2725,7 @@
mHalInteractiveModeEnabled = enable;
Trace.traceBegin(Trace.TRACE_TAG_POWER, "setHalInteractive(" + enable + ")");
try {
- nativeSetInteractive(enable);
+ mNativeWrapper.nativeSetInteractive(enable);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_POWER);
}
@@ -3127,7 +3197,7 @@
break;
}
- nativeSendPowerHint(hintId, data);
+ mNativeWrapper.nativeSendPowerHint(hintId, data);
}
/**
@@ -3718,12 +3788,6 @@
proto.flush();
}
- private SuspendBlocker createSuspendBlockerLocked(String name) {
- SuspendBlocker suspendBlocker = new SuspendBlockerImpl(name);
- mSuspendBlockers.add(suspendBlocker);
- return suspendBlocker;
- }
-
private void incrementBootCount() {
synchronized (mLock) {
int count;
@@ -4022,7 +4086,7 @@
Slog.wtf(TAG, "Suspend blocker \"" + mName
+ "\" was finalized without being released!");
mReferenceCount = 0;
- nativeReleaseSuspendBlocker(mName);
+ mNativeWrapper.nativeReleaseSuspendBlocker(mName);
Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, mTraceName, 0);
}
} finally {
@@ -4039,7 +4103,7 @@
Slog.d(TAG, "Acquiring suspend blocker \"" + mName + "\".");
}
Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, mTraceName, 0);
- nativeAcquireSuspendBlocker(mName);
+ mNativeWrapper.nativeAcquireSuspendBlocker(mName);
}
}
}
@@ -4052,7 +4116,7 @@
if (DEBUG_SPEW) {
Slog.d(TAG, "Releasing suspend blocker \"" + mName + "\".");
}
- nativeReleaseSuspendBlocker(mName);
+ mNativeWrapper.nativeReleaseSuspendBlocker(mName);
Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, mTraceName, 0);
} else if (mReferenceCount < 0) {
Slog.wtf(TAG, "Suspend blocker \"" + mName
@@ -4090,7 +4154,8 @@
}
}
- private final class BinderService extends IPowerManager.Stub {
+ @VisibleForTesting
+ final class BinderService extends IPowerManager.Stub {
@Override
public void onShellCommand(FileDescriptor in, FileDescriptor out,
FileDescriptor err, String[] args, ShellCallback callback,
@@ -4592,6 +4657,16 @@
}
@VisibleForTesting
+ BinderService getBinderServiceInstance() {
+ return mBinderService;
+ }
+
+ @VisibleForTesting
+ LocalService getLocalServiceInstance() {
+ return mLocalService;
+ }
+
+ @VisibleForTesting
// lastRebootReasonProperty argument to permit testing
int getLastShutdownReasonInternal(String lastRebootReasonProperty) {
String line = SystemProperties.get(lastRebootReasonProperty);
diff --git a/services/core/java/com/android/server/telecom/TelecomLoaderService.java b/services/core/java/com/android/server/telecom/TelecomLoaderService.java
index 6c5452a..7a3f030 100644
--- a/services/core/java/com/android/server/telecom/TelecomLoaderService.java
+++ b/services/core/java/com/android/server/telecom/TelecomLoaderService.java
@@ -22,7 +22,6 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
-import android.content.pm.PackageManagerInternal;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Handler;
@@ -39,12 +38,13 @@
import android.util.IntArray;
import android.util.Slog;
-import android.util.SparseBooleanArray;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.telephony.SmsApplication;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.pm.UserManagerService;
+import com.android.server.pm.permission.DefaultPermissionGrantPolicy;
+import com.android.server.pm.permission.PermissionManagerInternal;
/**
* Starts the telecom component by binding to its ITelecomService implementation. Telecom is setup
@@ -72,8 +72,8 @@
synchronized (mLock) {
if (mDefaultSmsAppRequests != null || mDefaultDialerAppRequests != null
|| mDefaultSimCallManagerRequests != null) {
- final PackageManagerInternal packageManagerInternal = LocalServices
- .getService(PackageManagerInternal.class);
+ final DefaultPermissionGrantPolicy permissionPolicy =
+ getDefaultPermissionGrantPolicy();
if (mDefaultSmsAppRequests != null) {
ComponentName smsComponent = SmsApplication.getDefaultSmsApplication(
@@ -83,7 +83,7 @@
for (int i = requestCount - 1; i >= 0; i--) {
final int userid = mDefaultSmsAppRequests.get(i);
mDefaultSmsAppRequests.remove(i);
- packageManagerInternal.grantDefaultPermissionsToDefaultSmsApp(
+ permissionPolicy.grantDefaultPermissionsToDefaultSmsApp(
smsComponent.getPackageName(), userid);
}
}
@@ -97,7 +97,7 @@
for (int i = requestCount - 1; i >= 0; i--) {
final int userId = mDefaultDialerAppRequests.get(i);
mDefaultDialerAppRequests.remove(i);
- packageManagerInternal.grantDefaultPermissionsToDefaultDialerApp(
+ permissionPolicy.grantDefaultPermissionsToDefaultDialerApp(
packageName, userId);
}
}
@@ -113,7 +113,7 @@
for (int i = requestCount - 1; i >= 0; i--) {
final int userId = mDefaultSimCallManagerRequests.get(i);
mDefaultSimCallManagerRequests.remove(i);
- packageManagerInternal
+ permissionPolicy
.grantDefaultPermissionsToDefaultSimCallManager(
packageName, userId);
}
@@ -132,6 +132,11 @@
}
}
+ private DefaultPermissionGrantPolicy getDefaultPermissionGrantPolicy() {
+ return LocalServices.getService(PermissionManagerInternal.class)
+ .getDefaultPermissionGrantPolicy();
+ }
+
private static final ComponentName SERVICE_COMPONENT = new ComponentName(
"com.android.server.telecom",
"com.android.server.telecom.components.TelecomService");
@@ -196,82 +201,68 @@
private void registerDefaultAppProviders() {
- final PackageManagerInternal packageManagerInternal = LocalServices.getService(
- PackageManagerInternal.class);
+ final DefaultPermissionGrantPolicy permissionPolicy = getDefaultPermissionGrantPolicy();
- // Set a callback for the package manager to query the default sms app.
- packageManagerInternal.setSmsAppPackagesProvider(
- new PackageManagerInternal.PackagesProvider() {
- @Override
- public String[] getPackages(int userId) {
- synchronized (mLock) {
- if (mServiceConnection == null) {
- if (mDefaultSmsAppRequests == null) {
- mDefaultSmsAppRequests = new IntArray();
- }
- mDefaultSmsAppRequests.add(userId);
- return null;
+ // Set a callback for the permission grant policy to query the default sms app.
+ permissionPolicy.setSmsAppPackagesProvider(userId -> {
+ synchronized (mLock) {
+ if (mServiceConnection == null) {
+ if (mDefaultSmsAppRequests == null) {
+ mDefaultSmsAppRequests = new IntArray();
}
+ mDefaultSmsAppRequests.add(userId);
+ return null;
}
- ComponentName smsComponent = SmsApplication.getDefaultSmsApplication(
- mContext, true);
- if (smsComponent != null) {
- return new String[]{smsComponent.getPackageName()};
- }
- return null;
}
+ ComponentName smsComponent = SmsApplication.getDefaultSmsApplication(
+ mContext, true);
+ if (smsComponent != null) {
+ return new String[]{smsComponent.getPackageName()};
+ }
+ return null;
});
- // Set a callback for the package manager to query the default dialer app.
- packageManagerInternal.setDialerAppPackagesProvider(
- new PackageManagerInternal.PackagesProvider() {
- @Override
- public String[] getPackages(int userId) {
- synchronized (mLock) {
- if (mServiceConnection == null) {
- if (mDefaultDialerAppRequests == null) {
- mDefaultDialerAppRequests = new IntArray();
- }
- mDefaultDialerAppRequests.add(userId);
- return null;
+ // Set a callback for the permission grant policy to query the default dialer app.
+ permissionPolicy.setDialerAppPackagesProvider(userId -> {
+ synchronized (mLock) {
+ if (mServiceConnection == null) {
+ if (mDefaultDialerAppRequests == null) {
+ mDefaultDialerAppRequests = new IntArray();
}
+ mDefaultDialerAppRequests.add(userId);
+ return null;
}
- String packageName = DefaultDialerManager.getDefaultDialerApplication(mContext);
- if (packageName != null) {
- return new String[]{packageName};
- }
- return null;
}
+ String packageName = DefaultDialerManager.getDefaultDialerApplication(mContext);
+ if (packageName != null) {
+ return new String[]{packageName};
+ }
+ return null;
});
- // Set a callback for the package manager to query the default sim call manager.
- packageManagerInternal.setSimCallManagerPackagesProvider(
- new PackageManagerInternal.PackagesProvider() {
- @Override
- public String[] getPackages(int userId) {
- synchronized (mLock) {
- if (mServiceConnection == null) {
- if (mDefaultSimCallManagerRequests == null) {
- mDefaultSimCallManagerRequests = new IntArray();
- }
- mDefaultSimCallManagerRequests.add(userId);
- return null;
+ // Set a callback for the permission grant policy to query the default sim call manager.
+ permissionPolicy.setSimCallManagerPackagesProvider(userId -> {
+ synchronized (mLock) {
+ if (mServiceConnection == null) {
+ if (mDefaultSimCallManagerRequests == null) {
+ mDefaultSimCallManagerRequests = new IntArray();
}
+ mDefaultSimCallManagerRequests.add(userId);
+ return null;
}
- TelecomManager telecomManager =
+ }
+ TelecomManager telecomManager =
(TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
- PhoneAccountHandle phoneAccount = telecomManager.getSimCallManager(userId);
- if (phoneAccount != null) {
- return new String[]{phoneAccount.getComponentName().getPackageName()};
- }
- return null;
+ PhoneAccountHandle phoneAccount = telecomManager.getSimCallManager(userId);
+ if (phoneAccount != null) {
+ return new String[]{phoneAccount.getComponentName().getPackageName()};
}
+ return null;
});
}
private void registerDefaultAppNotifier() {
- final PackageManagerInternal packageManagerInternal = LocalServices.getService(
- PackageManagerInternal.class);
+ final DefaultPermissionGrantPolicy permissionPolicy = getDefaultPermissionGrantPolicy();
// Notify the package manager on default app changes
final Uri defaultSmsAppUri = Settings.Secure.getUriFor(
@@ -287,17 +278,17 @@
ComponentName smsComponent = SmsApplication.getDefaultSmsApplication(
mContext, true);
if (smsComponent != null) {
- packageManagerInternal.grantDefaultPermissionsToDefaultSmsApp(
+ permissionPolicy.grantDefaultPermissionsToDefaultSmsApp(
smsComponent.getPackageName(), userId);
}
} else if (defaultDialerAppUri.equals(uri)) {
String packageName = DefaultDialerManager.getDefaultDialerApplication(
mContext);
if (packageName != null) {
- packageManagerInternal.grantDefaultPermissionsToDefaultDialerApp(
+ permissionPolicy.grantDefaultPermissionsToDefaultDialerApp(
packageName, userId);
}
- updateSimCallManagerPermissions(packageManagerInternal, userId);
+ updateSimCallManagerPermissions(permissionPolicy, userId);
}
}
};
@@ -310,14 +301,12 @@
private void registerCarrierConfigChangedReceiver() {
- final PackageManagerInternal packageManagerInternal = LocalServices.getService(
- PackageManagerInternal.class);
BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) {
for (int userId : UserManagerService.getInstance().getUserIds()) {
- updateSimCallManagerPermissions(packageManagerInternal, userId);
+ updateSimCallManagerPermissions(getDefaultPermissionGrantPolicy(), userId);
}
}
}
@@ -327,15 +316,15 @@
new IntentFilter(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED), null, null);
}
- private void updateSimCallManagerPermissions(PackageManagerInternal packageManagerInternal,
- int userId) {
+ private void updateSimCallManagerPermissions(
+ DefaultPermissionGrantPolicy permissionGrantPolicy, int userId) {
TelecomManager telecomManager =
(TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
PhoneAccountHandle phoneAccount = telecomManager.getSimCallManager(userId);
if (phoneAccount != null) {
Slog.i(TAG, "updating sim call manager permissions for userId:" + userId);
String packageName = phoneAccount.getComponentName().getPackageName();
- packageManagerInternal.grantDefaultPermissionsToDefaultSimCallManager(
+ permissionGrantPolicy.grantDefaultPermissionsToDefaultSimCallManager(
packageName, userId);
}
}
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 6c7304d..d518549 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -150,7 +150,6 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ToBooleanFunction;
-import com.android.internal.view.IInputMethodClient;
import com.android.server.policy.WindowManagerPolicy;
import com.android.server.wm.utils.RotationCache;
import com.android.server.wm.utils.WmDisplayCutout;
@@ -2949,7 +2948,7 @@
}
}
- boolean inputMethodClientHasFocus(IInputMethodClient client) {
+ boolean isInputMethodClientFocus(int uid, int pid) {
final WindowState imFocus = computeImeTarget(false /* updateImeTarget */);
if (imFocus == null) {
return false;
@@ -2961,17 +2960,13 @@
Slog.i(TAG_WM, "Last focus: " + mService.mLastFocus);
}
- final IInputMethodClient imeClient = imFocus.mSession.mClient;
-
if (DEBUG_INPUT_METHOD) {
- Slog.i(TAG_WM, "IM target client: " + imeClient);
- if (imeClient != null) {
- Slog.i(TAG_WM, "IM target client binder: " + imeClient.asBinder());
- Slog.i(TAG_WM, "Requesting client binder: " + client.asBinder());
- }
+ Slog.i(TAG_WM, "IM target uid/pid: " + imFocus.mSession.mUid
+ + "/" + imFocus.mSession.mPid);
+ Slog.i(TAG_WM, "Requesting client uid/pid: " + uid + "/" + pid);
}
- return imeClient != null && imeClient.asBinder() == client.asBinder();
+ return imFocus.mSession.mUid == uid && imFocus.mSession.mPid == pid;
}
boolean hasSecureWindowOnScreen() {
diff --git a/services/core/java/com/android/server/wm/TEST_MAPPING b/services/core/java/com/android/server/wm/TEST_MAPPING
index c99329a..0c9a14b 100644
--- a/services/core/java/com/android/server/wm/TEST_MAPPING
+++ b/services/core/java/com/android/server/wm/TEST_MAPPING
@@ -21,7 +21,7 @@
"include-annotation": "android.platform.test.annotations.Presubmit"
},
{
- "exclude-annotation": "android.support.test.filters.FlakyTest"
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
}
]
},
@@ -35,7 +35,7 @@
"include-annotation": "android.platform.test.annotations.Presubmit"
},
{
- "exclude-annotation": "android.support.test.filters.FlakyTest"
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
}
]
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java
index 793ce60..57cae39 100644
--- a/services/core/java/com/android/server/wm/WindowManagerInternal.java
+++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java
@@ -30,7 +30,6 @@
import android.view.MagnificationSpec;
import android.view.WindowInfo;
-import com.android.internal.view.IInputMethodClient;
import com.android.server.input.InputManagerService;
import com.android.server.policy.WindowManagerPolicy;
@@ -444,9 +443,14 @@
public abstract boolean isUidFocused(int uid);
/**
- * Returns {@code true} if a process that is identified by {@code client} has IME focus.
+ * Checks whether the specified process has IME focus or not.
+ *
+ * @param uid UID of the process to be queried
+ * @param pid PID of the process to be queried
+ * @return {@code true} if a process that is identified by {@code uid} and {@code pid} has IME
+ * focus
*/
- public abstract boolean inputMethodClientHasFocus(IInputMethodClient client);
+ public abstract boolean isInputMethodClientFocus(int uid, int pid);
/**
* Return the display Id for given window.
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index ee128c7..711f66a 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -7412,12 +7412,12 @@
}
@Override
- public boolean inputMethodClientHasFocus(IInputMethodClient client) {
+ public boolean isInputMethodClientFocus(int uid, int pid) {
synchronized (mWindowMap) {
// Check all displays if any input method window has focus.
for (int i = mRoot.mChildren.size() - 1; i >= 0; --i) {
final DisplayContent displayContent = mRoot.mChildren.get(i);
- if (displayContent.inputMethodClientHasFocus(client)) {
+ if (displayContent.isInputMethodClientFocus(uid, pid)) {
return true;
}
}
@@ -7430,8 +7430,8 @@
// press home. Sometimes the IME won't go down.)
// Would be nice to fix this more correctly, but it's
// way at the end of a release, and this should be good enough.
- if (mCurrentFocus != null && mCurrentFocus.mSession.mClient != null
- && mCurrentFocus.mSession.mClient.asBinder() == client.asBinder()) {
+ if (mCurrentFocus != null && mCurrentFocus.mSession.mUid == uid
+ && mCurrentFocus.mSession.mPid == pid) {
return true;
}
}
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java
index f6e5601..ffc7fa2 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java
@@ -188,17 +188,13 @@
@Test
public void testCanBeLaunchedOnDisplay() throws Exception {
- testSupportsLaunchingResizeable(false /*taskPresent*/, true /*taskResizeable*/,
- true /*activityResizeable*/, true /*expected*/);
+ mService.mSupportsMultiWindow = true;
+ final ActivityRecord activity = new ActivityBuilder(mService).build();
- testSupportsLaunchingResizeable(false /*taskPresent*/, true /*taskResizeable*/,
- false /*activityResizeable*/, false /*expected*/);
-
- testSupportsLaunchingResizeable(true /*taskPresent*/, false /*taskResizeable*/,
- true /*activityResizeable*/, false /*expected*/);
-
- testSupportsLaunchingResizeable(true /*taskPresent*/, true /*taskResizeable*/,
- false /*activityResizeable*/, true /*expected*/);
+ // An activity can be launched on default display.
+ assertTrue(activity.canBeLaunchedOnDisplay(DEFAULT_DISPLAY));
+ // An activity cannot be launched on a non-existent display.
+ assertFalse(activity.canBeLaunchedOnDisplay(DEFAULT_DISPLAY + 1));
}
@Test
@@ -229,26 +225,4 @@
assertNull(mActivity.pendingOptions);
assertNotNull(activity2.pendingOptions);
}
-
- private void testSupportsLaunchingResizeable(boolean taskPresent, boolean taskResizeable,
- boolean activityResizeable, boolean expected) {
- mService.mSupportsMultiWindow = true;
-
- final TaskRecord task = taskPresent
- ? new TaskBuilder(mService.mStackSupervisor).setStack(mStack).build() : null;
-
- if (task != null) {
- task.setResizeMode(taskResizeable ? RESIZE_MODE_RESIZEABLE : RESIZE_MODE_UNRESIZEABLE);
- }
-
- final ActivityRecord record = new ActivityBuilder(mService).setTask(task).build();
- record.info.resizeMode = activityResizeable
- ? RESIZE_MODE_RESIZEABLE : RESIZE_MODE_UNRESIZEABLE;
-
- record.canBeLaunchedOnDisplay(DEFAULT_DISPLAY);
-
-
- verify(mService.mStackSupervisor, times(1)).canPlaceEntityOnDisplay(anyInt(), eq(expected),
- anyInt(), anyInt(), eq(record.info));
- }
}
diff --git a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
index 5039e42..8ac2930 100644
--- a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
@@ -21,18 +21,32 @@
import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Matchers.anyBoolean;
-import static org.mockito.Matchers.eq;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
+import android.app.ActivityManagerInternal;
+import android.content.Context;
+import android.hardware.display.DisplayManagerInternal;
import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
+import android.os.BatteryManagerInternal;
+import android.os.Looper;
import android.os.PowerManager;
import android.os.PowerSaveState;
+import android.os.SystemClock;
import android.os.SystemProperties;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
-import com.android.server.power.batterysaver.BatterySaverController;
+import com.android.internal.app.IBatteryStats;
+import com.android.server.LocalServices;
+import com.android.server.SystemService;
+import com.android.server.lights.LightsManager;
+import com.android.server.policy.WindowManagerPolicy;
+import com.android.server.power.PowerManagerService.Injector;
+import com.android.server.power.PowerManagerService.NativeWrapper;
+import com.android.server.power.batterysaver.BatterySavingStats;
import org.junit.Rule;
import org.mockito.Mock;
@@ -47,11 +61,19 @@
private static final boolean BATTERY_SAVER_ENABLED = true;
private static final String TEST_LAST_REBOOT_PROPERTY = "test.sys.boot.reason";
- private @Mock BatterySaverPolicy mBatterySaverPolicy;
+ private @Mock BatterySaverPolicy mBatterySaverPolicyMock;
+ private @Mock LightsManager mLightsManagerMock;
+ private @Mock DisplayManagerInternal mDisplayManagerInternalMock;
+ private @Mock BatteryManagerInternal mBatteryManagerInternalMock;
+ private @Mock ActivityManagerInternal mActivityManagerInternalMock;
+ private @Mock PowerManagerService.NativeWrapper mNativeWrapperMock;
+ private @Mock Notifier mNotifierMock;
private PowerManagerService mService;
private PowerSaveState mPowerSaveState;
private DisplayPowerRequest mDisplayPowerRequest;
+
+
@Rule
public void setUp() throws Exception {
super.setUp();
@@ -61,11 +83,51 @@
.setBatterySaverEnabled(BATTERY_SAVER_ENABLED)
.setBrightnessFactor(BRIGHTNESS_FACTOR)
.build();
- when(mBatterySaverPolicy.getBatterySaverPolicy(
+ when(mBatterySaverPolicyMock.getBatterySaverPolicy(
eq(PowerManager.ServiceType.SCREEN_BRIGHTNESS), anyBoolean()))
.thenReturn(mPowerSaveState);
+
mDisplayPowerRequest = new DisplayPowerRequest();
- mService = new PowerManagerService(getContext(), mBatterySaverPolicy);
+ addLocalServiceMock(LightsManager.class, mLightsManagerMock);
+ addLocalServiceMock(DisplayManagerInternal.class, mDisplayManagerInternalMock);
+ addLocalServiceMock(BatteryManagerInternal.class, mBatteryManagerInternalMock);
+ addLocalServiceMock(ActivityManagerInternal.class, mActivityManagerInternalMock);
+
+ mService = new PowerManagerService(getContext(), new Injector() {
+ Notifier createNotifier(Looper looper, Context context, IBatteryStats batteryStats,
+ SuspendBlocker suspendBlocker, WindowManagerPolicy policy) {
+ return mNotifierMock;
+ }
+
+ SuspendBlocker createSuspendBlocker(PowerManagerService service, String name) {
+ return mock(SuspendBlocker.class);
+ }
+
+ BatterySaverPolicy createBatterySaverPolicy(
+ Object lock, Context context, BatterySavingStats batterySavingStats) {
+ return mBatterySaverPolicyMock;
+ }
+
+ NativeWrapper createNativeWrapper() {
+ return mNativeWrapperMock;
+ }
+ });
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ LocalServices.removeServiceForTest(LightsManager.class);
+ LocalServices.removeServiceForTest(DisplayManagerInternal.class);
+ LocalServices.removeServiceForTest(BatteryManagerInternal.class);
+ LocalServices.removeServiceForTest(ActivityManagerInternal.class);
+ }
+
+ /**
+ * Creates a mock and registers it to {@link LocalServices}.
+ */
+ private static <T> void addLocalServiceMock(Class<T> clazz, T mock) {
+ LocalServices.removeServiceForTest(clazz);
+ LocalServices.addService(clazz, mock);
}
@SmallTest
@@ -110,6 +172,25 @@
mService.setVrModeEnabled(false);
assertThat(mService.getDesiredScreenPolicyLocked()).isEqualTo(
DisplayPowerRequest.POLICY_BRIGHT);
+ }
+ @SmallTest
+ public void testWakefulnessAwake_InitialValue() throws Exception {
+ assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_AWAKE);
+ }
+
+ @SmallTest
+ public void testWakefulnessSleep_NoDozeSleepFlag() throws Exception {
+ // Start with AWAKE state
+ assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_AWAKE);
+
+ mService.systemReady(null);
+ mService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
+
+ // Take a nap with a flag.
+ mService.getBinderServiceInstance().goToSleep(SystemClock.uptimeMillis(),
+ PowerManager.GO_TO_SLEEP_REASON_APPLICATION, PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
+
+ assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_ASLEEP);
}
}
diff --git a/services/tests/wmtests/src/com/android/server/policy/DummyPolicyTests.java b/services/tests/wmtests/src/com/android/server/policy/DummyPolicyTests.java
new file mode 100644
index 0000000..03fb123
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/policy/DummyPolicyTests.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.policy;
+
+import android.platform.test.annotations.Presubmit;
+
+import org.junit.Test;
+
+import androidx.test.filters.FlakyTest;
+
+/**
+ * Dummy test for com.android.server.policy.
+ * TODO(b/113800711): Remove this class once the actual tests are moved from servicestests.
+ */
+public class DummyPolicyTests {
+
+ @Presubmit
+ @Test
+ public void preSubmitTest() {}
+
+ @FlakyTest
+ @Presubmit
+ @Test
+ public void flakyPreSubmitTest() {}
+
+ @Test
+ public void postSubmitTest() {}
+
+ @FlakyTest
+ @Test
+ public void flakyPostSubmitTest() {}
+}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index c5d6dc7..99ad1f4 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -19,6 +19,8 @@
import android.Manifest;
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
+
+import com.android.internal.app.IVoiceActionCheckCallback;
import com.android.server.wm.ActivityTaskManagerInternal;
import android.app.AppGlobals;
import android.content.ComponentName;
@@ -1128,6 +1130,27 @@
}
}
+ @Override
+ public void getActiveServiceSupportedActions(List<String> voiceActions,
+ IVoiceActionCheckCallback callback) {
+ enforceCallingPermission(Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE);
+ synchronized (this) {
+ if (mImpl == null) {
+ try {
+ callback.onComplete(null);
+ } catch (RemoteException e) {
+ }
+ return;
+ }
+ final long caller = Binder.clearCallingIdentity();
+ try {
+ mImpl.getActiveServiceSupportedActions(voiceActions, callback);
+ } finally {
+ Binder.restoreCallingIdentity(caller);
+ }
+ }
+ }
+
public void onSessionShown() {
synchronized (this) {
final int size = mVoiceInteractionSessionListeners.beginBroadcast();
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
index 57e9f66..61d7d6c 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
@@ -25,6 +25,8 @@
import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.ActivityTaskManager;
+
+import com.android.internal.app.IVoiceActionCheckCallback;
import com.android.server.wm.ActivityTaskManagerInternal;
import android.app.IActivityManager;
import android.app.IActivityTaskManager;
@@ -57,6 +59,7 @@
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
+import java.util.Set;
class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConnection.Callback {
final static String TAG = "VoiceInteractionServiceManager";
@@ -177,6 +180,23 @@
activityTokens);
}
+ public void getActiveServiceSupportedActions(List<String> commands,
+ IVoiceActionCheckCallback callback) {
+ if (mService == null) {
+ Slog.w(TAG, "Not bound to voice interaction service " + mComponent);
+ try {
+ callback.onComplete(null);
+ } catch (RemoteException e) {
+ }
+ return;
+ }
+ try {
+ mService.getActiveServiceSupportedActions(commands, callback);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "RemoteException while calling getActiveServiceSupportedActions", e);
+ }
+ }
+
public boolean hideSessionLocked() {
if (mActiveSession != null) {
return mActiveSession.hideLocked();
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index fa24796..b5d1f06 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -6217,36 +6217,25 @@
/**
* @deprecated Use {@link android.telecom.TelecomManager#endCall()} instead.
* @hide
+ * @removed
*/
@Deprecated
@SystemApi
@RequiresPermission(android.Manifest.permission.CALL_PHONE)
public boolean endCall() {
- try {
- ITelephony telephony = getITelephony();
- if (telephony != null)
- return telephony.endCall();
- } catch (RemoteException e) {
- Log.e(TAG, "Error calling ITelephony#endCall", e);
- }
return false;
}
/**
* @deprecated Use {@link android.telecom.TelecomManager#acceptRingingCall} instead
* @hide
+ * @removed
*/
@Deprecated
@SystemApi
@RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
public void answerRingingCall() {
- try {
- ITelephony telephony = getITelephony();
- if (telephony != null)
- telephony.answerRingingCall();
- } catch (RemoteException e) {
- Log.e(TAG, "Error calling ITelephony#answerRingingCall", e);
- }
+
}
/**