Merge "[Quick Access Wallet] Update docs, remove debug logs, and fix lint errors" into rvc-dev
This commit is contained in:
@@ -3435,13 +3435,15 @@ package android.service.notification {
|
||||
|
||||
package android.service.quickaccesswallet {
|
||||
|
||||
public interface QuickAccessWalletClient {
|
||||
public interface QuickAccessWalletClient extends java.io.Closeable {
|
||||
method public void addWalletServiceEventListener(@NonNull android.service.quickaccesswallet.QuickAccessWalletClient.WalletServiceEventListener);
|
||||
method public void addWalletServiceEventListener(@NonNull java.util.concurrent.Executor, @NonNull android.service.quickaccesswallet.QuickAccessWalletClient.WalletServiceEventListener);
|
||||
method @NonNull public static android.service.quickaccesswallet.QuickAccessWalletClient create(@NonNull android.content.Context);
|
||||
method @Nullable public android.content.Intent createWalletIntent();
|
||||
method @Nullable public android.content.Intent createWalletSettingsIntent();
|
||||
method public void disconnect();
|
||||
method public void getWalletCards(@NonNull android.service.quickaccesswallet.GetWalletCardsRequest, @NonNull android.service.quickaccesswallet.QuickAccessWalletClient.OnWalletCardsRetrievedCallback);
|
||||
method public void getWalletCards(@NonNull java.util.concurrent.Executor, @NonNull android.service.quickaccesswallet.GetWalletCardsRequest, @NonNull android.service.quickaccesswallet.QuickAccessWalletClient.OnWalletCardsRetrievedCallback);
|
||||
method public boolean isWalletFeatureAvailable();
|
||||
method public boolean isWalletFeatureAvailableWhenDeviceLocked();
|
||||
method public boolean isWalletServiceAvailable();
|
||||
|
||||
@@ -24,8 +24,6 @@ import android.os.RemoteException;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Handles response from the {@link QuickAccessWalletService} for {@link GetWalletCardsRequest}
|
||||
*
|
||||
@@ -56,7 +54,6 @@ final class GetWalletCardsCallbackImpl implements GetWalletCardsCallback {
|
||||
* presented as the selected card.
|
||||
*/
|
||||
public void onSuccess(@NonNull GetWalletCardsResponse response) {
|
||||
Log.i(TAG, "onSuccess");
|
||||
if (isValidResponse(response)) {
|
||||
mHandler.post(() -> onSuccessInternal(response));
|
||||
} else {
|
||||
@@ -78,7 +75,6 @@ final class GetWalletCardsCallbackImpl implements GetWalletCardsCallback {
|
||||
}
|
||||
|
||||
private void onSuccessInternal(GetWalletCardsResponse response) {
|
||||
Log.i(TAG, "onSuccessInternal");
|
||||
if (mCalled) {
|
||||
Log.w(TAG, "already called");
|
||||
return;
|
||||
@@ -86,7 +82,6 @@ final class GetWalletCardsCallbackImpl implements GetWalletCardsCallback {
|
||||
mCalled = true;
|
||||
try {
|
||||
mCallback.onGetWalletCardsSuccess(response);
|
||||
Log.i(TAG, "onSuccessInternal: returned response");
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Error returning wallet cards", e);
|
||||
}
|
||||
@@ -106,29 +101,53 @@ final class GetWalletCardsCallbackImpl implements GetWalletCardsCallback {
|
||||
}
|
||||
|
||||
private boolean isValidResponse(@NonNull GetWalletCardsResponse response) {
|
||||
return response != null
|
||||
&& response.getWalletCards() != null
|
||||
&& response.getSelectedIndex() >= 0
|
||||
&& (response.getWalletCards().isEmpty() // selectedIndex may be 0 when list is empty
|
||||
|| response.getSelectedIndex() < response.getWalletCards().size())
|
||||
&& response.getWalletCards().size() < mRequest.getMaxCards()
|
||||
&& areValidCards(response.getWalletCards());
|
||||
}
|
||||
|
||||
private boolean areValidCards(List<WalletCard> walletCards) {
|
||||
for (WalletCard walletCard : walletCards) {
|
||||
if (walletCard == null
|
||||
|| walletCard.getCardId() == null
|
||||
|| walletCard.getCardImage() == null
|
||||
|| TextUtils.isEmpty(walletCard.getContentDescription())
|
||||
|| walletCard.getPendingIntent() == null) {
|
||||
if (response == null) {
|
||||
Log.w(TAG, "Invalid response: response is null");
|
||||
return false;
|
||||
}
|
||||
if (response.getWalletCards() == null) {
|
||||
Log.w(TAG, "Invalid response: walletCards is null");
|
||||
return false;
|
||||
}
|
||||
if (response.getSelectedIndex() < 0) {
|
||||
Log.w(TAG, "Invalid response: selectedIndex is negative");
|
||||
return false;
|
||||
}
|
||||
if (!response.getWalletCards().isEmpty()
|
||||
&& response.getSelectedIndex() >= response.getWalletCards().size()) {
|
||||
Log.w(TAG, "Invalid response: selectedIndex out of bounds");
|
||||
return false;
|
||||
}
|
||||
if (response.getWalletCards().size() > mRequest.getMaxCards()) {
|
||||
Log.w(TAG, "Invalid response: too many cards");
|
||||
return false;
|
||||
}
|
||||
for (WalletCard walletCard : response.getWalletCards()) {
|
||||
if (walletCard == null) {
|
||||
Log.w(TAG, "Invalid response: card is null");
|
||||
return false;
|
||||
}
|
||||
if (walletCard.getCardId() == null) {
|
||||
Log.w(TAG, "Invalid response: cardId is null");
|
||||
return false;
|
||||
}
|
||||
Icon cardImage = walletCard.getCardImage();
|
||||
if (cardImage == null) {
|
||||
Log.w(TAG, "Invalid response: cardImage is null");
|
||||
return false;
|
||||
}
|
||||
if (cardImage.getType() == Icon.TYPE_BITMAP
|
||||
&& walletCard.getCardImage().getBitmap().getConfig()
|
||||
!= Bitmap.Config.HARDWARE) {
|
||||
Log.w(TAG, "WalletCard bitmaps should be hardware bitmaps");
|
||||
&& cardImage.getBitmap().getConfig() != Bitmap.Config.HARDWARE) {
|
||||
Log.w(TAG, "Invalid response: cardImage bitmaps must be hardware bitmaps");
|
||||
return false;
|
||||
}
|
||||
if (TextUtils.isEmpty(walletCard.getContentDescription())) {
|
||||
Log.w(TAG, "Invalid response: contentDescription is null");
|
||||
return false;
|
||||
}
|
||||
if (walletCard.getPendingIntent() == null) {
|
||||
Log.w(TAG, "Invalid response: pendingIntent is null");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -16,19 +16,23 @@
|
||||
|
||||
package android.service.quickaccesswallet;
|
||||
|
||||
import android.annotation.CallbackExecutor;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.TestApi;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
* Facilitates accessing cards from the {@link QuickAccessWalletService}.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@TestApi
|
||||
public interface QuickAccessWalletClient {
|
||||
public interface QuickAccessWalletClient extends Closeable {
|
||||
|
||||
/**
|
||||
* Create a client for accessing wallet cards from the {@link QuickAccessWalletService}. If the
|
||||
@@ -91,6 +95,14 @@ public interface QuickAccessWalletClient {
|
||||
@NonNull GetWalletCardsRequest request,
|
||||
@NonNull OnWalletCardsRetrievedCallback callback);
|
||||
|
||||
/**
|
||||
* Get wallet cards from the {@link QuickAccessWalletService}.
|
||||
*/
|
||||
void getWalletCards(
|
||||
@NonNull @CallbackExecutor Executor executor,
|
||||
@NonNull GetWalletCardsRequest request,
|
||||
@NonNull OnWalletCardsRetrievedCallback callback);
|
||||
|
||||
/**
|
||||
* Callback for getWalletCards
|
||||
*/
|
||||
@@ -111,12 +123,19 @@ public interface QuickAccessWalletClient {
|
||||
void notifyWalletDismissed();
|
||||
|
||||
/**
|
||||
* Unregister event listener.
|
||||
* Register an event listener.
|
||||
*/
|
||||
void addWalletServiceEventListener(@NonNull WalletServiceEventListener listener);
|
||||
|
||||
/**
|
||||
* Unregister event listener
|
||||
* Register an event listener.
|
||||
*/
|
||||
void addWalletServiceEventListener(
|
||||
@NonNull @CallbackExecutor Executor executor,
|
||||
@NonNull WalletServiceEventListener listener);
|
||||
|
||||
/**
|
||||
* Unregister an event listener
|
||||
*/
|
||||
void removeWalletServiceEventListener(@NonNull WalletServiceEventListener listener);
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ package android.service.quickaccesswallet;
|
||||
|
||||
import static android.service.quickaccesswallet.QuickAccessWalletService.SERVICE_INTERFACE;
|
||||
|
||||
import android.annotation.CallbackExecutor;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.app.ActivityManager;
|
||||
@@ -36,16 +37,19 @@ import android.util.Log;
|
||||
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
* Implements {@link QuickAccessWalletClient}. The client connects, performs requests, waits for
|
||||
* responses, and disconnects automatically after a short period of time. The client may
|
||||
* responses, and disconnects automatically one minute after the last call is performed.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class QuickAccessWalletClientImpl implements QuickAccessWalletClient, ServiceConnection {
|
||||
@@ -78,15 +82,14 @@ public class QuickAccessWalletClientImpl implements QuickAccessWalletClient, Ser
|
||||
|
||||
@Override
|
||||
public boolean isWalletServiceAvailable() {
|
||||
boolean available = mServiceInfo != null;
|
||||
Log.i(TAG, "isWalletServiceAvailable: " + available);
|
||||
return available;
|
||||
return mServiceInfo != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWalletFeatureAvailable() {
|
||||
int currentUser = ActivityManager.getCurrentUser();
|
||||
return checkUserSetupComplete()
|
||||
return currentUser == UserHandle.USER_SYSTEM
|
||||
&& checkUserSetupComplete()
|
||||
&& checkSecureSetting(Settings.Secure.GLOBAL_ACTIONS_PANEL_ENABLED)
|
||||
&& !new LockPatternUtils(mContext).isUserInLockdown(currentUser);
|
||||
}
|
||||
@@ -101,23 +104,29 @@ public class QuickAccessWalletClientImpl implements QuickAccessWalletClient, Ser
|
||||
public void getWalletCards(
|
||||
@NonNull GetWalletCardsRequest request,
|
||||
@NonNull OnWalletCardsRetrievedCallback callback) {
|
||||
getWalletCards(mContext.getMainExecutor(), request, callback);
|
||||
}
|
||||
|
||||
Log.i(TAG, "getWalletCards");
|
||||
|
||||
@Override
|
||||
public void getWalletCards(
|
||||
@NonNull @CallbackExecutor Executor executor,
|
||||
@NonNull GetWalletCardsRequest request,
|
||||
@NonNull OnWalletCardsRetrievedCallback callback) {
|
||||
if (!isWalletServiceAvailable()) {
|
||||
callback.onWalletCardRetrievalError(new GetWalletCardsError(null, null));
|
||||
executor.execute(
|
||||
() -> callback.onWalletCardRetrievalError(new GetWalletCardsError(null, null)));
|
||||
return;
|
||||
}
|
||||
|
||||
BaseCallbacks serviceCallback = new BaseCallbacks() {
|
||||
@Override
|
||||
public void onGetWalletCardsSuccess(GetWalletCardsResponse response) {
|
||||
mHandler.post(() -> callback.onWalletCardsRetrieved(response));
|
||||
executor.execute(() -> callback.onWalletCardsRetrieved(response));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGetWalletCardsFailure(GetWalletCardsError error) {
|
||||
mHandler.post(() -> callback.onWalletCardRetrievalError(error));
|
||||
executor.execute(() -> callback.onWalletCardRetrievalError(error));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -132,11 +141,11 @@ public class QuickAccessWalletClientImpl implements QuickAccessWalletClient, Ser
|
||||
serviceCallback.onGetWalletCardsFailure(new GetWalletCardsError(null, null));
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void selectWalletCard(@NonNull SelectWalletCardRequest request) {
|
||||
Log.i(TAG, "selectWalletCard");
|
||||
if (!isWalletServiceAvailable()) {
|
||||
return;
|
||||
}
|
||||
@@ -153,7 +162,6 @@ public class QuickAccessWalletClientImpl implements QuickAccessWalletClient, Ser
|
||||
if (!isWalletServiceAvailable()) {
|
||||
return;
|
||||
}
|
||||
Log.i(TAG, "notifyWalletDismissed");
|
||||
executeApiCall(new ApiCaller("onWalletDismissed") {
|
||||
@Override
|
||||
public void performApiCall(IQuickAccessWalletService service) throws RemoteException {
|
||||
@@ -164,15 +172,20 @@ public class QuickAccessWalletClientImpl implements QuickAccessWalletClient, Ser
|
||||
|
||||
@Override
|
||||
public void addWalletServiceEventListener(WalletServiceEventListener listener) {
|
||||
addWalletServiceEventListener(mContext.getMainExecutor(), listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addWalletServiceEventListener(
|
||||
@NonNull @CallbackExecutor Executor executor,
|
||||
@NonNull WalletServiceEventListener listener) {
|
||||
if (!isWalletServiceAvailable()) {
|
||||
return;
|
||||
}
|
||||
Log.i(TAG, "registerWalletServiceEventListener");
|
||||
BaseCallbacks callback = new BaseCallbacks() {
|
||||
@Override
|
||||
public void onWalletServiceEvent(WalletServiceEvent event) {
|
||||
Log.i(TAG, "onWalletServiceEvent");
|
||||
mHandler.post(() -> listener.onWalletServiceEvent(event));
|
||||
executor.execute(() -> listener.onWalletServiceEvent(event));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -193,7 +206,6 @@ public class QuickAccessWalletClientImpl implements QuickAccessWalletClient, Ser
|
||||
if (!isWalletServiceAvailable()) {
|
||||
return;
|
||||
}
|
||||
Log.i(TAG, "unregisterWalletServiceEventListener");
|
||||
executeApiCall(new ApiCaller("unregisterListener") {
|
||||
@Override
|
||||
public void performApiCall(IQuickAccessWalletService service) throws RemoteException {
|
||||
@@ -208,9 +220,13 @@ public class QuickAccessWalletClientImpl implements QuickAccessWalletClient, Ser
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
disconnect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnect() {
|
||||
Log.i(TAG, "disconnect");
|
||||
mHandler.post(() -> disconnectInternal(true));
|
||||
}
|
||||
|
||||
@@ -241,18 +257,15 @@ public class QuickAccessWalletClientImpl implements QuickAccessWalletClient, Ser
|
||||
}
|
||||
|
||||
private void connect() {
|
||||
Log.i(TAG, "connect");
|
||||
mHandler.post(this::connectInternal);
|
||||
}
|
||||
|
||||
private void connectInternal() {
|
||||
Log.i(TAG, "connectInternal");
|
||||
if (mServiceInfo == null) {
|
||||
Log.w(TAG, "Wallet service unavailable");
|
||||
return;
|
||||
}
|
||||
if (mIsConnected) {
|
||||
Log.w(TAG, "already connected");
|
||||
return;
|
||||
}
|
||||
mIsConnected = true;
|
||||
@@ -264,23 +277,14 @@ public class QuickAccessWalletClientImpl implements QuickAccessWalletClient, Ser
|
||||
}
|
||||
|
||||
private void onConnectedInternal(IQuickAccessWalletService service) {
|
||||
Log.i(TAG, "onConnectedInternal");
|
||||
if (!mIsConnected) {
|
||||
Log.w(TAG, "onConnectInternal but connection closed");
|
||||
mService = null;
|
||||
return;
|
||||
}
|
||||
mService = service;
|
||||
Log.i(TAG, "onConnectedInternal success: request queue size " + mRequestQueue.size());
|
||||
for (ApiCaller apiCaller : new ArrayList<>(mRequestQueue)) {
|
||||
try {
|
||||
apiCaller.performApiCall(mService);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "onConnectedInternal error", e);
|
||||
apiCaller.onApiError();
|
||||
disconnect();
|
||||
break;
|
||||
}
|
||||
performApiCallInternal(apiCaller, mService);
|
||||
mRequestQueue.remove(apiCaller);
|
||||
}
|
||||
}
|
||||
@@ -290,7 +294,6 @@ public class QuickAccessWalletClientImpl implements QuickAccessWalletClient, Ser
|
||||
* posting a new delayed message.
|
||||
*/
|
||||
private void resetServiceConnectionTimeout() {
|
||||
Log.i(TAG, "resetServiceConnectionTimeout");
|
||||
mHandler.removeMessages(MSG_TIMEOUT_SERVICE);
|
||||
mHandler.postDelayed(
|
||||
() -> disconnectInternal(true),
|
||||
@@ -299,13 +302,11 @@ public class QuickAccessWalletClientImpl implements QuickAccessWalletClient, Ser
|
||||
}
|
||||
|
||||
private void disconnectInternal(boolean clearEventListeners) {
|
||||
Log.i(TAG, "disconnectInternal: " + clearEventListeners);
|
||||
if (!mIsConnected) {
|
||||
Log.w(TAG, "already disconnected");
|
||||
return;
|
||||
}
|
||||
if (clearEventListeners && !mEventListeners.isEmpty()) {
|
||||
Log.i(TAG, "disconnectInternal: clear event listeners");
|
||||
for (WalletServiceEventListener listener : mEventListeners.keySet()) {
|
||||
removeWalletServiceEventListener(listener);
|
||||
}
|
||||
@@ -320,29 +321,33 @@ public class QuickAccessWalletClientImpl implements QuickAccessWalletClient, Ser
|
||||
}
|
||||
|
||||
private void executeApiCall(ApiCaller apiCaller) {
|
||||
Log.i(TAG, "execute: " + apiCaller.mDesc);
|
||||
mHandler.post(() -> executeInternal(apiCaller));
|
||||
}
|
||||
|
||||
private void executeInternal(ApiCaller apiCall) {
|
||||
Log.i(TAG, "executeInternal: " + apiCall.mDesc);
|
||||
private void executeInternal(ApiCaller apiCaller) {
|
||||
if (mIsConnected && mService != null) {
|
||||
try {
|
||||
apiCall.performApiCall(mService);
|
||||
Log.i(TAG, "executeInternal success: " + apiCall.mDesc);
|
||||
resetServiceConnectionTimeout();
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "executeInternal error: " + apiCall.mDesc, e);
|
||||
apiCall.onApiError();
|
||||
disconnect();
|
||||
}
|
||||
performApiCallInternal(apiCaller, mService);
|
||||
} else {
|
||||
Log.i(TAG, "executeInternal: queued" + apiCall.mDesc);
|
||||
mRequestQueue.add(apiCall);
|
||||
mRequestQueue.add(apiCaller);
|
||||
connect();
|
||||
}
|
||||
}
|
||||
|
||||
private void performApiCallInternal(ApiCaller apiCaller, IQuickAccessWalletService service) {
|
||||
if (service == null) {
|
||||
apiCaller.onApiError();
|
||||
return;
|
||||
}
|
||||
try {
|
||||
apiCaller.performApiCall(service);
|
||||
resetServiceConnectionTimeout();
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "executeInternal error: " + apiCaller.mDesc, e);
|
||||
apiCaller.onApiError();
|
||||
disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
private abstract static class ApiCaller {
|
||||
private final String mDesc;
|
||||
|
||||
@@ -350,7 +355,8 @@ public class QuickAccessWalletClientImpl implements QuickAccessWalletClient, Ser
|
||||
this.mDesc = desc;
|
||||
}
|
||||
|
||||
abstract void performApiCall(IQuickAccessWalletService service) throws RemoteException;
|
||||
abstract void performApiCall(IQuickAccessWalletService service)
|
||||
throws RemoteException;
|
||||
|
||||
void onApiError() {
|
||||
Log.w(TAG, "api error: " + mDesc);
|
||||
@@ -359,7 +365,6 @@ public class QuickAccessWalletClientImpl implements QuickAccessWalletClient, Ser
|
||||
|
||||
@Override // ServiceConnection
|
||||
public void onServiceConnected(ComponentName name, IBinder binder) {
|
||||
Log.i(TAG, "onServiceConnected: " + name);
|
||||
IQuickAccessWalletService service = IQuickAccessWalletService.Stub.asInterface(binder);
|
||||
mHandler.post(() -> onConnectedInternal(service));
|
||||
}
|
||||
@@ -367,19 +372,16 @@ public class QuickAccessWalletClientImpl implements QuickAccessWalletClient, Ser
|
||||
@Override // ServiceConnection
|
||||
public void onServiceDisconnected(ComponentName name) {
|
||||
// Do not disconnect, as we may later be re-connected
|
||||
Log.w(TAG, "onServiceDisconnected");
|
||||
}
|
||||
|
||||
@Override // ServiceConnection
|
||||
public void onBindingDied(ComponentName name) {
|
||||
// This is a recoverable error but the client will need to reconnect.
|
||||
Log.w(TAG, "onBindingDied");
|
||||
disconnect();
|
||||
}
|
||||
|
||||
@Override // ServiceConnection
|
||||
public void onNullBinding(ComponentName name) {
|
||||
Log.w(TAG, "onNullBinding");
|
||||
disconnect();
|
||||
}
|
||||
|
||||
|
||||
@@ -66,13 +66,11 @@ class QuickAccessWalletServiceInfo {
|
||||
static QuickAccessWalletServiceInfo tryCreate(@NonNull Context context) {
|
||||
ComponentName defaultPaymentApp = getDefaultPaymentApp(context);
|
||||
if (defaultPaymentApp == null) {
|
||||
Log.d(TAG, "create: default payment app not set");
|
||||
return null;
|
||||
}
|
||||
|
||||
ServiceInfo serviceInfo = getWalletServiceInfo(context, defaultPaymentApp.getPackageName());
|
||||
if (serviceInfo == null) {
|
||||
Log.d(TAG, "create: unable to resolve service intent");
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -180,7 +180,7 @@ public final class WalletCard implements Parcelable {
|
||||
* GetWalletCardsRequest#getCardWidthPx()} and a height of {@link
|
||||
* GetWalletCardsRequest#getCardHeightPx()}. If the card image
|
||||
* does not have these dimensions, it may appear distorted when it
|
||||
* is scaled to fit these dimensions on screen. Bitmaps should be
|
||||
* is scaled to fit these dimensions on screen. Bitmaps must be
|
||||
* of type {@link android.graphics.Bitmap.Config#HARDWARE} for
|
||||
* performance reasons.
|
||||
* @param contentDescription The content description of the card image. This field is
|
||||
|
||||
@@ -116,16 +116,17 @@ import java.util.concurrent.Executor;
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* Helper to show the global actions dialog. Each item is an {@link Action} that
|
||||
* may show depending on whether the keyguard is showing, and whether the device
|
||||
* is provisioned.
|
||||
* Helper to show the global actions dialog. Each item is an {@link Action} that may show depending
|
||||
* on whether the keyguard is showing, and whether the device is provisioned.
|
||||
*/
|
||||
public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
|
||||
DialogInterface.OnShowListener, ConfigurationController.ConfigurationListener {
|
||||
DialogInterface.OnShowListener,
|
||||
ConfigurationController.ConfigurationListener,
|
||||
GlobalActionsPanelPlugin.Callbacks {
|
||||
|
||||
static public final String SYSTEM_DIALOG_REASON_KEY = "reason";
|
||||
static public final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions";
|
||||
static public final String SYSTEM_DIALOG_REASON_DREAM = "dream";
|
||||
public static final String SYSTEM_DIALOG_REASON_KEY = "reason";
|
||||
public static final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions";
|
||||
public static final String SYSTEM_DIALOG_REASON_DREAM = "dream";
|
||||
|
||||
private static final String TAG = "GlobalActionsDialog";
|
||||
|
||||
@@ -271,8 +272,9 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
|
||||
@Override
|
||||
public void onUnlockedChanged() {
|
||||
if (mDialog != null && mDialog.mPanelController != null) {
|
||||
boolean locked = !keyguardStateController.canDismissLockScreen();
|
||||
mDialog.mPanelController.onDeviceLockStateChanged(locked);
|
||||
boolean unlocked = keyguardStateController.isUnlocked()
|
||||
|| keyguardStateController.canDismissLockScreen();
|
||||
mDialog.mPanelController.onDeviceLockStateChanged(unlocked);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -386,7 +388,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
|
||||
mItems.add(getSettingsAction());
|
||||
} else if (GLOBAL_ACTION_KEY_LOCKDOWN.equals(actionKey)) {
|
||||
if (Settings.Secure.getIntForUser(mContentResolver,
|
||||
Settings.Secure.LOCKDOWN_IN_POWER_MENU, 0, getCurrentUser().id) != 0
|
||||
Settings.Secure.LOCKDOWN_IN_POWER_MENU, 0, getCurrentUser().id) != 0
|
||||
&& shouldDisplayLockdown()) {
|
||||
mItems.add(getLockdownAction());
|
||||
}
|
||||
@@ -420,26 +422,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
|
||||
|
||||
mAdapter = new MyAdapter();
|
||||
|
||||
GlobalActionsPanelPlugin.PanelViewController panelViewController =
|
||||
mPanelPlugin != null
|
||||
? mPanelPlugin.onPanelShown(
|
||||
new GlobalActionsPanelPlugin.Callbacks() {
|
||||
@Override
|
||||
public void dismissGlobalActionsMenu() {
|
||||
dismissDialog();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startPendingIntentDismissingKeyguard(
|
||||
PendingIntent intent) {
|
||||
mActivityStarter
|
||||
.startPendingIntentDismissingKeyguard(intent);
|
||||
}
|
||||
},
|
||||
!mKeyguardStateController.isUnlocked())
|
||||
: null;
|
||||
|
||||
ActionsDialog dialog = new ActionsDialog(mContext, mAdapter, panelViewController,
|
||||
ActionsDialog dialog = new ActionsDialog(mContext, mAdapter, getWalletPanelViewController(),
|
||||
mDepthController, mSysuiColorExtractor, mStatusBarService,
|
||||
mNotificationShadeWindowController,
|
||||
shouldShowControls() ? mControlsUiController : null, mBlurUtils);
|
||||
@@ -477,6 +460,33 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
|
||||
mConfigurationController.removeCallback(this);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private GlobalActionsPanelPlugin.PanelViewController getWalletPanelViewController() {
|
||||
if (mPanelPlugin == null) {
|
||||
return null;
|
||||
}
|
||||
return mPanelPlugin.onPanelShown(this, !mKeyguardStateController.isUnlocked());
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements {@link GlobalActionsPanelPlugin.Callbacks#dismissGlobalActionsMenu()}, which is
|
||||
* called when the quick access wallet requests dismissal.
|
||||
*/
|
||||
@Override
|
||||
public void dismissGlobalActionsMenu() {
|
||||
dismissDialog();
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements {@link GlobalActionsPanelPlugin.Callbacks#dismissGlobalActionsMenu()}, which is
|
||||
* called when the quick access wallet requests that an intent be started (with lock screen
|
||||
* shown first if needed).
|
||||
*/
|
||||
@Override
|
||||
public void startPendingIntentDismissingKeyguard(PendingIntent pendingIntent) {
|
||||
mActivityStarter.startPendingIntentDismissingKeyguard(pendingIntent);
|
||||
}
|
||||
|
||||
private final class PowerAction extends SinglePressAction implements LongPressAction {
|
||||
private PowerAction() {
|
||||
super(R.drawable.ic_lock_power_off,
|
||||
@@ -919,7 +929,9 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
|
||||
}
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void onDismiss(DialogInterface dialog) {
|
||||
if (mDialog == dialog) {
|
||||
mDialog = null;
|
||||
@@ -935,17 +947,19 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
|
||||
}
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void onShow(DialogInterface dialog) {
|
||||
mMetricsLogger.visible(MetricsEvent.POWER_MENU);
|
||||
}
|
||||
|
||||
/**
|
||||
* The adapter used for the list within the global actions dialog, taking
|
||||
* into account whether the keyguard is showing via
|
||||
* {@link com.android.systemui.globalactions.GlobalActionsDialog#mKeyguardShowing} and whether
|
||||
* the device is provisioned
|
||||
* via {@link com.android.systemui.globalactions.GlobalActionsDialog#mDeviceProvisioned}.
|
||||
* The adapter used for the list within the global actions dialog, taking into account whether
|
||||
* the keyguard is showing via
|
||||
* {@link com.android.systemui.globalactions.GlobalActionsDialog#mKeyguardShowing}
|
||||
* and whether the device is provisioned via
|
||||
* {@link com.android.systemui.globalactions.GlobalActionsDialog#mDeviceProvisioned}.
|
||||
*/
|
||||
public class MyAdapter extends MultiListAdapter {
|
||||
private int countItems(boolean separated) {
|
||||
@@ -1076,8 +1090,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
|
||||
*/
|
||||
public interface Action {
|
||||
/**
|
||||
* @return Text that will be announced when dialog is created. null
|
||||
* for none.
|
||||
* @return Text that will be announced when dialog is created. null for none.
|
||||
*/
|
||||
CharSequence getLabelForAccessibility(Context context);
|
||||
|
||||
@@ -1086,15 +1099,13 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
|
||||
void onPress();
|
||||
|
||||
/**
|
||||
* @return whether this action should appear in the dialog when the keygaurd
|
||||
* is showing.
|
||||
* @return whether this action should appear in the dialog when the keygaurd is showing.
|
||||
*/
|
||||
boolean showDuringKeyguard();
|
||||
|
||||
/**
|
||||
* @return whether this action should appear in the dialog before the
|
||||
* device is provisioned.onlongpress
|
||||
*
|
||||
* @return whether this action should appear in the dialog before the device is
|
||||
* provisioned.onlongpress
|
||||
*/
|
||||
boolean showBeforeProvisioning();
|
||||
|
||||
@@ -1113,8 +1124,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
|
||||
}
|
||||
|
||||
/**
|
||||
* A single press action maintains no state, just responds to a press
|
||||
* and takes an action.
|
||||
* A single press action maintains no state, just responds to a press and takes an action.
|
||||
*/
|
||||
|
||||
private abstract class SinglePressAction implements Action {
|
||||
@@ -1188,8 +1198,8 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
|
||||
}
|
||||
|
||||
/**
|
||||
* A toggle action knows whether it is on or off, and displays an icon
|
||||
* and status message accordingly.
|
||||
* A toggle action knows whether it is on or off, and displays an icon and status message
|
||||
* accordingly.
|
||||
*/
|
||||
private static abstract class ToggleAction implements Action {
|
||||
|
||||
@@ -1239,8 +1249,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
|
||||
}
|
||||
|
||||
/**
|
||||
* Override to make changes to resource IDs just before creating the
|
||||
* View.
|
||||
* Override to make changes to resource IDs just before creating the View.
|
||||
*/
|
||||
void willCreate() {
|
||||
|
||||
@@ -1296,9 +1305,9 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementations may override this if their state can be in on of the intermediate
|
||||
* states until some notification is received (e.g airplane mode is 'turning off' until
|
||||
* we know the wireless connections are back online
|
||||
* Implementations may override this if their state can be in on of the intermediate states
|
||||
* until some notification is received (e.g airplane mode is 'turning off' until we know the
|
||||
* wireless connections are back online
|
||||
*
|
||||
* @param buttonOn Whether the button was turned on or off
|
||||
*/
|
||||
@@ -1316,12 +1325,13 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
|
||||
private class AirplaneModeAction extends ToggleAction {
|
||||
AirplaneModeAction() {
|
||||
super(
|
||||
R.drawable.ic_lock_airplane_mode,
|
||||
R.drawable.ic_lock_airplane_mode_off,
|
||||
R.string.global_actions_toggle_airplane_mode,
|
||||
R.string.global_actions_airplane_mode_on_status,
|
||||
R.string.global_actions_airplane_mode_off_status);
|
||||
R.drawable.ic_lock_airplane_mode,
|
||||
R.drawable.ic_lock_airplane_mode_off,
|
||||
R.string.global_actions_toggle_airplane_mode,
|
||||
R.string.global_actions_airplane_mode_on_status,
|
||||
R.string.global_actions_airplane_mode_off_status);
|
||||
}
|
||||
|
||||
void onToggle(boolean on) {
|
||||
if (mHasTelephony && TelephonyProperties.in_ecm_mode().orElse(false)) {
|
||||
mIsWaitingForEcmExit = true;
|
||||
@@ -1607,11 +1617,11 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
|
||||
window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
|
||||
window.addFlags(
|
||||
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
|
||||
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
|
||||
| WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR
|
||||
| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
|
||||
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
|
||||
| WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
|
||||
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
|
||||
| WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR
|
||||
| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
|
||||
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
|
||||
| WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
|
||||
window.setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY);
|
||||
window.getAttributes().setFitInsetsTypes(0 /* types */);
|
||||
setTitle(R.string.global_actions);
|
||||
@@ -1755,7 +1765,8 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
|
||||
|
||||
/**
|
||||
* Updates background and system bars according to current GradientColors.
|
||||
* @param colors Colors and hints to use.
|
||||
*
|
||||
* @param colors Colors and hints to use.
|
||||
* @param animate Interpolates gradient if true, just sets otherwise.
|
||||
*/
|
||||
private void updateColors(GradientColors colors, boolean animate) {
|
||||
@@ -1921,8 +1932,8 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether or not the Global Actions menu should be forced to
|
||||
* use the newer grid-style layout.
|
||||
* Determines whether or not the Global Actions menu should be forced to use the newer
|
||||
* grid-style layout.
|
||||
*/
|
||||
private static boolean isForceGridEnabled(Context context) {
|
||||
return isPanelDebugModeEnabled(context);
|
||||
|
||||
Reference in New Issue
Block a user