Merge changes I8953967a,If17eddad into oc-dev
* changes: Add go to web action for instant apps Fix when instant app notif is showing
This commit is contained in:
@@ -1988,6 +1988,9 @@
|
||||
<!-- Action label for launching app info on the specified app [CHAR LIMIT=20] -->
|
||||
<string name="app_info">App info</string>
|
||||
|
||||
<!-- Action label for switching to web for an instant app [CHAR LIMIT=20] -->
|
||||
<string name="go_to_web">Go to web</string>
|
||||
|
||||
<!-- Quick settings tile for toggling mobile data [CHAR LIMIT=20] -->
|
||||
<string name="mobile_data">Mobile data</string>
|
||||
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the
|
||||
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui;
|
||||
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
import android.view.IDockedStackListener;
|
||||
import android.view.WindowManagerGlobal;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Utility wrapper to listen for whether or not a docked stack exists, to be
|
||||
* used for things like the different overview icon in that mode.
|
||||
*/
|
||||
public class DockedStackExistsListener extends IDockedStackListener.Stub {
|
||||
|
||||
private static final String TAG = "DockedStackExistsListener";
|
||||
|
||||
private final Consumer<Boolean> mCallback;
|
||||
|
||||
private DockedStackExistsListener(Consumer<Boolean> callback) {
|
||||
mCallback = callback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDividerVisibilityChanged(boolean visible) throws RemoteException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDockedStackExistsChanged(final boolean exists) throws RemoteException {
|
||||
mCallback.accept(exists);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDockedStackMinimizedChanged(boolean minimized, long animDuration,
|
||||
boolean isHomeStackResizable) throws RemoteException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAdjustedForImeChanged(boolean adjustedForIme, long animDuration)
|
||||
throws RemoteException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDockSideChanged(int newDockSide) throws RemoteException {
|
||||
}
|
||||
|
||||
public static void register(Consumer<Boolean> callback) {
|
||||
try {
|
||||
WindowManagerGlobal.getWindowManagerService().registerDockedStackListener(
|
||||
new DockedStackExistsListener(callback));
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Failed registering docked stack exists listener", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -47,6 +47,7 @@ import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.DockedStackExistsListener;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.RecentsComponent;
|
||||
import com.android.systemui.plugins.PluginListener;
|
||||
@@ -566,40 +567,10 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav
|
||||
|
||||
getImeSwitchButton().setOnClickListener(mImeSwitcherClickListener);
|
||||
|
||||
try {
|
||||
WindowManagerGlobal.getWindowManagerService().registerDockedStackListener(new Stub() {
|
||||
@Override
|
||||
public void onDividerVisibilityChanged(boolean visible) throws RemoteException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDockedStackExistsChanged(final boolean exists) throws RemoteException {
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mDockedStackExists = exists;
|
||||
updateRecentsIcon();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDockedStackMinimizedChanged(boolean minimized, long animDuration,
|
||||
boolean isHomeStackResizable) throws RemoteException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAdjustedForImeChanged(boolean adjustedForIme, long animDuration)
|
||||
throws RemoteException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDockSideChanged(int newDockSide) throws RemoteException {
|
||||
}
|
||||
});
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Failed registering docked stack exists listener", e);
|
||||
}
|
||||
DockedStackExistsListener.register(exists -> mHandler.post(() -> {
|
||||
mDockedStackExists = exists;
|
||||
updateRecentsIcon();
|
||||
}));
|
||||
}
|
||||
|
||||
void updateRotatedViews() {
|
||||
|
||||
@@ -28,6 +28,7 @@ import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.SynchronousUserSwitchObserver;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
@@ -50,11 +51,11 @@ import android.telecom.TelecomManager;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
|
||||
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
|
||||
import com.android.internal.telephony.IccCardConstants;
|
||||
import com.android.internal.telephony.TelephonyIntents;
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.DockedStackExistsListener;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.SysUiServiceProvider;
|
||||
import com.android.systemui.qs.tiles.DndTile;
|
||||
@@ -82,6 +83,8 @@ import com.android.systemui.statusbar.policy.UserInfoController;
|
||||
import com.android.systemui.statusbar.policy.ZenModeController;
|
||||
import com.android.systemui.util.NotificationChannels;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This class contains all of the policy about which icons are installed in the status
|
||||
* bar at boot time. It goes through the normal API for icons, even though it probably
|
||||
@@ -94,6 +97,7 @@ public class PhoneStatusBarPolicy implements Callback, Callbacks,
|
||||
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
|
||||
|
||||
public static final int LOCATION_STATUS_ICON_ID = R.drawable.stat_sys_location;
|
||||
public static final int NUM_TASKS_FOR_INSTANT_APP_INFO = 5;
|
||||
|
||||
private final String mSlotCast;
|
||||
private final String mSlotHotspot;
|
||||
@@ -132,6 +136,7 @@ public class PhoneStatusBarPolicy implements Callback, Callbacks,
|
||||
private boolean mZenVisible;
|
||||
private boolean mVolumeVisible;
|
||||
private boolean mCurrentUserSetup;
|
||||
private boolean mDockedStackExists;
|
||||
|
||||
private boolean mManagedProfileIconVisible = false;
|
||||
private boolean mManagedProfileInQuietMode = false;
|
||||
@@ -248,6 +253,10 @@ public class PhoneStatusBarPolicy implements Callback, Callbacks,
|
||||
noMan.cancel(notification.getTag(), notification.getId());
|
||||
}
|
||||
}
|
||||
DockedStackExistsListener.register(exists -> {
|
||||
mDockedStackExists = exists;
|
||||
updateForegroundInstantApps();
|
||||
});
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
@@ -495,23 +504,18 @@ public class PhoneStatusBarPolicy implements Callback, Callbacks,
|
||||
IPackageManager pm = AppGlobals.getPackageManager();
|
||||
mCurrentNotifs.clear();
|
||||
try {
|
||||
ArraySet<Integer> stacksToCheck = new ArraySet<>();
|
||||
int[] STACKS_TO_CHECK = new int[]{
|
||||
StackId.FULLSCREEN_WORKSPACE_STACK_ID,
|
||||
StackId.DOCKED_STACK_ID,
|
||||
};
|
||||
for (int i = 0; i < STACKS_TO_CHECK.length; i++) {
|
||||
StackInfo info = ActivityManager.getService().getStackInfo(STACKS_TO_CHECK[i]);
|
||||
if (info == null || info.topActivity == null) continue;
|
||||
String pkg = info.topActivity.getPackageName();
|
||||
if (!hasNotif(notifs, pkg, info.userId)) {
|
||||
// TODO: Optimize by not always needing to get application info.
|
||||
// Maybe cache non-ephemeral packages?
|
||||
ApplicationInfo appInfo = pm.getApplicationInfo(pkg,
|
||||
PackageManager.MATCH_UNINSTALLED_PACKAGES, info.userId);
|
||||
if (appInfo.isInstantApp()) {
|
||||
postEphemeralNotif(pkg, info.userId, appInfo, noMan);
|
||||
}
|
||||
}
|
||||
int focusedId = ActivityManager.getService().getFocusedStackId();
|
||||
if (focusedId == StackId.FULLSCREEN_WORKSPACE_STACK_ID
|
||||
|| focusedId == StackId.FULLSCREEN_WORKSPACE_STACK_ID) {
|
||||
checkStack(StackId.FULLSCREEN_WORKSPACE_STACK_ID, notifs, noMan, pm);
|
||||
}
|
||||
if (mDockedStackExists) {
|
||||
checkStack(StackId.DOCKED_STACK_ID, notifs, noMan, pm);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
e.rethrowFromSystemServer();
|
||||
@@ -521,8 +525,28 @@ public class PhoneStatusBarPolicy implements Callback, Callbacks,
|
||||
new UserHandle(v.second)));
|
||||
}
|
||||
|
||||
private void checkStack(int stackId, ArraySet<Pair<String, Integer>> notifs,
|
||||
NotificationManager noMan, IPackageManager pm) {
|
||||
try {
|
||||
StackInfo info = ActivityManager.getService().getStackInfo(stackId);
|
||||
if (info == null || info.topActivity == null) return;
|
||||
String pkg = info.topActivity.getPackageName();
|
||||
if (!hasNotif(notifs, pkg, info.userId)) {
|
||||
// TODO: Optimize by not always needing to get application info.
|
||||
// Maybe cache non-ephemeral packages?
|
||||
ApplicationInfo appInfo = pm.getApplicationInfo(pkg,
|
||||
PackageManager.MATCH_UNINSTALLED_PACKAGES, info.userId);
|
||||
if (appInfo.isInstantApp()) {
|
||||
postEphemeralNotif(pkg, info.userId, appInfo, noMan, info.taskIds[info.taskIds.length - 1]);
|
||||
}
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
private void postEphemeralNotif(String pkg, int userId, ApplicationInfo appInfo,
|
||||
NotificationManager noMan) {
|
||||
NotificationManager noMan, int taskId) {
|
||||
final Bundle extras = new Bundle();
|
||||
extras.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME,
|
||||
mContext.getString(R.string.instant_apps));
|
||||
@@ -531,12 +555,39 @@ public class PhoneStatusBarPolicy implements Callback, Callbacks,
|
||||
PendingIntent appInfoAction = PendingIntent.getActivity(mContext, 0,
|
||||
new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
|
||||
.setData(Uri.fromParts("package", pkg, null)), 0);
|
||||
// TODO: Add action for go to web as well.
|
||||
Action action = new Notification.Action.Builder(null, mContext.getString(R.string.app_info),
|
||||
appInfoAction).build();
|
||||
|
||||
noMan.notifyAsUser(pkg, SystemMessage.NOTE_INSTANT_APPS,
|
||||
new Notification.Builder(mContext, NotificationChannels.GENERAL)
|
||||
Intent browserIntent = getTaskIntent(taskId, userId);
|
||||
Notification.Builder builder = new Notification.Builder(mContext, NotificationChannels.GENERAL);
|
||||
if (browserIntent != null) {
|
||||
PendingIntent pendingIntent = PendingIntent.getActivity(mContext,
|
||||
0 /* requestCode */, browserIntent, 0 /* flags */);
|
||||
browserIntent.setComponent(null);
|
||||
browserIntent.addFlags(Intent.FLAG_IGNORE_EPHEMERAL);
|
||||
browserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
|
||||
ComponentName aiaComponent = null;
|
||||
try {
|
||||
aiaComponent = AppGlobals.getPackageManager().getInstantAppInstallerComponent();
|
||||
} catch (RemoteException e) {
|
||||
e.rethrowFromSystemServer();
|
||||
}
|
||||
Intent goToWebIntent = new Intent()
|
||||
.setComponent(aiaComponent)
|
||||
.setAction(Intent.ACTION_VIEW)
|
||||
.addCategory(Intent.CATEGORY_BROWSABLE)
|
||||
.putExtra(Intent.EXTRA_PACKAGE_NAME, appInfo.packageName)
|
||||
.putExtra(Intent.EXTRA_VERSION_CODE, appInfo.versionCode)
|
||||
.putExtra(Intent.EXTRA_EPHEMERAL_FAILURE, pendingIntent);
|
||||
|
||||
PendingIntent webPendingIntent = PendingIntent.getActivity(mContext, 0, goToWebIntent, 0);
|
||||
Action webAction = new Notification.Action.Builder(null, mContext.getString(R.string.go_to_web),
|
||||
webPendingIntent).build();
|
||||
builder.addAction(webAction);
|
||||
}
|
||||
|
||||
noMan.notifyAsUser(pkg, SystemMessage.NOTE_INSTANT_APPS, builder
|
||||
.addExtras(extras)
|
||||
.addAction(action)
|
||||
.setContentIntent(appInfoAction)
|
||||
@@ -551,6 +602,17 @@ public class PhoneStatusBarPolicy implements Callback, Callbacks,
|
||||
new UserHandle(userId));
|
||||
}
|
||||
|
||||
private Intent getTaskIntent(int taskId, int userId) {
|
||||
List<ActivityManager.RecentTaskInfo> tasks = mContext.getSystemService(ActivityManager.class)
|
||||
.getRecentTasksForUser(NUM_TASKS_FOR_INSTANT_APP_INFO, 0, userId);
|
||||
for (int i = 0; i < tasks.size(); i++) {
|
||||
if (tasks.get(i).id == taskId) {
|
||||
return tasks.get(i).baseIntent;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean hasNotif(ArraySet<Pair<String, Integer>> notifs, String pkg, int userId) {
|
||||
Pair<String, Integer> key = new Pair<>(pkg, userId);
|
||||
if (notifs.remove(key)) {
|
||||
|
||||
Reference in New Issue
Block a user