1 /* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.wallpaper.livepicker; 18 19 import android.app.Activity; 20 import android.app.WallpaperManager; 21 import android.app.WallpaperInfo; 22 import android.app.Dialog; 23 import android.service.wallpaper.IWallpaperConnection; 24 import android.service.wallpaper.IWallpaperService; 25 import android.service.wallpaper.IWallpaperEngine; 26 import android.service.wallpaper.WallpaperSettingsActivity; 27 import android.content.ServiceConnection; 28 import android.content.Intent; 29 import android.content.Context; 30 import android.content.ComponentName; 31 import android.os.RemoteException; 32 import android.os.IBinder; 33 import android.os.ParcelFileDescriptor; 34 import android.os.Bundle; 35 import android.view.MotionEvent; 36 import android.view.View; 37 import android.view.WindowManager; 38 import android.view.ViewGroup; 39 import android.view.Window; 40 import android.view.LayoutInflater; 41 import android.util.Log; 42 import android.widget.TextView; 43 44 public class LiveWallpaperPreview extends Activity { 45 static final String EXTRA_LIVE_WALLPAPER_INTENT = "android.live_wallpaper.intent"; 46 static final String EXTRA_LIVE_WALLPAPER_SETTINGS = "android.live_wallpaper.settings"; 47 static final String EXTRA_LIVE_WALLPAPER_PACKAGE = "android.live_wallpaper.package"; 48 49 private static final String LOG_TAG = "LiveWallpaperPreview"; 50 51 private WallpaperManager mWallpaperManager; 52 private WallpaperConnection mWallpaperConnection; 53 54 private String mSettings; 55 private String mPackageName; 56 private Intent mWallpaperIntent; 57 private View mView; 58 private Dialog mDialog; 59 60 static void showPreview(Activity activity, int code, Intent intent, WallpaperInfo info) { 61 Intent preview = new Intent(activity, LiveWallpaperPreview.class); 62 preview.putExtra(EXTRA_LIVE_WALLPAPER_INTENT, intent); 63 preview.putExtra(EXTRA_LIVE_WALLPAPER_SETTINGS, info.getSettingsActivity()); 64 preview.putExtra(EXTRA_LIVE_WALLPAPER_PACKAGE, info.getPackageName()); 65 activity.startActivityForResult(preview, code); 66 } 67 68 @Override 69 protected void onCreate(Bundle savedInstanceState) { 70 super.onCreate(savedInstanceState); 71 72 Bundle extras = getIntent().getExtras(); 73 mWallpaperIntent = (Intent) extras.get(EXTRA_LIVE_WALLPAPER_INTENT); 74 if (mWallpaperIntent == null) { 75 setResult(RESULT_CANCELED); 76 finish(); 77 } 78 79 setContentView(R.layout.live_wallpaper_preview); 80 mView = findViewById(R.id.configure); 81 82 mSettings = extras.getString(EXTRA_LIVE_WALLPAPER_SETTINGS); 83 mPackageName = extras.getString(EXTRA_LIVE_WALLPAPER_PACKAGE); 84 if (mSettings == null) { 85 mView.setVisibility(View.GONE); 86 } 87 88 mWallpaperManager = WallpaperManager.getInstance(this); 89 90 mWallpaperConnection = new WallpaperConnection(mWallpaperIntent); 91 } 92 93 public void setLiveWallpaper(View v) { 94 try { 95 mWallpaperManager.getIWallpaperManager().setWallpaperComponent( 96 mWallpaperIntent.getComponent()); 97 mWallpaperManager.setWallpaperOffsetSteps(0.5f, 0.0f); 98 mWallpaperManager.setWallpaperOffsets(v.getRootView().getWindowToken(), 0.5f, 0.0f); 99 setResult(RESULT_OK); 100 } catch (RemoteException e) { 101 // do nothing 102 } catch (RuntimeException e) { 103 Log.w(LOG_TAG, "Failure setting wallpaper", e); 104 } 105 finish(); 106 } 107 108 @SuppressWarnings({"UnusedDeclaration"}) 109 public void configureLiveWallpaper(View v) { 110 Intent intent = new Intent(); 111 intent.setComponent(new ComponentName(mPackageName, mSettings)); 112 intent.putExtra(WallpaperSettingsActivity.EXTRA_PREVIEW_MODE, true); 113 startActivity(intent); 114 } 115 116 @Override 117 public void onResume() { 118 super.onResume(); 119 if (mWallpaperConnection != null && mWallpaperConnection.mEngine != null) { 120 try { 121 mWallpaperConnection.mEngine.setVisibility(true); 122 } catch (RemoteException e) { 123 // Ignore 124 } 125 } 126 } 127 128 @Override 129 public void onPause() { 130 super.onPause(); 131 if (mWallpaperConnection != null && mWallpaperConnection.mEngine != null) { 132 try { 133 mWallpaperConnection.mEngine.setVisibility(false); 134 } catch (RemoteException e) { 135 // Ignore 136 } 137 } 138 } 139 140 @Override 141 public void onAttachedToWindow() { 142 super.onAttachedToWindow(); 143 144 showLoading(); 145 146 mView.post(new Runnable() { 147 public void run() { 148 if (!mWallpaperConnection.connect()) { 149 mWallpaperConnection = null; 150 } 151 } 152 }); 153 } 154 155 private void showLoading() { 156 LayoutInflater inflater = LayoutInflater.from(this); 157 TextView content = (TextView) inflater.inflate(R.layout.live_wallpaper_loading, null); 158 159 mDialog = new Dialog(this, android.R.style.Theme_Black); 160 161 Window window = mDialog.getWindow(); 162 WindowManager.LayoutParams lp = window.getAttributes(); 163 164 lp.width = WindowManager.LayoutParams.MATCH_PARENT; 165 lp.height = WindowManager.LayoutParams.MATCH_PARENT; 166 window.setType(WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA); 167 168 mDialog.setContentView(content, new ViewGroup.LayoutParams( 169 ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT 170 )); 171 mDialog.show(); 172 } 173 174 @Override 175 public void onDetachedFromWindow() { 176 super.onDetachedFromWindow(); 177 178 if (mDialog != null) mDialog.dismiss(); 179 180 if (mWallpaperConnection != null) { 181 mWallpaperConnection.disconnect(); 182 } 183 mWallpaperConnection = null; 184 } 185 186 @Override 187 public boolean dispatchTouchEvent(MotionEvent ev) { 188 if (mWallpaperConnection != null && mWallpaperConnection.mEngine != null) { 189 MotionEvent dup = MotionEvent.obtainNoHistory(ev); 190 try { 191 mWallpaperConnection.mEngine.dispatchPointer(dup); 192 } catch (RemoteException e) { 193 } 194 } 195 196 if (ev.getAction() == MotionEvent.ACTION_DOWN) { 197 onUserInteraction(); 198 } 199 boolean handled = getWindow().superDispatchTouchEvent(ev); 200 if (!handled) { 201 handled = onTouchEvent(ev); 202 } 203 204 if (!handled && mWallpaperConnection != null && mWallpaperConnection.mEngine != null) { 205 int action = ev.getActionMasked(); 206 try { 207 if (action == MotionEvent.ACTION_UP) { 208 mWallpaperConnection.mEngine.dispatchWallpaperCommand( 209 WallpaperManager.COMMAND_TAP, 210 (int) ev.getX(), (int) ev.getY(), 0, null); 211 } else if (action == MotionEvent.ACTION_POINTER_UP) { 212 int pointerIndex = ev.getActionIndex(); 213 mWallpaperConnection.mEngine.dispatchWallpaperCommand( 214 WallpaperManager.COMMAND_SECONDARY_TAP, 215 (int) ev.getX(pointerIndex), (int) ev.getY(pointerIndex), 0, null); 216 } 217 } catch (RemoteException e) { 218 } 219 } 220 return handled; 221 } 222 223 class WallpaperConnection extends IWallpaperConnection.Stub implements ServiceConnection { 224 final Intent mIntent; 225 IWallpaperService mService; 226 IWallpaperEngine mEngine; 227 boolean mConnected; 228 229 WallpaperConnection(Intent intent) { 230 mIntent = intent; 231 } 232 233 public boolean connect() { 234 synchronized (this) { 235 if (!bindService(mIntent, this, Context.BIND_AUTO_CREATE)) { 236 return false; 237 } 238 239 mConnected = true; 240 return true; 241 } 242 } 243 244 public void disconnect() { 245 synchronized (this) { 246 mConnected = false; 247 if (mEngine != null) { 248 try { 249 mEngine.destroy(); 250 } catch (RemoteException e) { 251 // Ignore 252 } 253 mEngine = null; 254 } 255 unbindService(this); 256 mService = null; 257 } 258 } 259 260 public void onServiceConnected(ComponentName name, IBinder service) { 261 if (mWallpaperConnection == this) { 262 mService = IWallpaperService.Stub.asInterface(service); 263 try { 264 final View view = mView; 265 final View root = view.getRootView(); 266 mService.attach(this, view.getWindowToken(), 267 WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY, 268 true, root.getWidth(), root.getHeight()); 269 } catch (RemoteException e) { 270 Log.w(LOG_TAG, "Failed attaching wallpaper; clearing", e); 271 } 272 } 273 } 274 275 public void onServiceDisconnected(ComponentName name) { 276 mService = null; 277 mEngine = null; 278 if (mWallpaperConnection == this) { 279 Log.w(LOG_TAG, "Wallpaper service gone: " + name); 280 } 281 } 282 283 public void attachEngine(IWallpaperEngine engine) { 284 synchronized (this) { 285 if (mConnected) { 286 mEngine = engine; 287 try { 288 engine.setVisibility(true); 289 } catch (RemoteException e) { 290 // Ignore 291 } 292 } else { 293 try { 294 engine.destroy(); 295 } catch (RemoteException e) { 296 // Ignore 297 } 298 } 299 } 300 } 301 302 public ParcelFileDescriptor setWallpaper(String name) { 303 return null; 304 } 305 } 306 } 307