Expose the HomeVisibilityListener API
Rename HomeVisibilityObserver to HomeVisibilityListener and expose it as module-only API. This listener is used by the SIM toolkit to detect when the home screen is visible. Also fix some bugs in the original implementation that were uncovered during CTS writing. Fixes: 170226810 Test: atest ActivityManagerTest#testHomeVisibilityListener Change-Id: I5d99f2bad144711d7135cc800921abf01df6235d
This commit is contained in:
@@ -1,10 +1,20 @@
|
||||
// Signature format: 2.0
|
||||
package android.app {
|
||||
|
||||
public class ActivityManager {
|
||||
method @RequiresPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) public void addHomeVisibilityListener(@NonNull java.util.concurrent.Executor, @NonNull android.app.HomeVisibilityListener);
|
||||
method @RequiresPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) public void removeHomeVisibilityListener(@NonNull android.app.HomeVisibilityListener);
|
||||
}
|
||||
|
||||
public class AppOpsManager {
|
||||
field public static final String OPSTR_NO_ISOLATED_STORAGE = "android:no_isolated_storage";
|
||||
}
|
||||
|
||||
public abstract class HomeVisibilityListener {
|
||||
ctor public HomeVisibilityListener();
|
||||
method public abstract void onHomeVisibilityChanged(boolean);
|
||||
}
|
||||
|
||||
public class NotificationManager {
|
||||
method public boolean hasEnabledNotificationListener(@NonNull String, @NonNull android.os.UserHandle);
|
||||
field public static final String ACTION_NOTIFICATION_LISTENER_ENABLED_CHANGED = "android.app.action.NOTIFICATION_LISTENER_ENABLED_CHANGED";
|
||||
|
||||
@@ -77,6 +77,7 @@ package android.app {
|
||||
}
|
||||
|
||||
public class ActivityManager {
|
||||
method @RequiresPermission("android.permission.SET_ACTIVITY_WATCHER") public void addHomeVisibilityListener(@NonNull java.util.concurrent.Executor, @NonNull android.app.HomeVisibilityListener);
|
||||
method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public void addOnUidImportanceListener(android.app.ActivityManager.OnUidImportanceListener, int);
|
||||
method public void alwaysShowUnsupportedCompileSdkWarning(android.content.ComponentName);
|
||||
method @RequiresPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) public void forceStopPackage(String);
|
||||
@@ -86,6 +87,7 @@ package android.app {
|
||||
method @RequiresPermission("android.permission.INJECT_EVENTS") public void holdLock(int);
|
||||
method public static boolean isHighEndGfx();
|
||||
method @RequiresPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) public void killProcessesWhenImperceptible(@NonNull int[], @NonNull String);
|
||||
method @RequiresPermission("android.permission.SET_ACTIVITY_WATCHER") public void removeHomeVisibilityListener(@NonNull android.app.HomeVisibilityListener);
|
||||
method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public void removeOnUidImportanceListener(android.app.ActivityManager.OnUidImportanceListener);
|
||||
method @RequiresPermission(android.Manifest.permission.RESET_APP_ERRORS) public void resetAppErrors();
|
||||
method public static void resumeAppSwitches() throws android.os.RemoteException;
|
||||
@@ -456,6 +458,11 @@ package android.app {
|
||||
method @RequiresPermission("android.permission.WRITE_DREAM_STATE") public void stopDream();
|
||||
}
|
||||
|
||||
public abstract class HomeVisibilityListener {
|
||||
ctor public HomeVisibilityListener();
|
||||
method public abstract void onHomeVisibilityChanged(boolean);
|
||||
}
|
||||
|
||||
public final class NotificationChannel implements android.os.Parcelable {
|
||||
method public int getOriginalImportance();
|
||||
method public boolean isBlockable();
|
||||
|
||||
@@ -100,6 +100,7 @@ import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -4752,31 +4753,43 @@ public class ActivityManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Register with {@link HomeVisibilityObserver} with ActivityManager.
|
||||
* TODO: b/144351078 expose as SystemApi
|
||||
* Register to be notified when the visibility of the home screen changes.
|
||||
*
|
||||
* @param executor The executor on which the listener should be called.
|
||||
* @param listener The listener that is called when home visibility changes.
|
||||
* @hide
|
||||
*/
|
||||
public void registerHomeVisibilityObserver(@NonNull HomeVisibilityObserver observer) {
|
||||
Preconditions.checkNotNull(observer);
|
||||
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
|
||||
@TestApi
|
||||
@RequiresPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
|
||||
public void addHomeVisibilityListener(@NonNull Executor executor,
|
||||
@NonNull HomeVisibilityListener listener) {
|
||||
Preconditions.checkNotNull(listener);
|
||||
Preconditions.checkNotNull(executor);
|
||||
try {
|
||||
observer.init(mContext, this);
|
||||
getService().registerProcessObserver(observer.mObserver);
|
||||
listener.init(mContext, executor, this);
|
||||
getService().registerProcessObserver(listener.mObserver);
|
||||
// Notify upon first registration.
|
||||
observer.onHomeVisibilityChanged(observer.mIsHomeActivityVisible);
|
||||
executor.execute(() ->
|
||||
listener.onHomeVisibilityChanged(listener.mIsHomeActivityVisible));
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister with {@link HomeVisibilityObserver} with ActivityManager.
|
||||
* TODO: b/144351078 expose as SystemApi
|
||||
* Removes a listener that was previously added with {@link #addHomeVisibilityListener}.
|
||||
*
|
||||
* @param listener The listener that was previously added.
|
||||
* @hide
|
||||
*/
|
||||
public void unregisterHomeVisibilityObserver(@NonNull HomeVisibilityObserver observer) {
|
||||
Preconditions.checkNotNull(observer);
|
||||
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
|
||||
@TestApi
|
||||
@RequiresPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
|
||||
public void removeHomeVisibilityListener(@NonNull HomeVisibilityListener listener) {
|
||||
Preconditions.checkNotNull(listener);
|
||||
try {
|
||||
getService().unregisterProcessObserver(observer.mObserver);
|
||||
getService().unregisterProcessObserver(listener.mObserver);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
|
||||
@@ -16,49 +16,56 @@
|
||||
|
||||
package android.app;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.annotation.SystemApi;
|
||||
import android.annotation.TestApi;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.os.Binder;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
* An observer / callback to create and register by
|
||||
* {@link ActivityManager#registerHomeVisibilityObserver} so that it's triggered when
|
||||
* visibility of home page changes.
|
||||
* TODO: b/144351078 expose as SystemApi
|
||||
* A listener that will be invoked when the visibility of the home screen changes.
|
||||
* Register this callback via {@link ActivityManager#addHomeVisibilityListener}
|
||||
* @hide
|
||||
*/
|
||||
public abstract class HomeVisibilityObserver {
|
||||
// This is a single-method listener that needs a bunch of supporting code, so it can't be an
|
||||
// interface
|
||||
@SuppressLint("ListenerInterface")
|
||||
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
|
||||
@TestApi
|
||||
public abstract class HomeVisibilityListener {
|
||||
private Context mContext;
|
||||
private ActivityManager mActivityManager;
|
||||
private Executor mExecutor;
|
||||
/** @hide */
|
||||
IProcessObserver.Stub mObserver;
|
||||
android.app.IProcessObserver.Stub mObserver;
|
||||
/** @hide */
|
||||
boolean mIsHomeActivityVisible;
|
||||
|
||||
/** @hide */
|
||||
void init(Context context, ActivityManager activityManager) {
|
||||
void init(Context context, Executor executor, ActivityManager activityManager) {
|
||||
mContext = context;
|
||||
mActivityManager = activityManager;
|
||||
mIsHomeActivityVisible = isHomeActivityVisible();
|
||||
mExecutor = executor;
|
||||
}
|
||||
|
||||
/**
|
||||
* The API that needs implemented and will be triggered when activity on home page changes.
|
||||
* Called when the visibility of the home screen changes.
|
||||
*
|
||||
* @param isHomeActivityVisible Whether the home screen activity is now visible.
|
||||
*/
|
||||
public abstract void onHomeVisibilityChanged(boolean isHomeActivityVisible);
|
||||
|
||||
public HomeVisibilityObserver() {
|
||||
mObserver = new IProcessObserver.Stub() {
|
||||
public HomeVisibilityListener() {
|
||||
mObserver = new android.app.IProcessObserver.Stub() {
|
||||
@Override
|
||||
public void onForegroundActivitiesChanged(int pid, int uid, boolean fg) {
|
||||
boolean isHomeActivityVisible = isHomeActivityVisible();
|
||||
if (mIsHomeActivityVisible != isHomeActivityVisible) {
|
||||
mIsHomeActivityVisible = isHomeActivityVisible;
|
||||
onHomeVisibilityChanged(mIsHomeActivityVisible);
|
||||
}
|
||||
refreshHomeVisibility();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -67,6 +74,17 @@ public abstract class HomeVisibilityObserver {
|
||||
|
||||
@Override
|
||||
public void onProcessDied(int pid, int uid) {
|
||||
refreshHomeVisibility();
|
||||
}
|
||||
|
||||
private void refreshHomeVisibility() {
|
||||
boolean isHomeActivityVisible = isHomeActivityVisible();
|
||||
if (mIsHomeActivityVisible != isHomeActivityVisible) {
|
||||
mIsHomeActivityVisible = isHomeActivityVisible;
|
||||
Binder.withCleanCallingIdentity(() ->
|
||||
mExecutor.execute(() ->
|
||||
onHomeVisibilityChanged(mIsHomeActivityVisible)));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -83,12 +101,9 @@ public abstract class HomeVisibilityObserver {
|
||||
}
|
||||
|
||||
// We can assume that the screen is idle if the home application is in the foreground.
|
||||
final Intent intent = new Intent(Intent.ACTION_MAIN, null);
|
||||
intent.addCategory(Intent.CATEGORY_HOME);
|
||||
|
||||
ResolveInfo info = mContext.getPackageManager().resolveActivity(intent,
|
||||
PackageManager.MATCH_DEFAULT_ONLY);
|
||||
if (info != null && top.equals(info.activityInfo.packageName)) {
|
||||
String defaultHomePackage = mContext.getPackageManager()
|
||||
.getHomeActivities(new ArrayList<>()).getPackageName();
|
||||
if (Objects.equals(top, defaultHomePackage)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,20 @@
|
||||
// Signature format: 2.0
|
||||
package android.app {
|
||||
|
||||
public class ActivityManager {
|
||||
method @RequiresPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) public void addHomeVisibilityListener(@NonNull java.util.concurrent.Executor, @NonNull android.app.HomeVisibilityListener);
|
||||
method @RequiresPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) public void removeHomeVisibilityListener(@NonNull android.app.HomeVisibilityListener);
|
||||
}
|
||||
|
||||
public class AppOpsManager {
|
||||
field public static final String OPSTR_NO_ISOLATED_STORAGE = "android:no_isolated_storage";
|
||||
}
|
||||
|
||||
public abstract class HomeVisibilityListener {
|
||||
ctor public HomeVisibilityListener();
|
||||
method public abstract void onHomeVisibilityChanged(boolean);
|
||||
}
|
||||
|
||||
public class NotificationManager {
|
||||
method public boolean hasEnabledNotificationListener(@NonNull String, @NonNull android.os.UserHandle);
|
||||
field public static final String ACTION_NOTIFICATION_LISTENER_ENABLED_CHANGED = "android.app.action.NOTIFICATION_LISTENER_ENABLED_CHANGED";
|
||||
|
||||
Reference in New Issue
Block a user