ExtView: Allow window type and flags to be overridden

KeyguardExternalViews need to have a different window type
as well as different flags set when creating the window.  this
patch allows those to be overridden when extending the
ExternalViewProviderService.  This patch also makes sure that
the width and height of the external view window is always the
same as the display size.

Change-Id: Ic5fc0d211e9fee0e610d55a3620e6e322defe231
This commit is contained in:
d34d 2015-12-14 09:58:14 -08:00 committed by Clark Scheff
parent 637e40fba5
commit 582ba4c91e
4 changed files with 113 additions and 14 deletions

View File

@ -39,10 +39,11 @@ import java.util.LinkedList;
public class ExternalView extends View implements Application.ActivityLifecycleCallbacks,
ViewTreeObserver.OnPreDrawListener {
private Context mContext;
private LinkedList<Runnable> mQueue = new LinkedList<Runnable>();
private volatile IExternalViewProvider mExternalViewProvider;
private final ExternalViewProperties mExternalViewProperties;
protected Context mContext;
protected final ExternalViewProperties mExternalViewProperties;
protected volatile IExternalViewProvider mExternalViewProvider;
public ExternalView(Context context, AttributeSet attrs) {
this(context, attrs, null);
@ -94,7 +95,7 @@ public class ExternalView extends View implements Application.ActivityLifecycleC
}
}
private void performAction(Runnable r) {
protected void performAction(Runnable r) {
if (mExternalViewProvider != null) {
r.run();
} else {

View File

@ -81,6 +81,12 @@ public abstract class ExternalViewProviderService extends Service {
protected abstract Provider createExternalView(Bundle options);
protected abstract class Provider {
public static final int DEFAULT_WINDOW_TYPE = WindowManager.LayoutParams.TYPE_PHONE;
public static final int DEFAULT_WINDOW_FLAGS =
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS |
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;;
private final class ProviderImpl extends IExternalViewProvider.Stub {
private final Window mWindow;
private final WindowManager.LayoutParams mParams;
@ -88,15 +94,13 @@ public abstract class ExternalViewProviderService extends Service {
private boolean mShouldShow = true;
private boolean mAskedShow = false;
public ProviderImpl() {
public ProviderImpl(Provider provider) {
mWindow = new PhoneWindow(ExternalViewProviderService.this);
((ViewGroup) mWindow.getDecorView()).addView(onCreateView());
mParams = new WindowManager.LayoutParams();
mParams.type = WindowManager.LayoutParams.TYPE_PHONE;
mParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS |
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
mParams.type = provider.getWindowType();
mParams.flags = provider.getWindowFlags();
mParams.gravity = Gravity.LEFT | Gravity.TOP;
mParams.format = PixelFormat.TRANSPARENT;
}
@ -202,7 +206,7 @@ public abstract class ExternalViewProviderService extends Service {
}
}
private final ProviderImpl mImpl = new ProviderImpl();
private final ProviderImpl mImpl = new ProviderImpl(this);
private final Bundle mOptions;
protected Provider(Bundle options) {
@ -220,5 +224,13 @@ public abstract class ExternalViewProviderService extends Service {
protected void onPause() {}
protected void onStop() {}
protected void onDetach() {}
/*package*/ int getWindowType() {
return DEFAULT_WINDOW_TYPE;
}
/*package*/ int getWindowFlags() {
return DEFAULT_WINDOW_FLAGS;
}
}
}

View File

@ -13,34 +13,72 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cyanogenmod.externalviews;
import android.content.Context;
import android.content.ComponentName;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.RemoteException;
import android.util.AttributeSet;
import android.view.WindowManager;
/**
* TODO: unhide once documented and finalized
* @hide
*/
public final class KeyguardExternalView extends ExternalView {
public static final String EXTRA_PERMISSION_LIST = "permissions_list";
public static final String CATEGORY_KEYGUARD_GRANT_PERMISSION
= "org.cyanogenmod.intent.category.KEYGUARD_GRANT_PERMISSION";
private final Point mDisplaySize;
public KeyguardExternalView(Context context, AttributeSet attrs) {
super(context,attrs);
this(context, attrs, null);
}
public KeyguardExternalView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context,attrs,defStyleAttr);
this(context,attrs);
}
public KeyguardExternalView(Context context, AttributeSet attrs, int defStyleAttr,
int defStyleRes) {
super(context,attrs,defStyleAttr,defStyleRes);
this(context,attrs);
}
public KeyguardExternalView(Context context, AttributeSet attributeSet,
ComponentName componentName) {
super(context,attributeSet,componentName);
mDisplaySize = new Point();
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
wm.getDefaultDisplay().getRealSize(mDisplaySize);
}
@Override
public boolean onPreDraw() {
if (!mExternalViewProperties.hasChanged()) {
return true;
}
// keyguard views always take up the full screen when visible
final int x = mExternalViewProperties.getX();
final int y = mExternalViewProperties.getY();
final int width = mDisplaySize.x - x;
final int height = mDisplaySize.y - y;
final boolean visible = mExternalViewProperties.isVisible();
final Rect clipRect = new Rect(x, y, width + x, height + y);
performAction(new Runnable() {
@Override
public void run() {
try {
mExternalViewProvider.alterWindow(x, y, width, height, visible,
clipRect);
} catch (RemoteException e) {
}
}
});
return true;
}
}

View File

@ -0,0 +1,48 @@
/*
* 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.os.Bundle;
import android.view.WindowManager;
/**
* TODO: unhide once documented and finalized
* @hide
*/
public abstract class KeyguardExternalViewProviderService extends ExternalViewProviderService {
private static final String TAG = KeyguardExternalViewProviderService.class.getSimpleName();
private static final boolean DEBUG = false;
protected abstract class Provider extends ExternalViewProviderService.Provider {
protected Provider(Bundle options) {
super(options);
}
/*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;
}
}
}