/* * Copyright (C) 2015 The CyanogenMod 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 cyanogenmod.externalviews; import android.app.Service; import android.content.Context; import android.content.Intent; import android.graphics.PixelFormat; import android.graphics.Rect; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.RemoteCallbackList; import android.os.RemoteException; import android.util.Log; import android.view.ActionMode; import android.view.Gravity; import android.view.KeyEvent; import android.view.Menu; import android.view.MenuItem; import android.view.MotionEvent; import android.view.SearchEvent; import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; import android.view.accessibility.AccessibilityEvent; import com.android.internal.policy.PhoneWindow; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; /** * A class for providing a view that can be displayed within the lock screen. Applications that * wish to provide a view to be displayed within the lock screen should extend this service. * *
Applications extending this class should include the * {@link cyanogenmod.platform.Manifest.permission#THIRD_PARTY_KEYGUARD} permission in their * manifest
*Applications extending this class should also extend * {@link KeyguardExternalViewProviderService.Provider} and return a new instance of * {@link KeyguardExternalViewProviderService.Provider} in * {@link KeyguardExternalViewProviderService#createExternalView(Bundle)}.
*/ public abstract class KeyguardExternalViewProviderService extends Service { private static final String TAG = KeyguardExternalViewProviderService.class.getSimpleName(); private static final boolean DEBUG = false; /** * The action that must be declared as handled by this service. * *{@code
*
<lockscreen>
* tag.
*/
public static final String META_DATA = "cyanogenmod.externalviews.keyguard";
private WindowManager mWindowManager;
private final Handler mHandler = new Handler();
@Override
public void onCreate() {
super.onCreate();
mWindowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
return START_NOT_STICKY;
}
@Override
public final IBinder onBind(Intent intent) {
return new IExternalViewProviderFactory.Stub() {
@Override public IBinder createExternalView(final Bundle options) {
FutureTaskThe view component should enter a paused state when this is called, and save any state * information that may be needed once the lock screen is displayed again. For example, a * non-interactive component that provides animated visuals should pause playback of those * animations and save the state, if necessary, of that animation.
*/ protected abstract void onKeyguardDismissed(); /** * Called from the host when the keyguard is displaying the security screen for the user to * enter their pin, password, or pattern. * *Interactive components will no longer have focus when the bouncer is displayed and * should enter a paused or idle state while the bouncer is being shown.
* @param showing True if the bouncer is being show or false when it is dismissed without the * device being unlocked. */ protected abstract void onBouncerShowing(boolean showing); /** * Called from the host when the screen is turned on. * *The provided view should return to a running state when this is called. For example, * a non-interactive component that provides animated visuals should resume playback of * those animations.
*/ protected abstract void onScreenTurnedOn(); /** * Called from the host when the screen is turned off. * *The provided view should provided view should pause its activity, if not currently * in a paused state, and do any work necessary to be ready when the screen is turned * back on. This will allow for a seamless user experience once the screen is turned on. *
*/ protected abstract void onScreenTurnedOff(); /** * Called from the host when the user is swiping the lockscreen * to transition into the live lock screen * * @param swipeProgress [0-1] represents the progress of the swipe */ protected void onLockscreenSlideOffsetChanged(float swipeProgress) {} // callbacks from provider to host /** * Request that the keyguard be dismissed. Calling this method will dismiss the lock * screen, if it is a not secure, or present the user with the security screen for the user * to enter their security code to finish dismissing the lock screen. * *If the user has a secure lock screen and dismisses the bouncer without entering their * secure code, the lock screen will not be dismissed and * {@link KeyguardExternalViewProviderService.Provider#onBouncerShowing(boolean)} will be * called with {@code onShowing} being set to false, indicating that the lock screen was not * dismissed as requested.
* @return True if the call succeeded. */ protected final boolean requestDismiss() { return mImpl.requestDismiss(); } /** * Request that the keyguard be dismissed and the activity provided by the given intent be * started once the keyguard is dismissed. If a secure lock screen is being used the user * will need to enter their correct security code to finish dismissing the lock screen. * *If the user has a secure lock screen and dismisses the bouncer without entering their * secure code, the lock screen will not be dismissed and * {@link KeyguardExternalViewProviderService.Provider#onBouncerShowing(boolean)} will be * called with onShowing being set to false, indicating that the lock screen was not * dismissed as requested.
* @param intent An intent specifying an activity to launch. * @return True if the call succeeded. */ protected final boolean requestDismissAndStartActivity(final Intent intent) { return mImpl.requestDismissAndStartActivity(intent); } /** * Call this method when you would like to take focus and hide the notification panel. * *You should call this method if your component requires focus and the users's * attention. The user will still be able to bring the notifications back into view by * sliding down from the status bar. * Calling this method has no effect for non-interactive components.
* @deprecated As of SDK version {@link cyanogenmod.os.Build.CM_VERSION_CODES#ELDERBERRY} * this does nothing. */ @Deprecated protected final void collapseNotificationPanel() { /* do nothing */ } /** * This method should be called when the provided view needs to change from interactive to * non-interactive and vice versa. * *Interactive components can receive input focus and receive user interaction while * non-interactive components never receive focus and are purely visual.
* @param isInteractive */ protected final void setInteractivity(final boolean isInteractive) { mImpl.setInteractivity(isInteractive); } /** * Call this method when you like to slide in the lockscreen on top of * your live lockscreen. Only relevant if you use * {@link KeyguardExternalViewProviderService.Provider#setInteractivity(boolean)} */ protected final void slideLockscreenIn() { mImpl.slideLockscreenIn(); } /*package*/ final int getWindowType() { return WindowManager.LayoutParams.TYPE_KEYGUARD_PANEL; } /*package*/ final int getWindowFlags() { return WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_FULLSCREEN; } } }