Loading core/java/com/android/internal/globalactions/Action.java 0 → 100644 +42 −0 Original line number Diff line number Diff line /* * 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.globalactions; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; /** What each item in the global actions dialog must be able to support. */ public interface Action { /** @return Text that will be announced when dialog is created. {@code null} for none. */ CharSequence getLabelForAccessibility(Context context); /** Create the view that represents this action. */ View create(Context context, View convertView, ViewGroup parent, LayoutInflater inflater); /** Called when the action is selected by the user. */ void onPress(); /** @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. */ boolean showBeforeProvisioning(); /** @return {@code true} if the action is enabled for user interaction. */ boolean isEnabled(); } core/java/com/android/internal/globalactions/ActionsAdapter.java 0 → 100644 +112 −0 Original line number Diff line number Diff line /* * 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.globalactions; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import java.util.function.BooleanSupplier; import java.util.List; /** * The adapter used for the list within the global actions dialog, taking into account whether the * keyguard is showing via {@link LegacyGlobalActions#mKeyguardShowing} and whether the device is * provisioned via {@link LegacyGlobalActions#mDeviceProvisioned}. */ public class ActionsAdapter extends BaseAdapter { private final Context mContext; private final List<Action> mItems; private final BooleanSupplier mDeviceProvisioned; private final BooleanSupplier mKeyguardShowing; public ActionsAdapter(Context context, List<Action> items, BooleanSupplier deviceProvisioned, BooleanSupplier keyguardShowing) { mContext = context; mItems = items; mDeviceProvisioned = deviceProvisioned; mKeyguardShowing = keyguardShowing; } @Override public int getCount() { final boolean keyguardShowing = mKeyguardShowing.getAsBoolean(); final boolean deviceProvisioned = mDeviceProvisioned.getAsBoolean(); int count = 0; for (int i = 0; i < mItems.size(); i++) { final Action action = mItems.get(i); if (keyguardShowing && !action.showDuringKeyguard()) { continue; } if (!deviceProvisioned && !action.showBeforeProvisioning()) { continue; } count++; } return count; } @Override public boolean isEnabled(int position) { return getItem(position).isEnabled(); } @Override public boolean areAllItemsEnabled() { return false; } @Override public Action getItem(int position) { final boolean keyguardShowing = mKeyguardShowing.getAsBoolean(); final boolean deviceProvisioned = mDeviceProvisioned.getAsBoolean(); int filteredPos = 0; for (int i = 0; i < mItems.size(); i++) { final Action action = mItems.get(i); if (keyguardShowing && !action.showDuringKeyguard()) { continue; } if (!deviceProvisioned && !action.showBeforeProvisioning()) { continue; } if (filteredPos == position) { return action; } filteredPos++; } throw new IllegalArgumentException("position " + position + " out of range of showable actions" + ", filtered count=" + getCount() + ", keyguardshowing=" + keyguardShowing + ", provisioned=" + deviceProvisioned); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { Action action = getItem(position); return action.create(mContext, convertView, parent, LayoutInflater.from(mContext)); } } core/java/com/android/internal/globalactions/ActionsDialog.java 0 → 100644 +94 −0 Original line number Diff line number Diff line /* * 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.globalactions; import android.app.Dialog; import android.content.Context; import android.content.DialogInterface; import android.os.Bundle; import android.util.TypedValue; import android.view.accessibility.AccessibilityEvent; import android.view.KeyEvent; import android.widget.ListView; import com.android.internal.app.AlertController; /** A dialog that lists the given Action items to be user selectable. */ public final class ActionsDialog extends Dialog implements DialogInterface { private final Context mContext; private final AlertController mAlert; private final ActionsAdapter mAdapter; public ActionsDialog(Context context, AlertController.AlertParams params) { super(context, getDialogTheme(context)); mContext = getContext(); mAlert = AlertController.create(mContext, this, getWindow()); mAdapter = (ActionsAdapter) params.mAdapter; params.apply(mAlert); } private static int getDialogTheme(Context context) { TypedValue outValue = new TypedValue(); context.getTheme().resolveAttribute(com.android.internal.R.attr.alertDialogTheme, outValue, true); return outValue.resourceId; } @Override protected void onStart() { super.setCanceledOnTouchOutside(true); super.onStart(); } public ListView getListView() { return mAlert.getListView(); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mAlert.installContent(); } @Override public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) { for (int i = 0; i < mAdapter.getCount(); ++i) { CharSequence label = mAdapter.getItem(i).getLabelForAccessibility(getContext()); if (label != null) { event.getText().add(label); } } } return super.dispatchPopulateAccessibilityEvent(event); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (mAlert.onKeyDown(keyCode, event)) { return true; } return super.onKeyDown(keyCode, event); } @Override public boolean onKeyUp(int keyCode, KeyEvent event) { if (mAlert.onKeyUp(keyCode, event)) { return true; } return super.onKeyUp(keyCode, event); } } core/java/com/android/internal/globalactions/LongPressAction.java 0 → 100644 +21 −0 Original line number Diff line number Diff line /* * 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.globalactions; /** An action that also supports long press. */ public interface LongPressAction extends Action { boolean onLongPress(); } core/java/com/android/internal/globalactions/SinglePressAction.java 0 → 100644 +99 −0 Original line number Diff line number Diff line /* * 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.globalactions; import android.content.Context; import android.graphics.drawable.Drawable; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import com.android.internal.R; /** A single press action maintains no state, just responds to a press and takes an action. */ public abstract class SinglePressAction implements Action { private final int mIconResId; private final Drawable mIcon; private final int mMessageResId; private final CharSequence mMessage; protected SinglePressAction(int iconResId, int messageResId) { mIconResId = iconResId; mMessageResId = messageResId; mMessage = null; mIcon = null; } protected SinglePressAction(int iconResId, Drawable icon, CharSequence message) { mIconResId = iconResId; mMessageResId = 0; mMessage = message; mIcon = icon; } @Override public boolean isEnabled() { return true; } public String getStatus() { return null; } @Override abstract public void onPress(); @Override public CharSequence getLabelForAccessibility(Context context) { if (mMessage != null) { return mMessage; } else { return context.getString(mMessageResId); } } @Override public View create( Context context, View convertView, ViewGroup parent, LayoutInflater inflater) { View v = inflater.inflate(R.layout.global_actions_item, parent, false); ImageView icon = v.findViewById(R.id.icon); TextView messageView = v.findViewById(R.id.message); TextView statusView = v.findViewById(R.id.status); final String status = getStatus(); if (!TextUtils.isEmpty(status)) { statusView.setText(status); } else { statusView.setVisibility(View.GONE); } if (mIcon != null) { icon.setImageDrawable(mIcon); icon.setScaleType(ImageView.ScaleType.CENTER_CROP); } else if (mIconResId != 0) { icon.setImageDrawable(context.getDrawable(mIconResId)); } if (mMessage != null) { messageView.setText(mMessage); } else { messageView.setText(mMessageResId); } return v; } } Loading
core/java/com/android/internal/globalactions/Action.java 0 → 100644 +42 −0 Original line number Diff line number Diff line /* * 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.globalactions; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; /** What each item in the global actions dialog must be able to support. */ public interface Action { /** @return Text that will be announced when dialog is created. {@code null} for none. */ CharSequence getLabelForAccessibility(Context context); /** Create the view that represents this action. */ View create(Context context, View convertView, ViewGroup parent, LayoutInflater inflater); /** Called when the action is selected by the user. */ void onPress(); /** @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. */ boolean showBeforeProvisioning(); /** @return {@code true} if the action is enabled for user interaction. */ boolean isEnabled(); }
core/java/com/android/internal/globalactions/ActionsAdapter.java 0 → 100644 +112 −0 Original line number Diff line number Diff line /* * 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.globalactions; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import java.util.function.BooleanSupplier; import java.util.List; /** * The adapter used for the list within the global actions dialog, taking into account whether the * keyguard is showing via {@link LegacyGlobalActions#mKeyguardShowing} and whether the device is * provisioned via {@link LegacyGlobalActions#mDeviceProvisioned}. */ public class ActionsAdapter extends BaseAdapter { private final Context mContext; private final List<Action> mItems; private final BooleanSupplier mDeviceProvisioned; private final BooleanSupplier mKeyguardShowing; public ActionsAdapter(Context context, List<Action> items, BooleanSupplier deviceProvisioned, BooleanSupplier keyguardShowing) { mContext = context; mItems = items; mDeviceProvisioned = deviceProvisioned; mKeyguardShowing = keyguardShowing; } @Override public int getCount() { final boolean keyguardShowing = mKeyguardShowing.getAsBoolean(); final boolean deviceProvisioned = mDeviceProvisioned.getAsBoolean(); int count = 0; for (int i = 0; i < mItems.size(); i++) { final Action action = mItems.get(i); if (keyguardShowing && !action.showDuringKeyguard()) { continue; } if (!deviceProvisioned && !action.showBeforeProvisioning()) { continue; } count++; } return count; } @Override public boolean isEnabled(int position) { return getItem(position).isEnabled(); } @Override public boolean areAllItemsEnabled() { return false; } @Override public Action getItem(int position) { final boolean keyguardShowing = mKeyguardShowing.getAsBoolean(); final boolean deviceProvisioned = mDeviceProvisioned.getAsBoolean(); int filteredPos = 0; for (int i = 0; i < mItems.size(); i++) { final Action action = mItems.get(i); if (keyguardShowing && !action.showDuringKeyguard()) { continue; } if (!deviceProvisioned && !action.showBeforeProvisioning()) { continue; } if (filteredPos == position) { return action; } filteredPos++; } throw new IllegalArgumentException("position " + position + " out of range of showable actions" + ", filtered count=" + getCount() + ", keyguardshowing=" + keyguardShowing + ", provisioned=" + deviceProvisioned); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { Action action = getItem(position); return action.create(mContext, convertView, parent, LayoutInflater.from(mContext)); } }
core/java/com/android/internal/globalactions/ActionsDialog.java 0 → 100644 +94 −0 Original line number Diff line number Diff line /* * 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.globalactions; import android.app.Dialog; import android.content.Context; import android.content.DialogInterface; import android.os.Bundle; import android.util.TypedValue; import android.view.accessibility.AccessibilityEvent; import android.view.KeyEvent; import android.widget.ListView; import com.android.internal.app.AlertController; /** A dialog that lists the given Action items to be user selectable. */ public final class ActionsDialog extends Dialog implements DialogInterface { private final Context mContext; private final AlertController mAlert; private final ActionsAdapter mAdapter; public ActionsDialog(Context context, AlertController.AlertParams params) { super(context, getDialogTheme(context)); mContext = getContext(); mAlert = AlertController.create(mContext, this, getWindow()); mAdapter = (ActionsAdapter) params.mAdapter; params.apply(mAlert); } private static int getDialogTheme(Context context) { TypedValue outValue = new TypedValue(); context.getTheme().resolveAttribute(com.android.internal.R.attr.alertDialogTheme, outValue, true); return outValue.resourceId; } @Override protected void onStart() { super.setCanceledOnTouchOutside(true); super.onStart(); } public ListView getListView() { return mAlert.getListView(); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mAlert.installContent(); } @Override public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) { for (int i = 0; i < mAdapter.getCount(); ++i) { CharSequence label = mAdapter.getItem(i).getLabelForAccessibility(getContext()); if (label != null) { event.getText().add(label); } } } return super.dispatchPopulateAccessibilityEvent(event); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (mAlert.onKeyDown(keyCode, event)) { return true; } return super.onKeyDown(keyCode, event); } @Override public boolean onKeyUp(int keyCode, KeyEvent event) { if (mAlert.onKeyUp(keyCode, event)) { return true; } return super.onKeyUp(keyCode, event); } }
core/java/com/android/internal/globalactions/LongPressAction.java 0 → 100644 +21 −0 Original line number Diff line number Diff line /* * 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.globalactions; /** An action that also supports long press. */ public interface LongPressAction extends Action { boolean onLongPress(); }
core/java/com/android/internal/globalactions/SinglePressAction.java 0 → 100644 +99 −0 Original line number Diff line number Diff line /* * 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.globalactions; import android.content.Context; import android.graphics.drawable.Drawable; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import com.android.internal.R; /** A single press action maintains no state, just responds to a press and takes an action. */ public abstract class SinglePressAction implements Action { private final int mIconResId; private final Drawable mIcon; private final int mMessageResId; private final CharSequence mMessage; protected SinglePressAction(int iconResId, int messageResId) { mIconResId = iconResId; mMessageResId = messageResId; mMessage = null; mIcon = null; } protected SinglePressAction(int iconResId, Drawable icon, CharSequence message) { mIconResId = iconResId; mMessageResId = 0; mMessage = message; mIcon = icon; } @Override public boolean isEnabled() { return true; } public String getStatus() { return null; } @Override abstract public void onPress(); @Override public CharSequence getLabelForAccessibility(Context context) { if (mMessage != null) { return mMessage; } else { return context.getString(mMessageResId); } } @Override public View create( Context context, View convertView, ViewGroup parent, LayoutInflater inflater) { View v = inflater.inflate(R.layout.global_actions_item, parent, false); ImageView icon = v.findViewById(R.id.icon); TextView messageView = v.findViewById(R.id.message); TextView statusView = v.findViewById(R.id.status); final String status = getStatus(); if (!TextUtils.isEmpty(status)) { statusView.setText(status); } else { statusView.setVisibility(View.GONE); } if (mIcon != null) { icon.setImageDrawable(mIcon); icon.setScaleType(ImageView.ScaleType.CENTER_CROP); } else if (mIconResId != 0) { icon.setImageDrawable(context.getDrawable(mIconResId)); } if (mMessage != null) { messageView.setText(mMessage); } else { messageView.setText(mMessageResId); } return v; } }