+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 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.
--->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-
- <item
- android:state_enabled="true"
- android:state_active="false"
- android:state_focused="false"
- android:drawable="@drawable/ic_action_assist_generic_normal" />
-
- <item
- android:state_enabled="true"
- android:state_active="true"
- android:state_focused="false"
- android:drawable="@drawable/ic_action_assist_generic_activated" />
-
- <item
- android:state_enabled="true"
- android:state_active="false"
- android:state_focused="true"
- android:drawable="@drawable/ic_action_assist_generic_activated" />
-
-</selector>
android:orientation="horizontal"
android:gravity="@integer/kg_selector_gravity"
android:contentDescription="@string/keyguard_accessibility_slide_area"
-
- prvandroid:targetDrawables="@array/lockscreen_targets_unlock_only"
- prvandroid:targetDescriptions="@array/lockscreen_target_descriptions_unlock_only"
- prvandroid:directionDescriptions="@array/lockscreen_direction_descriptions"
prvandroid:handleDrawable="@drawable/ic_lockscreen_handle"
prvandroid:outerRingDrawable="@drawable/ic_lockscreen_outerring"
prvandroid:outerRadius="@dimen/glowpadview_target_placement_radius"
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/common/assets/res/any/colors.xml
-**
-** Copyright 2006, 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.
-*/
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-
- <!-- Resources for GlowPadView in LockScreen -->
- <array name="lockscreen_targets_when_silent">
- <item>@null</item>"
- <item>@drawable/ic_action_assist_generic</item>
- <item>@drawable/ic_lockscreen_soundon</item>
- <item>@drawable/ic_lockscreen_unlock</item>
- </array>
-
- <array name="lockscreen_target_descriptions_when_silent">
- <item>@null</item>
- <item>@string/description_target_search</item>
- <item>@string/description_target_soundon</item>
- <item>@string/description_target_unlock</item>
- </array>
-
- <array name="lockscreen_direction_descriptions">
- <item>@null</item>
- <item>@string/description_direction_up</item>
- <item>@string/description_direction_left</item>
- <item>@string/description_direction_down</item>
- </array>
-
- <array name="lockscreen_targets_when_soundon">
- <item>@null</item>
- <item>@drawable/ic_action_assist_generic</item>
- <item>@drawable/ic_lockscreen_silent</item>
- <item>@drawable/ic_lockscreen_unlock</item>
- </array>
-
- <array name="lockscreen_target_descriptions_when_soundon">
- <item>@null</item>
- <item>@string/description_target_search</item>
- <item>@string/description_target_silent</item>
- <item>@string/description_target_unlock</item>
- </array>
-
- <array name="lockscreen_targets_with_camera">
- <item>@null</item>
- <item>@drawable/ic_action_assist_generic</item>
- <item>@drawable/ic_lockscreen_camera</item>
- <item>@drawable/ic_lockscreen_unlock</item>
- </array>
-
- <array name="lockscreen_target_descriptions_with_camera">
- <item>@null</item>
- <item>@string/description_target_search</item>
- <item>@string/description_target_camera</item>
- <item>@string/description_target_unlock</item>
- </array>
-
-</resources>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/common/assets/res/any/colors.xml
-**
-** Copyright 2006, 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.
-*/
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-
- <!-- Resources for GlowPadView in LockScreen -->
- <array name="lockscreen_targets_when_silent">
- <item>@drawable/ic_lockscreen_unlock</item>
- <item>@null</item>
- <item>@drawable/ic_lockscreen_soundon</item>
- <item>@null</item>
- </array>
-
- <array name="lockscreen_target_descriptions_when_silent">
- <item>@string/description_target_unlock</item>
- <item>@null</item>
- <item>@string/description_target_soundon</item>
- <item>@null</item>
- </array>
-
- <array name="lockscreen_direction_descriptions">
- <item>@string/description_direction_right</item>
- <item>@null</item>
- <item>@string/description_direction_left</item>
- <item>@null</item>
- </array>
-
- <array name="lockscreen_targets_when_soundon">
- <item>@drawable/ic_lockscreen_unlock</item>
- <item>@null</item>
- <item>@drawable/ic_lockscreen_silent</item>
- <item>@null</item>
- </array>
-
- <array name="lockscreen_target_descriptions_when_soundon">
- <item>@string/description_target_unlock</item>
- <item>@null</item>
- <item>@string/description_target_silent</item>
- <item>@null</item>
- </array>
-
- <array name="lockscreen_targets_with_camera">
- <item>@drawable/ic_lockscreen_unlock</item>
- <item>@drawable/ic_action_assist_generic</item>
- <item>@drawable/ic_lockscreen_camera</item>
- <item>@null</item>
- </array>
-
- <array name="lockscreen_target_descriptions_with_camera">
- <item>@string/description_target_unlock</item>
- <item>@string/description_target_search</item>
- <item>@string/description_target_camera</item>
- <item>@null</item>
- </array>
-
-</resources>
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- Resources for GlowPadView in LockScreen -->
- <array name="lockscreen_targets_when_silent">
- <item>@drawable/ic_lockscreen_unlock</item>
- <item>@drawable/ic_action_assist_generic</item>
- <item>@drawable/ic_lockscreen_soundon</item>
- <item>@null</item>
- </array>
-
- <array name="lockscreen_target_descriptions_when_silent">
- <item>@string/description_target_unlock</item>
- <item>@string/description_target_search</item>
- <item>@string/description_target_soundon</item>
- <item>@null</item>
- </array>
-
- <array name="lockscreen_direction_descriptions">
- <item>@string/description_direction_right</item>
- <item>@string/description_direction_up</item>
- <item>@string/description_direction_left</item>
- <item>@null</item>
- </array>
-
- <array name="lockscreen_targets_when_soundon">
- <item>@drawable/ic_lockscreen_unlock</item>
- <item>@drawable/ic_action_assist_generic</item>
- <item>@drawable/ic_lockscreen_silent</item>
- <item>@null</item>
- </array>
-
- <array name="lockscreen_target_descriptions_when_soundon">
- <item>@string/description_target_unlock</item>
- <item>@string/description_target_search</item>
- <item>@string/description_target_silent</item>
- <item>@null</item>
- </array>
-
- <array name="lockscreen_targets_with_camera">
- <item>@drawable/ic_lockscreen_unlock</item>
- <item>@drawable/ic_action_assist_generic</item>
- <item>@drawable/ic_lockscreen_camera</item>
- <item>@null</item>
- </array>
-
- <array name="lockscreen_target_descriptions_with_camera">
- <item>@string/description_target_unlock</item>
- <item>@string/description_target_search</item>
- <item>@string/description_target_camera</item>
- <item>@null</item>
- </array>
-
- <array name="lockscreen_targets_unlock_only">
- <item>@drawable/ic_lockscreen_unlock</item>
- </array>
-
- <array name="lockscreen_target_descriptions_unlock_only">
- <item>@string/description_target_unlock</item>
- </array>
-
<!-- list of 3- or 4-letter mnemonics for a 10-key numeric keypad -->
<string-array translatable="false" name="lockscreen_num_pad_klondike">
<item>+</item><!-- 0 -->
@Override
public void onResume(int reason) {
- getSecurityView(mCurrentSecuritySelection).onResume(reason);
+ if (mCurrentSecuritySelection != SecurityMode.None) {
+ getSecurityView(mCurrentSecuritySelection).onResume(reason);
+ }
}
@Override
public void onPause() {
- getSecurityView(mCurrentSecuritySelection).onPause();
+ if (mCurrentSecuritySelection != SecurityMode.None) {
+ getSecurityView(mCurrentSecuritySelection).onPause();
+ }
}
public void startAppearAnimation() {
- getSecurityView(mCurrentSecuritySelection).startAppearAnimation();
+ if (mCurrentSecuritySelection != SecurityMode.None) {
+ getSecurityView(mCurrentSecuritySelection).startAppearAnimation();
+ }
}
void updateSecurityViews(boolean isBouncing) {
view = (KeyguardSecurityView)v;
}
- if (view instanceof KeyguardSelectorView) {
- KeyguardSelectorView selectorView = (KeyguardSelectorView) view;
- View carrierText = selectorView.findViewById(R.id.keyguard_selector_fade_container);
- selectorView.setCarrierArea(carrierText);
- }
-
return view;
}
oldView.onPause();
oldView.setKeyguardCallback(mNullCallback); // ignore requests from old view
}
- newView.onResume(KeyguardSecurityView.VIEW_REVEALED);
- newView.setKeyguardCallback(mCallback);
+ if (securityMode != SecurityMode.None) {
+ newView.onResume(KeyguardSecurityView.VIEW_REVEALED);
+ newView.setKeyguardCallback(mCallback);
+ }
// Find and show this child.
final int childCount = mSecurityViewFlipper.getChildCount();
}
mCurrentSecuritySelection = securityMode;
- mSecurityCallback.onSecurityModeChanged(securityMode, newView.needsInput());
+ mSecurityCallback.onSecurityModeChanged(securityMode,
+ securityMode != SecurityMode.None && newView.needsInput());
}
private KeyguardSecurityViewFlipper getFlipper() {
private int getSecurityViewIdForMode(SecurityMode securityMode) {
switch (securityMode) {
- case None: return R.id.keyguard_selector_view;
case Pattern: return R.id.keyguard_pattern_view;
case PIN: return R.id.keyguard_pin_view;
case Password: return R.id.keyguard_password_view;
private int getLayoutIdFor(SecurityMode securityMode) {
switch (securityMode) {
- case None: return R.layout.keyguard_selector_view;
case Pattern: return R.layout.keyguard_pattern_view;
case PIN: return R.layout.keyguard_pin_view;
case Password: return R.layout.keyguard_password_view;
+++ /dev/null
-/*
- * Copyright (C) 2012 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.keyguard;
-
-import android.animation.ObjectAnimator;
-import android.app.SearchManager;
-import android.app.admin.DevicePolicyManager;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.drawable.Drawable;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.util.Slog;
-import android.view.View;
-import android.widget.LinearLayout;
-
-import com.android.internal.telephony.IccCardConstants.State;
-import com.android.internal.widget.LockPatternUtils;
-import com.android.internal.widget.multiwaveview.GlowPadView;
-import com.android.internal.widget.multiwaveview.GlowPadView.OnTriggerListener;
-
-public class KeyguardSelectorView extends LinearLayout implements KeyguardSecurityView {
- private static final String TAG = "SecuritySelectorView";
- private static final String ASSIST_ICON_METADATA_NAME =
- "com.android.systemui.action_assist_icon";
-
- private KeyguardSecurityCallback mCallback;
- private GlowPadView mGlowPadView;
- private ObjectAnimator mAnim;
- private View mFadeView;
- private boolean mIsBouncing;
- private boolean mCameraDisabled;
- private boolean mSearchDisabled;
- private LockPatternUtils mLockPatternUtils;
- private SecurityMessageDisplay mSecurityMessageDisplay;
- private Drawable mBouncerFrame;
-
- OnTriggerListener mOnTriggerListener = new OnTriggerListener() {
-
- public void onTrigger(View v, int target) {
- final int resId = mGlowPadView.getResourceIdForTarget(target);
-
- if (resId == R.drawable.ic_lockscreen_unlock_phantom
- || resId == R.drawable.ic_lockscreen_unlock) {
- mCallback.userActivity();
- mCallback.dismiss(false);
- }
- }
-
- public void onReleased(View v, int handle) {
- if (!mIsBouncing) {
- doTransition(mFadeView, 1.0f);
- }
- }
-
- public void onGrabbed(View v, int handle) {
- mCallback.userActivity();
- doTransition(mFadeView, 0.0f);
- }
-
- public void onGrabbedStateChange(View v, int handle) {
-
- }
-
- public void onFinishFinalAnimation() {
-
- }
-
- };
-
- KeyguardUpdateMonitorCallback mUpdateCallback = new KeyguardUpdateMonitorCallback() {
-
- @Override
- public void onDevicePolicyManagerStateChanged() {
- updateTargets();
- }
-
- @Override
- public void onSimStateChanged(State simState) {
- updateTargets();
- }
- };
-
- public KeyguardSelectorView(Context context) {
- this(context, null);
- }
-
- public KeyguardSelectorView(Context context, AttributeSet attrs) {
- super(context, attrs);
- mLockPatternUtils = new LockPatternUtils(getContext());
- }
-
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
- mGlowPadView = (GlowPadView) findViewById(R.id.glow_pad_view);
- mGlowPadView.setOnTriggerListener(mOnTriggerListener);
- updateTargets();
-
- mSecurityMessageDisplay = new KeyguardMessageArea.Helper(this);
- View bouncerFrameView = findViewById(R.id.keyguard_selector_view_frame);
- mBouncerFrame = bouncerFrameView.getBackground();
- }
-
- public void setCarrierArea(View carrierArea) {
- mFadeView = carrierArea;
- }
-
- public boolean isTargetPresent(int resId) {
- return mGlowPadView.getTargetPosition(resId) != -1;
- }
-
- @Override
- public void showUsabilityHint() {
- mGlowPadView.ping();
- }
-
- private void updateTargets() {
- int currentUserHandle = mLockPatternUtils.getCurrentUser();
- DevicePolicyManager dpm = mLockPatternUtils.getDevicePolicyManager();
- int disabledFeatures = dpm.getKeyguardDisabledFeatures(null, currentUserHandle);
- boolean secureCameraDisabled = mLockPatternUtils.isSecure()
- && (disabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0;
- boolean cameraDisabledByAdmin = dpm.getCameraDisabled(null, currentUserHandle)
- || secureCameraDisabled;
- final KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(getContext());
- boolean disabledBySimState = monitor.isSimLocked();
- boolean cameraTargetPresent =
- isTargetPresent(R.drawable.ic_lockscreen_camera);
- boolean searchTargetPresent =
- isTargetPresent(R.drawable.ic_action_assist_generic);
-
- if (cameraDisabledByAdmin) {
- Log.v(TAG, "Camera disabled by Device Policy");
- } else if (disabledBySimState) {
- Log.v(TAG, "Camera disabled by Sim State");
- }
- boolean currentUserSetup = 0 != Settings.Secure.getIntForUser(
- mContext.getContentResolver(),
- Settings.Secure.USER_SETUP_COMPLETE,
- 0 /*default */,
- currentUserHandle);
- boolean searchActionAvailable =
- ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
- .getAssistIntent(mContext, false, UserHandle.USER_CURRENT) != null;
- mCameraDisabled = cameraDisabledByAdmin || disabledBySimState || !cameraTargetPresent
- || !currentUserSetup;
- mSearchDisabled = disabledBySimState || !searchActionAvailable || !searchTargetPresent
- || !currentUserSetup;
- updateResources();
- }
-
- public void updateResources() {
- // Update the search icon with drawable from the search .apk
- if (!mSearchDisabled) {
- Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
- .getAssistIntent(mContext, false, UserHandle.USER_CURRENT);
- if (intent != null) {
- // XXX Hack. We need to substitute the icon here but haven't formalized
- // the public API. The "_google" metadata will be going away, so
- // DON'T USE IT!
- ComponentName component = intent.getComponent();
- boolean replaced = mGlowPadView.replaceTargetDrawablesIfPresent(component,
- ASSIST_ICON_METADATA_NAME + "_google", R.drawable.ic_action_assist_generic);
-
- if (!replaced && !mGlowPadView.replaceTargetDrawablesIfPresent(component,
- ASSIST_ICON_METADATA_NAME, R.drawable.ic_action_assist_generic)) {
- Slog.w(TAG, "Couldn't grab icon from package " + component);
- }
- }
- }
-
- mGlowPadView.setEnableTarget(R.drawable.ic_lockscreen_camera, !mCameraDisabled);
- mGlowPadView.setEnableTarget(R.drawable.ic_action_assist_generic, !mSearchDisabled);
- }
-
- void doTransition(View view, float to) {
- if (mAnim != null) {
- mAnim.cancel();
- }
- mAnim = ObjectAnimator.ofFloat(view, "alpha", to);
- mAnim.start();
- }
-
- public void setKeyguardCallback(KeyguardSecurityCallback callback) {
- mCallback = callback;
- }
-
- public void setLockPatternUtils(LockPatternUtils utils) {
- mLockPatternUtils = utils;
- }
-
- @Override
- public void reset() {
- mGlowPadView.reset(false);
- }
-
- @Override
- public boolean needsInput() {
- return false;
- }
-
- @Override
- public void onPause() {
- KeyguardUpdateMonitor.getInstance(getContext()).removeCallback(mUpdateCallback);
- }
-
- @Override
- public void onResume(int reason) {
- KeyguardUpdateMonitor.getInstance(getContext()).registerCallback(mUpdateCallback);
- }
-
- @Override
- public KeyguardSecurityCallback getCallback() {
- return mCallback;
- }
-
- @Override
- public void showBouncer(int duration) {
- mIsBouncing = true;
- KeyguardSecurityViewHelper.
- showBouncer(mSecurityMessageDisplay, mFadeView, mBouncerFrame, duration);
- }
-
- @Override
- public void hideBouncer(int duration) {
- mIsBouncing = false;
- KeyguardSecurityViewHelper.
- hideBouncer(mSecurityMessageDisplay, mFadeView, mBouncerFrame, duration);
- }
-
- @Override
- public void startAppearAnimation() {
- // noop.
- }
-}
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ ~ Copyright (C) 2014 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
+ -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+ <gradient
+ android:type="linear"
+ android:angle="180"
+ android:startColor="#55000000"
+ android:endColor="#00000000" />
+</shape>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ ~ Copyright (C) 2014 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
+ -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+ <gradient
+ android:type="linear"
+ android:angle="90"
+ android:startColor="#55000000"
+ android:endColor="#00000000" />
+</shape>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 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.
--->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-
- <item
- android:state_enabled="true"
- android:state_active="false"
- android:state_focused="false"
- android:drawable="@drawable/ic_action_assist_generic_normal" />
-
- <item
- android:state_enabled="true"
- android:state_active="true"
- android:state_focused="false"
- android:drawable="@drawable/ic_action_assist_generic_activated" />
-
- <item
- android:state_enabled="true"
- android:state_active="false"
- android:state_focused="true"
- android:drawable="@drawable/ic_action_assist_generic_activated" />
-
-</selector>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ ~ Copyright (C) 2014 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
+ -->
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+ <solid android:color="@color/search_panel_card_color" />
+ <corners android:radius="@dimen/notification_material_rounded_rect_radius" />
+</shape>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ ~ Copyright (C) 2014 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
+ -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+ <gradient
+ android:type="linear"
+ android:angle="90"
+ android:startColor="#55000000"
+ android:endColor="#00000000" />
+</shape>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* apps/common/assets/default/default/skins/StatusBar.xml
-**
-** Copyright 2012, 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.
-*/
--->
-
-<com.android.systemui.SearchPanelView
- xmlns:prvandroid="http://schemas.android.com/apk/prv/res/android"
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/search_panel_container"
- android:layout_height="match_parent"
- android:layout_width="match_parent"
- android:paddingBottom="0dip">
-
- <RelativeLayout
- android:id="@+id/search_bg_protect"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_marginBottom="0dip">
-
- <RelativeLayout
- android:id="@+id/search_panel_container"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_alignParentEnd="true">
-
- <com.android.internal.widget.multiwaveview.GlowPadView
- android:id="@+id/glow_pad_view"
- android:orientation="vertical"
- android:layout_width="@dimen/navbar_search_panel_height"
- android:layout_height="match_parent"
- android:layout_alignParentBottom="true"
- android:gravity="start"
-
- prvandroid:targetDrawables="@array/navbar_search_targets"
- prvandroid:targetDescriptions="@array/navbar_search_target_descriptions"
- prvandroid:directionDescriptions="@array/navbar_search_direction_descriptions"
- prvandroid:outerRingDrawable="@drawable/navbar_search_outerring"
- prvandroid:outerRadius="@dimen/navbar_search_outerring_radius"
- prvandroid:innerRadius="@dimen/glowpadview_inner_radius"
- prvandroid:snapMargin="@dimen/navbar_search_snap_margin"
- prvandroid:feedbackCount="0"
- prvandroid:vibrationDuration="@integer/config_vibration_duration"
- prvandroid:alwaysTrackFinger="true"
- prvandroid:glowRadius="@dimen/glowpadview_glow_radius"
- prvandroid:pointDrawable="@drawable/ic_lockscreen_glowdot"
- />
-
- </RelativeLayout>
-
- </RelativeLayout>
-
-</com.android.systemui.SearchPanelView>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* apps/common/assets/default/default/skins/StatusBar.xml
-**
-** Copyright 2012, 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.
-*/
--->
-
-<com.android.systemui.SearchPanelView
- xmlns:prvandroid="http://schemas.android.com/apk/prv/res/android"
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/search_panel_container"
- android:layout_height="match_parent"
- android:layout_width="match_parent">
-
- <com.android.internal.widget.multiwaveview.GlowPadView
- android:id="@+id/glow_pad_view"
- android:layout_width="wrap_content"
- android:layout_height="@dimen/navbar_search_panel_height"
- android:layout_gravity="center_horizontal|bottom"
- android:gravity="center_horizontal|top"
-
- prvandroid:targetDrawables="@array/navbar_search_targets"
- prvandroid:targetDescriptions="@array/navbar_search_target_descriptions"
- prvandroid:directionDescriptions="@array/navbar_search_direction_descriptions"
- prvandroid:outerRingDrawable="@drawable/navbar_search_outerring"
- prvandroid:outerRadius="@dimen/navbar_search_outerring_radius"
- prvandroid:innerRadius="@dimen/glowpadview_inner_radius"
- prvandroid:snapMargin="@dimen/navbar_search_snap_margin"
- prvandroid:feedbackCount="0"
- prvandroid:vibrationDuration="@integer/config_vibration_duration"
- prvandroid:alwaysTrackFinger="true"
- prvandroid:glowRadius="@dimen/glowpadview_glow_radius"
- prvandroid:pointDrawable="@drawable/ic_lockscreen_glowdot"/>
-
-</com.android.systemui.SearchPanelView>
*/
-->
+<!-- Extends FrameLayout -->
<com.android.systemui.SearchPanelView
- xmlns:prvandroid="http://schemas.android.com/apk/prv/res/android"
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/search_panel_container"
android:layout_height="match_parent"
- android:layout_width="match_parent"
- android:paddingBottom="0dip">
-
- <RelativeLayout
- android:id="@+id/search_bg_protect"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_marginBottom="0dip">
-
- <RelativeLayout
- android:id="@+id/search_panel_container"
- android:layout_width="match_parent"
+ android:layout_width="match_parent">
+
+ <com.android.systemui.statusbar.AlphaOptimizedView
+ style="@style/SearchPanelScrim"
+ android:id="@+id/search_panel_scrim"
+ android:background="@drawable/search_panel_scrim" />
+
+ <FrameLayout
+ style="@style/SearchPanelCard"
+ android:id="@+id/search_panel_card"
+ android:background="@drawable/search_panel_card_bg"
+ android:elevation="12dp">
+
+ <ImageView
+ style="@style/SearchPanelLogo"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_alignParentBottom="true">
-
- <com.android.internal.widget.multiwaveview.GlowPadView
- android:id="@+id/glow_pad_view"
- android:orientation="horizontal"
- android:layout_width="match_parent"
- android:layout_height="@dimen/navbar_search_panel_height"
- android:layout_alignParentBottom="true"
- android:gravity="top"
-
- prvandroid:targetDrawables="@array/navbar_search_targets"
- prvandroid:targetDescriptions="@array/navbar_search_target_descriptions"
- prvandroid:directionDescriptions="@array/navbar_search_direction_descriptions"
- prvandroid:outerRingDrawable="@drawable/navbar_search_outerring"
- prvandroid:outerRadius="@dimen/navbar_search_outerring_radius"
- prvandroid:innerRadius="@dimen/glowpadview_inner_radius"
- prvandroid:snapMargin="@dimen/navbar_search_snap_margin"
- prvandroid:feedbackCount="0"
- prvandroid:vibrationDuration="@integer/config_vibration_duration"
- prvandroid:alwaysTrackFinger="true"
- prvandroid:glowRadius="@dimen/glowpadview_glow_radius"
- prvandroid:pointDrawable="@drawable/ic_lockscreen_glowdot"
- />
-
- </RelativeLayout>
-
- </RelativeLayout>
+ android:id="@+id/search_logo" />
+ </FrameLayout>
</com.android.systemui.SearchPanelView>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/common/assets/res/any/colors.xml
-**
-** Copyright 2012, 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.
-*/
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-
- <array name="navbar_search_targets">
- <item>@null</item>
- <item>@null</item>
- <item>@drawable/ic_action_assist_generic</item>
- <item>@null</item>
- </array>
-
- <array name="navbar_search_target_descriptions">
- <item>@null</item>
- <item>@null</item>
- <item>@string/description_target_search</item>
- <item>@null</item>
- </array>
-
- <array name="navbar_search_direction_descriptions">
- <item>@null</item>
- <item>@null</item>
- <item>@string/description_direction_left</item>
- <item>@null</item>
- </array>
-
-</resources>
<style name="BrightnessDialogContainer" parent="@style/BaseBrightnessDialogContainer">
<item name="android:layout_width">360dp</item>
</style>
+
+ <style name="SearchPanelCard">
+ <item name="android:layout_width">@dimen/search_panel_card_height</item>
+ <item name="android:layout_height">match_parent</item>
+ <item name="android:layout_marginTop">16dp</item>
+ <item name="android:layout_marginBottom">16dp</item>
+ <item name="android:layout_gravity">right</item>
+ </style>
+
+ <style name="SearchPanelLogo">
+ <item name="android:layout_gravity">top|left</item>
+ </style>
+
+ <style name="SearchPanelScrim">
+ <item name="android:layout_width">@dimen/search_panel_scrim_height</item>
+ <item name="android:layout_height">match_parent</item>
+ <item name="android:layout_gravity">right</item>
+ </style>
</resources>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/common/assets/res/any/colors.xml
-**
-** Copyright 2012, 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.
-*/
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-
- <array name="navbar_search_targets">
- <item>@null</item>
- <item>@drawable/ic_action_assist_generic</item>
- <item>@null</item>
- <item>@null</item>
- </array>
-
- <array name="navbar_search_target_descriptions">
- <item>@null</item>
- <item>@string/description_target_search</item>
- <item>@null</item>
- <item>@null</item>
- </array>
-
- <array name="navbar_search_direction_descriptions">
- <item>@null</item>
- <item>@string/description_direction_left</item>
- <item>@null</item>
- <item>@null</item>
- </array>
-
-</resources>
<item name="android:layout_width">@dimen/notification_panel_width</item>
<item name="android:layout_gravity">center_horizontal</item>
</style>
+
+ <style name="SearchPanelCard">
+ <item name="android:layout_width">550dp</item>
+ <item name="android:layout_height">@dimen/search_panel_card_height</item>
+ <item name="android:layout_gravity">center_horizontal|bottom</item>
+ </style>
+
+ <style name="SearchPanelLogo">
+ <item name="android:layout_gravity">top|center_horizontal</item>
+ </style>
+
+ <style name="SearchPanelScrim">
+ <item name="android:layout_width">match_parent</item>
+ <item name="android:layout_height">@dimen/search_panel_scrim_height</item>
+ <item name="android:layout_gravity">bottom</item>
+ </style>
</resources>
*/
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-
- <array name="navbar_search_targets">
- <item>@null</item>
- <item>@drawable/ic_action_assist_generic</item>
- <item>@null</item>
- <item>@null</item>
- </array>
-
- <array name="navbar_search_target_descriptions">
- <item>@null</item>
- <item>@string/description_target_search</item>
- <item>@null</item>
- <item>@null</item>
- </array>
-
- <array name="navbar_search_direction_descriptions">
- <item>@null</item>
- <item>@string/description_direction_up</item>
- <item>@null</item>
- <item>@null</item>
- </array>
<!-- BatteryMeterView parameters -->
<array name="batterymeter_color_levels">
<color name="notification_guts_title_color">#FFFFFFFF</color>
<color name="notification_guts_text_color">#99FFFFFF</color>
<color name="notification_guts_btn_color">#FFFFFFFF</color>
+
+ <color name="search_panel_card_color">#ffffff</color>
</resources>
<!-- Additional translation (downwards) for appearing notifications when going to the full shade
from Keyguard. -->
<dimen name="go_to_full_shade_appearing_translation">200dp</dimen>
+
+ <!-- The height of the search panel card. -->
+ <dimen name="search_panel_card_height">300dp</dimen>
+
+ <!-- The height of the scrim behind the search panel card. -->
+ <dimen name="search_panel_scrim_height">250dp</dimen>
+
+ <!-- How much from the bottom of the screen the card should peek in when activating the search
+ panel -->
+ <dimen name="search_card_peek_height">100dp</dimen>
+
+ <!-- How far the user needs to drag up to invoke search. -->
+ <dimen name="search_panel_threshold">150dp</dimen>
</resources>
<item name="android:textStyle">italic</item>
<item name="android:textColor">#60000000</item>
</style>
+
+ <style name="SearchPanelCard">
+ <item name="android:layout_width">match_parent</item>
+ <item name="android:layout_height">@dimen/search_panel_card_height</item>
+ <item name="android:layout_marginStart">8dp</item>
+ <item name="android:layout_marginEnd">8dp</item>
+ <item name="android:layout_gravity">bottom</item>
+ </style>
+
+ <style name="SearchPanelLogo">
+ <item name="android:layout_gravity">top|center_horizontal</item>
+ </style>
+
+ <style name="SearchPanelScrim">
+ <item name="android:layout_width">match_parent</item>
+ <item name="android:layout_height">@dimen/search_panel_scrim_height</item>
+ <item name="android:layout_gravity">bottom</item>
+ </style>
</resources>
package com.android.systemui;
-import android.animation.LayoutTransition;
-import android.app.ActivityManagerNative;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
import android.app.ActivityOptions;
import android.app.SearchManager;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.media.AudioAttributes;
-import android.os.RemoteException;
-import android.os.ServiceManager;
+import android.os.AsyncTask;
+import android.os.Bundle;
import android.os.UserHandle;
import android.os.Vibrator;
import android.provider.Settings;
import android.util.AttributeSet;
-import android.util.EventLog;
import android.util.Log;
-import android.view.IWindowManager;
import android.view.MotionEvent;
import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewTreeObserver;
-import android.view.ViewTreeObserver.OnPreDrawListener;
+import android.view.animation.AnimationUtils;
+import android.view.animation.Interpolator;
import android.widget.FrameLayout;
+import android.widget.ImageView;
-import com.android.internal.widget.multiwaveview.GlowPadView;
-import com.android.internal.widget.multiwaveview.GlowPadView.OnTriggerListener;
import com.android.systemui.statusbar.BaseStatusBar;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.StatusBarPanel;
-import com.android.systemui.statusbar.phone.KeyguardTouchDelegate;
import com.android.systemui.statusbar.phone.PhoneStatusBar;
-public class SearchPanelView extends FrameLayout implements
- StatusBarPanel, ActivityOptions.OnAnimationStartedListener {
- private static final int SEARCH_PANEL_HOLD_DURATION = 0;
- static final String TAG = "SearchPanelView";
- static final boolean DEBUG = PhoneStatusBar.DEBUG || false;
- public static final boolean DEBUG_GESTURES = true;
+public class SearchPanelView extends FrameLayout implements StatusBarPanel {
+
+ private static final String TAG = "SearchPanelView";
private static final String ASSIST_ICON_METADATA_NAME =
"com.android.systemui.action_assist_icon";
private final Context mContext;
private BaseStatusBar mBar;
- private boolean mShowing;
- private View mSearchTargetsContainer;
- private GlowPadView mGlowPadView;
- private IWindowManager mWm;
+ private View mCard;
+ private ImageView mLogo;
+ private View mScrim;
+
+ private int mPeekHeight;
+ private int mThreshold;
+ private boolean mHorizontal;
+ private final Interpolator mLinearOutSlowInInterpolator;
+ private final Interpolator mFastOutLinearInInterpolator;
+
+ private boolean mAnimatingIn;
+ private boolean mAnimatingOut;
+ private boolean mDragging;
+ private boolean mDraggedFarEnough;
+ private float mStartTouch;
+ private float mStartDrag;
+
+ private ObjectAnimator mEnterAnimator;
+
+ private boolean mStartExitAfterAnimatingIn;
public SearchPanelView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
public SearchPanelView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mContext = context;
- mWm = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
+ mPeekHeight = context.getResources().getDimensionPixelSize(R.dimen.search_card_peek_height);
+ mThreshold = context.getResources().getDimensionPixelSize(R.dimen.search_panel_threshold);
+ mLinearOutSlowInInterpolator =
+ AnimationUtils.loadInterpolator(context, android.R.interpolator.linear_out_slow_in);
+ mFastOutLinearInInterpolator =
+ AnimationUtils.loadInterpolator(context, android.R.interpolator.fast_out_linear_in);
}
private void startAssistActivity() {
// Close Recent Apps if needed
mBar.animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_SEARCH_PANEL);
- boolean isKeyguardShowing = false;
- try {
- isKeyguardShowing = mWm.isKeyguardLocked();
- } catch (RemoteException e) {
-
- }
-
- if (isKeyguardShowing) {
- // Have keyguard show the bouncer and launch the activity if the user succeeds.
- KeyguardTouchDelegate.getInstance(getContext()).showAssistant();
- onAnimationStarted();
- } else {
- // Otherwise, keyguard isn't showing so launch it from here.
- Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
- .getAssistIntent(mContext, true, UserHandle.USER_CURRENT);
- if (intent == null) return;
-
- try {
- ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
- } catch (RemoteException e) {
- // too bad, so sad...
- }
-
- try {
- ActivityOptions opts = ActivityOptions.makeCustomAnimation(mContext,
- R.anim.search_launch_enter, R.anim.search_launch_exit,
- getHandler(), this);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- mContext.startActivityAsUser(intent, opts.toBundle(),
- new UserHandle(UserHandle.USER_CURRENT));
- } catch (ActivityNotFoundException e) {
- Log.w(TAG, "Activity not found for " + intent.getAction());
- onAnimationStarted();
- }
- }
- }
- class GlowPadTriggerListener implements GlowPadView.OnTriggerListener {
- boolean mWaitingForLaunch;
+ final Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
+ .getAssistIntent(mContext, true, UserHandle.USER_CURRENT);
+ if (intent == null) return;
- public void onGrabbed(View v, int handle) {
- }
-
- public void onReleased(View v, int handle) {
- }
-
- public void onGrabbedStateChange(View v, int handle) {
- if (!mWaitingForLaunch && OnTriggerListener.NO_HANDLE == handle) {
- mBar.hideSearchPanel();
- }
- }
-
- public void onTrigger(View v, final int target) {
- final int resId = mGlowPadView.getResourceIdForTarget(target);
- switch (resId) {
- case R.drawable.ic_action_assist_generic:
- mWaitingForLaunch = true;
- startAssistActivity();
- vibrate();
- break;
- }
- }
-
- public void onFinishFinalAnimation() {
+ try {
+ final ActivityOptions opts = ActivityOptions.makeCustomAnimation(mContext,
+ R.anim.search_launch_enter, R.anim.search_launch_exit);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ AsyncTask.execute(new Runnable() {
+ @Override
+ public void run() {
+ mContext.startActivityAsUser(intent, opts.toBundle(),
+ new UserHandle(UserHandle.USER_CURRENT));
+ }
+ });
+ } catch (ActivityNotFoundException e) {
+ Log.w(TAG, "Activity not found for " + intent.getAction());
}
}
- final GlowPadTriggerListener mGlowPadViewListener = new GlowPadTriggerListener();
-
- @Override
- public void onAnimationStarted() {
- postDelayed(new Runnable() {
- public void run() {
- mGlowPadViewListener.mWaitingForLaunch = false;
- mBar.hideSearchPanel();
- }
- }, SEARCH_PANEL_HOLD_DURATION);
- }
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- mSearchTargetsContainer = findViewById(R.id.search_panel_container);
- // TODO: fetch views
- mGlowPadView = (GlowPadView) findViewById(R.id.glow_pad_view);
- mGlowPadView.setOnTriggerListener(mGlowPadViewListener);
+ mCard = findViewById(R.id.search_panel_card);
+ mLogo = (ImageView) findViewById(R.id.search_logo);
+ mScrim = findViewById(R.id.search_panel_scrim);
}
private void maybeSwapSearchIcon() {
.getAssistIntent(mContext, false, UserHandle.USER_CURRENT);
if (intent != null) {
ComponentName component = intent.getComponent();
- if (component == null || !mGlowPadView.replaceTargetDrawablesIfPresent(component,
- ASSIST_ICON_METADATA_NAME,
- R.drawable.ic_action_assist_generic)) {
- if (DEBUG) Log.v(TAG, "Couldn't grab icon for component " + component);
+ replaceDrawable(mLogo, component, ASSIST_ICON_METADATA_NAME);
+ } else {
+ mLogo.setImageDrawable(null);
+ }
+ }
+
+ public void replaceDrawable(ImageView v, ComponentName component, String name) {
+ if (component != null) {
+ try {
+ PackageManager packageManager = mContext.getPackageManager();
+ // Look for the search icon specified in the activity meta-data
+ Bundle metaData = packageManager.getActivityInfo(
+ component, PackageManager.GET_META_DATA).metaData;
+ if (metaData != null) {
+ int iconResId = metaData.getInt(name);
+ if (iconResId != 0) {
+ Resources res = packageManager.getResourcesForActivity(component);
+ v.setImageDrawable(res.getDrawable(iconResId));
+ return;
+ }
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.w(TAG, "Failed to swap drawable; "
+ + component.flattenToShortString() + " not found", e);
+ } catch (Resources.NotFoundException nfe) {
+ Log.w(TAG, "Failed to swap drawable from "
+ + component.flattenToShortString(), nfe);
}
}
+ v.setImageDrawable(null);
}
private boolean pointInside(int x, int y, View v) {
}
public boolean isInContentArea(int x, int y) {
- return pointInside(x, y, mSearchTargetsContainer);
+ return pointInside(x, y, mCard);
}
- private final OnPreDrawListener mPreDrawListener = new ViewTreeObserver.OnPreDrawListener() {
- public boolean onPreDraw() {
- getViewTreeObserver().removeOnPreDrawListener(this);
- mGlowPadView.resumeAnimations();
- return false;
- }
- };
-
private void vibrate() {
Context context = getContext();
if (Settings.System.getIntForUser(context.getContentResolver(),
}
public void show(final boolean show, boolean animate) {
- if (!show) {
- final LayoutTransition transitioner = animate ? createLayoutTransitioner() : null;
- ((ViewGroup) mSearchTargetsContainer).setLayoutTransition(transitioner);
- }
- mShowing = show;
if (show) {
maybeSwapSearchIcon();
if (getVisibility() != View.VISIBLE) {
setVisibility(View.VISIBLE);
- // Don't start the animation until we've created the layer, which is done
- // right before we are drawn
- mGlowPadView.suspendAnimations();
- mGlowPadView.ping();
- getViewTreeObserver().addOnPreDrawListener(mPreDrawListener);
vibrate();
+ mCard.setAlpha(1f);
+ if (animate) {
+ startEnterAnimation();
+ } else {
+ mScrim.setAlpha(1f);
+ if (mHorizontal) {
+ mCard.setX(getWidth() - mPeekHeight);
+ } else {
+ mCard.setY(getHeight() - mPeekHeight);
+ }
+ }
}
setFocusable(true);
setFocusableInTouchMode(true);
requestFocus();
} else {
- setVisibility(View.INVISIBLE);
+ if (animate) {
+ startAbortAnimation();
+ } else {
+ setVisibility(View.INVISIBLE);
+ }
+ }
+ }
+
+ private void startEnterAnimation() {
+ if (mHorizontal) {
+ mCard.setX(getWidth());
+ } else {
+ mCard.setY(getHeight());
}
+ mAnimatingIn = true;
+ mCard.animate().cancel();
+ mEnterAnimator = ObjectAnimator.ofFloat(mCard, mHorizontal ? View.X : View.Y,
+ mHorizontal ? mCard.getX() : mCard.getY(),
+ mHorizontal ? getWidth() - mPeekHeight : getHeight() - mPeekHeight);
+ mEnterAnimator.setDuration(300);
+ mEnterAnimator.setStartDelay(50);
+ mEnterAnimator.setInterpolator(mLinearOutSlowInInterpolator);
+ mEnterAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mEnterAnimator = null;
+ mAnimatingIn = false;
+ if (mStartExitAfterAnimatingIn) {
+ startExitAnimation();
+ }
+ }
+ });
+ mEnterAnimator.start();
+ mScrim.setAlpha(0f);
+ mScrim.animate()
+ .alpha(1f)
+ .setDuration(300)
+ .setStartDelay(50)
+ .setInterpolator(PhoneStatusBar.ALPHA_IN)
+ .start();
+
+ }
+
+ private void startAbortAnimation() {
+ mCard.animate().cancel();
+ mAnimatingOut = true;
+ if (mHorizontal) {
+ mCard.animate().x(getWidth());
+ } else {
+ mCard.animate().y(getHeight());
+ }
+ mCard.animate()
+ .setDuration(150)
+ .setInterpolator(mFastOutLinearInInterpolator)
+ .withEndAction(new Runnable() {
+ @Override
+ public void run() {
+ mAnimatingOut = false;
+ setVisibility(View.INVISIBLE);
+ }
+ });
+ mScrim.animate()
+ .alpha(0f)
+ .setDuration(150)
+ .setStartDelay(0)
+ .setInterpolator(PhoneStatusBar.ALPHA_OUT);
}
public void hide(boolean animate) {
// This will indirectly cause show(false, ...) to get called
mBar.animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
} else {
- setVisibility(View.INVISIBLE);
+ if (animate) {
+ startAbortAnimation();
+ } else {
+ setVisibility(View.INVISIBLE);
+ }
}
}
- /**
- * We need to be aligned at the bottom. LinearLayout can't do this, so instead,
- * let LinearLayout do all the hard work, and then shift everything down to the bottom.
- */
- @Override
- protected void onLayout(boolean changed, int l, int t, int r, int b) {
- super.onLayout(changed, l, t, r, b);
- // setPanelHeight(mSearchTargetsContainer.getHeight());
- }
-
@Override
public boolean dispatchHoverEvent(MotionEvent event) {
// Ignore hover events outside of this panel bounds since such events
* when the animation is done.
*/
public boolean isShowing() {
- return mShowing;
+ return getVisibility() == View.VISIBLE && !mAnimatingOut;
}
public void setBar(BaseStatusBar bar) {
mBar = bar;
}
+ public boolean isAssistantAvailable() {
+ return ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
+ .getAssistIntent(mContext, false, UserHandle.USER_CURRENT) != null;
+ }
+
+ private float rubberband(float diff) {
+ return Math.signum(diff) * (float) Math.pow(Math.abs(diff), 0.8f);
+ }
+
@Override
public boolean onTouchEvent(MotionEvent event) {
- if (DEBUG_GESTURES) {
- if (event.getActionMasked() != MotionEvent.ACTION_MOVE) {
- EventLog.writeEvent(EventLogTags.SYSUI_SEARCHPANEL_TOUCH,
- event.getActionMasked(), (int) event.getX(), (int) event.getY());
- }
+ int action = event.getActionMasked();
+ switch (action) {
+ case MotionEvent.ACTION_DOWN:
+ mStartTouch = mHorizontal ? event.getX() : event.getY();
+ mDragging = false;
+ mDraggedFarEnough = false;
+ mStartExitAfterAnimatingIn = false;
+ break;
+ case MotionEvent.ACTION_MOVE:
+ float currentTouch = mHorizontal ? event.getX() : event.getY();
+ if (getVisibility() == View.VISIBLE && !mDragging &&
+ (!mAnimatingIn || Math.abs(mStartTouch - currentTouch) > mThreshold)) {
+ mStartDrag = currentTouch;
+ mDragging = true;
+ }
+ if (!mDraggedFarEnough && Math.abs(mStartTouch - currentTouch) > mThreshold) {
+ mDraggedFarEnough = true;
+ }
+ if (mDragging) {
+ if (!mAnimatingIn && !mAnimatingOut) {
+ if (Math.abs(currentTouch - mStartDrag) > mThreshold) {
+ startExitAnimation();
+ } else {
+ if (mHorizontal) {
+ mCard.setX(getWidth() - mPeekHeight + rubberband(
+ currentTouch - mStartDrag));
+ } else {
+ mCard.setY(getHeight() - mPeekHeight + rubberband(
+ currentTouch - mStartDrag));
+ }
+ }
+ } else if (mAnimatingIn ) {
+ float diff = rubberband(currentTouch - mStartDrag);
+ PropertyValuesHolder[] values = mEnterAnimator.getValues();
+ values[0].setFloatValues(
+ mHorizontal ? getWidth() + diff : getHeight() + diff,
+ mHorizontal
+ ? getWidth() - mPeekHeight + diff
+ : getHeight() - mPeekHeight + diff);
+ mEnterAnimator.setCurrentPlayTime(mEnterAnimator.getCurrentPlayTime());
+ }
+ }
+ break;
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_CANCEL:
+ if (mDraggedFarEnough) {
+ if (mAnimatingIn) {
+ mStartExitAfterAnimatingIn = true;
+ } else {
+ startExitAnimation();
+ }
+ } else {
+ startAbortAnimation();
+ }
+ break;
}
- return super.onTouchEvent(event);
+ return true;
}
- private LayoutTransition createLayoutTransitioner() {
- LayoutTransition transitioner = new LayoutTransition();
- transitioner.setDuration(200);
- transitioner.setStartDelay(LayoutTransition.CHANGE_DISAPPEARING, 0);
- transitioner.setAnimator(LayoutTransition.DISAPPEARING, null);
- return transitioner;
+ private void startExitAnimation() {
+ if (mAnimatingOut || getVisibility() != View.VISIBLE) {
+ return;
+ }
+ if (mEnterAnimator != null) {
+ mEnterAnimator.cancel();
+ }
+ mAnimatingOut = true;
+ startAssistActivity();
+ vibrate();
+ mCard.animate()
+ .alpha(0f)
+ .withLayer()
+ .setDuration(250)
+ .setInterpolator(PhoneStatusBar.ALPHA_OUT)
+ .withEndAction(new Runnable() {
+ @Override
+ public void run() {
+ mAnimatingOut = false;
+ setVisibility(View.INVISIBLE);
+ }
+ });
+ mScrim.animate()
+ .alpha(0f)
+ .setDuration(250)
+ .setStartDelay(0)
+ .setInterpolator(PhoneStatusBar.ALPHA_OUT);
}
- public boolean isAssistantAvailable() {
- return ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
- .getAssistIntent(mContext, false, UserHandle.USER_CURRENT) != null;
+ public void setHorizontal(boolean horizontal) {
+ mHorizontal = horizontal;
}
}
if (DEBUG) Log.d(TAG, "opening search panel");
if (mSearchPanelView != null && mSearchPanelView.isAssistantAvailable()) {
mSearchPanelView.show(true, true);
- onShowSearchPanel();
}
break;
case MSG_CLOSE_SEARCH_PANEL:
if (DEBUG) Log.d(TAG, "closing search panel");
if (mSearchPanelView != null && mSearchPanelView.isShowing()) {
mSearchPanelView.show(false, true);
- onHideSearchPanel();
}
break;
}
protected void workAroundBadLayerDrawableOpacity(View v) {
}
- protected void onHideSearchPanel() {
- }
-
- protected void onShowSearchPanel() {
- }
-
private boolean inflateViews(NotificationData.Entry entry, ViewGroup parent) {
return inflateViews(entry, parent, false);
}
mBarBackground.finishAnimation();
}
- public void setContentVisible(boolean visible) {
- // for subclasses
- }
-
private static class BarBackgroundDrawable extends Drawable {
private final int mOpaque;
private final int mSemiTransparent;
return max;
}
- @Override
- public void setContentVisible(boolean visible) {
- final float alpha = visible ? 1 : 0;
- fadeContent(mView.getBackButton(), alpha);
- }
-
- private void fadeContent(View v, float alpha) {
- if (v != null) {
- v.animate().alpha(alpha).setDuration(CONTENT_FADE_DURATION);
- }
- }
-
private void setKeyButtonViewQuiescentAlpha(View button, float alpha, boolean animate) {
if (button instanceof KeyButtonView) {
((KeyButtonView) button).setQuiescentAlpha(alpha, animate);
// performs manual animation in sync with layout transitions
private final NavTransitionListener mTransitionListener = new NavTransitionListener();
+ private OnVerticalChangedListener mOnVerticalChangedListener;
+
private class NavTransitionListener implements TransitionListener {
private boolean mBackTransitioning;
private boolean mHomeAppearing;
mDelegateHelper.setBar(phoneStatusBar);
}
+ public void setOnVerticalChangedListener(OnVerticalChangedListener onVerticalChangedListener) {
+ mOnVerticalChangedListener = onVerticalChangedListener;
+ }
+
@Override
public boolean onTouchEvent(MotionEvent event) {
if (mDeadZone != null && event.getAction() == MotionEvent.ACTION_OUTSIDE) {
// swap to x coordinate if orientation is not in vertical
if (mDelegateHelper != null) {
- mDelegateHelper.setSwapXY(!mVertical);
+ mDelegateHelper.setSwapXY(mVertical);
}
setNavigationIconHints(mNavigationIconHints, true);
mVertical = newVertical;
//Log.v(TAG, String.format("onSizeChanged: h=%d, w=%d, vert=%s", h, w, mVertical?"y":"n"));
reorient();
+ if (mOnVerticalChangedListener != null) {
+ mOnVerticalChangedListener.onVerticalChanged(newVertical);
+ }
}
postCheckForInvalidLayout("sizeChanged");
pw.println();
}
+ public interface OnVerticalChangedListener {
+ void onVerticalChanged(boolean isVertical);
+ }
}
mNavigationBarView.setDisabledFlags(mDisabled);
mNavigationBarView.setBar(this);
+ mNavigationBarView.setOnVerticalChangedListener(
+ new NavigationBarView.OnVerticalChangedListener() {
+ @Override
+ public void onVerticalChanged(boolean isVertical) {
+ if (mSearchPanelView != null) {
+ mSearchPanelView.setHorizontal(isVertical);
+ }
+ }
+ });
mNavigationBarView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
}
@Override
- protected void onShowSearchPanel() {
- if (mNavigationBarView != null) {
- mNavigationBarView.getBarTransitions().setContentVisible(false);
- }
- }
-
- @Override
- protected void onHideSearchPanel() {
- if (mNavigationBarView != null) {
- mNavigationBarView.getBarTransitions().setContentVisible(true);
- }
- }
-
- @Override
protected View getStatusBarView() {
return mStatusBarView;
}
}
lp.gravity = Gravity.BOTTOM | Gravity.START;
lp.setTitle("SearchPanel");
- // TODO: Define custom animation for Search panel
- lp.windowAnimations = com.android.internal.R.style.Animation_RecentApplications;
lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED
| WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
return lp;
View.OnTouchListener mHomeActionListener = new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
switch(event.getAction()) {
- case MotionEvent.ACTION_DOWN:
+ case MotionEvent.ACTION_DOWN:
if (!shouldDisableNavbarGestures()) {
mHandler.removeCallbacks(mShowSearchPanel);
mHandler.postDelayed(mShowSearchPanel, mShowSearchHoldoff);